1 /*
2 * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package jdk.internal.classfile.impl.verifier;
26
27 import java.lang.classfile.ClassHierarchyResolver;
28 import java.lang.classfile.ClassModel;
29 import jdk.internal.classfile.components.ClassPrinter;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.function.Consumer;
34
35 import jdk.internal.classfile.impl.ClassHierarchyImpl;
36 import jdk.internal.classfile.impl.RawBytecodeHelper;
37 import jdk.internal.classfile.impl.verifier.VerificationSignature.BasicType;
38 import jdk.internal.classfile.impl.verifier.VerificationWrapper.ConstantPoolWrapper;
39
40 import static jdk.internal.classfile.impl.RawBytecodeHelper.*;
41 import static jdk.internal.classfile.impl.verifier.VerificationFrame.FLAG_THIS_UNINIT;
42 import static jdk.internal.classfile.impl.verifier.VerificationSignature.BasicType.T_BOOLEAN;
43 import static jdk.internal.classfile.impl.verifier.VerificationSignature.BasicType.T_LONG;
44
45 /// VerifierImpl performs selected checks and verifications of the class file
46 /// format according to {@jvms 4.8 Format Checking},
47 /// {@jvms 4.9 Constraints on Java Virtual Machine code},
48 /// {@jvms 4.10 Verification of class Files} and {@jvms 6.5 Instructions}
49 ///
50 /// From `verifier.cpp`.
51 public final class VerifierImpl {
52 static final int
53 JVM_CONSTANT_Utf8 = 1,
54 JVM_CONSTANT_Unicode = 2,
55 JVM_CONSTANT_Integer = 3,
56 JVM_CONSTANT_Float = 4,
57 JVM_CONSTANT_Long = 5,
58 JVM_CONSTANT_Double = 6,
59 JVM_CONSTANT_Class = 7,
60 JVM_CONSTANT_String = 8,
61 JVM_CONSTANT_Fieldref = 9,
62 JVM_CONSTANT_Methodref = 10,
63 JVM_CONSTANT_InterfaceMethodref = 11,
64 JVM_CONSTANT_NameAndType = 12,
65 JVM_CONSTANT_MethodHandle = 15,
66 JVM_CONSTANT_MethodType = 16,
67 JVM_CONSTANT_Dynamic = 17,
68 JVM_CONSTANT_InvokeDynamic = 18,
69 JVM_CONSTANT_Module = 19,
70 JVM_CONSTANT_Package = 20,
71 JVM_CONSTANT_ExternalMax = 20;
72
73 static final char JVM_SIGNATURE_SPECIAL = '<',
74 JVM_SIGNATURE_ARRAY = '[',
75 JVM_SIGNATURE_BYTE = 'B',
76 JVM_SIGNATURE_CHAR = 'C',
77 JVM_SIGNATURE_CLASS = 'L',
78 JVM_SIGNATURE_FLOAT = 'F',
79 JVM_SIGNATURE_DOUBLE = 'D',
80 JVM_SIGNATURE_INT = 'I',
81 JVM_SIGNATURE_LONG = 'J',
82 JVM_SIGNATURE_SHORT = 'S',
83 JVM_SIGNATURE_BOOLEAN = 'Z';
84
85 static final String java_lang_String = "java/lang/String";
86 static final String object_initializer_name = "<init>";
87 static final String java_lang_invoke_MethodHandle = "java/lang/invoke/MethodHandle";
88 static final String java_lang_Object = "java/lang/Object";
89 static final String java_lang_invoke_MethodType = "java/lang/invoke/MethodType";
90 static final String java_lang_Throwable = "java/lang/Throwable";
91 static final String java_lang_Class = "java/lang/Class";
92
93 String errorContext = "";
94 private int bci;
95
96 static void log_info(Consumer<String> logger, String messageFormat, Object... args) {
97 if (logger != null) logger.accept(String.format(messageFormat + "%n", args));
98 }
99 private final Consumer<String> _logger;
100 void log_info(String messageFormat, Object... args) {
101 log_info(_logger, messageFormat, args);
102 }
103
104
105 static final int STACKMAP_ATTRIBUTE_MAJOR_VERSION = 50;
106 static final int INVOKEDYNAMIC_MAJOR_VERSION = 51;
107 static final int NOFAILOVER_MAJOR_VERSION = 51;
108 static final int MAX_CODE_SIZE = 65535;
109
110 public static List<VerifyError> verify(ClassModel classModel, Consumer<String> logger) {
111 return verify(classModel, ClassHierarchyResolver.defaultResolver(), logger);
112 }
113
114 public static List<VerifyError> verify(ClassModel classModel, ClassHierarchyResolver classHierarchyResolver, Consumer<String> logger) {
115 String clsName = classModel.thisClass().asInternalName();
116 log_info(logger, "Start class verification for: %s", clsName);
117 try {
118 var klass = new VerificationWrapper(classModel);
119 var errors = new ArrayList<VerifyError>();
120 errors.addAll(new ParserVerifier(classModel).verify());
121 if (is_eligible_for_verification(klass)) {
122 if (klass.majorVersion() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) {
123 var verifierErrors = new VerifierImpl(klass, classHierarchyResolver, logger).verify_class();
124 if (!verifierErrors.isEmpty() && klass.majorVersion() < NOFAILOVER_MAJOR_VERSION) {
125 log_info(logger, "Fail over class verification to old verifier for: %s", klass.thisClassName());
126 errors.addAll(inference_verify(klass));
127 } else {
128 errors.addAll(verifierErrors);
129 }
130 } else {
131 errors.addAll(inference_verify(klass));
132 }
133 }
134 return Collections.unmodifiableList(errors);
135 } finally {
136 log_info(logger, "End class verification for: %s", clsName);
137 }
138 }
139
140 public static boolean is_eligible_for_verification(VerificationWrapper klass) {
141 // 8330606 Not applicable here
142 return true;
143 }
144
145 static List<VerifyError> inference_verify(VerificationWrapper klass) {
146 return List.of(new VerifyError("Inference verification is not supported"));
147 }
148
149 static class sig_as_verification_types {
150 private int _num_args;
151 private ArrayList<VerificationType> _sig_verif_types;
152
153 sig_as_verification_types(ArrayList<VerificationType> sig_verif_types) {
154 this._sig_verif_types = sig_verif_types;
155 this._num_args = 0;
156 }
157
158 int num_args() {
159 return _num_args;
160 }
161
162 void set_num_args(int num_args) {
163 _num_args = num_args;
164 }
165
166 ArrayList<VerificationType> sig_verif_types() {
167 return _sig_verif_types;
168 }
169 }
170
171 VerificationType cp_ref_index_to_type(int index, ConstantPoolWrapper cp) {
172 return cp_index_to_type(cp.refClassIndexAt(index), cp);
173 }
174
175 final VerificationWrapper _klass;
176 final ClassHierarchyImpl _class_hierarchy;
177 VerificationWrapper.MethodWrapper _method;
178 VerificationType _this_type;
179
180 static final int BYTECODE_OFFSET = 1, NEW_OFFSET = 2;
181
182 VerificationWrapper current_class() {
183 return _klass;
184 }
185
186 ClassHierarchyImpl class_hierarchy() {
187 return _class_hierarchy;
188 }
189
190 VerificationType current_type() {
191 return _this_type;
192 }
193
194 VerificationType cp_index_to_type(int index, ConstantPoolWrapper cp) {
195 return VerificationType.reference_type(cp.classNameAt(index));
196 }
197
198 int change_sig_to_verificationType(VerificationSignature sig_type, VerificationType inference_types[], int inference_type_index) {
199 BasicType bt = sig_type.type();
200 switch (bt) {
201 case T_OBJECT:
202 case T_ARRAY:
203 String name = sig_type.asSymbol();
204 inference_types[inference_type_index] = VerificationType.reference_type(name);
205 return 1;
206 case T_LONG:
207 inference_types[inference_type_index] = VerificationType.long_type;
208 inference_types[++inference_type_index] = VerificationType.long2_type;
209 return 2;
210 case T_DOUBLE:
211 inference_types[inference_type_index] = VerificationType.double_type;
212 inference_types[++inference_type_index] = VerificationType.double2_type;
213 return 2;
214 case T_INT:
215 case T_BOOLEAN:
216 case T_BYTE:
217 case T_CHAR:
218 case T_SHORT:
219 inference_types[inference_type_index] = VerificationType.integer_type;
220 return 1;
221 case T_FLOAT:
222 inference_types[inference_type_index] = VerificationType.float_type;
223 return 1;
224 default:
225 verifyError("Should not reach here");
226 return 1;
227 }
228 }
229
230 private static final int NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION = 51;
231 private static final int STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION = 52;
232 private static final int MAX_ARRAY_DIMENSIONS = 255;
233
234 VerifierImpl(VerificationWrapper klass, ClassHierarchyResolver classHierarchyResolver, Consumer<String> logger) {
235 _klass = klass;
236 _class_hierarchy = new ClassHierarchyImpl(classHierarchyResolver);
237 _this_type = VerificationType.reference_type(klass.thisClassName());
238 _logger = logger;
239 }
240
241 private VerificationType object_type() {
242 return VerificationType.reference_type(java_lang_Object);
243 }
244
245 List<VerifyError> verify_class() {
246 log_info("Verifying class %s with new format", _klass.thisClassName());
247 var errors = new ArrayList<VerifyError>();
248 for (VerificationWrapper.MethodWrapper m : _klass.methods()) {
249 if (m.isNative() || m.isAbstract() || m.isBridge()) {
250 continue;
251 }
252 verify_method(m, errors);
253 }
254 return errors;
255 }
256
257 void translate_signature(String method_sig, sig_as_verification_types sig_verif_types) {
258 var sig_stream = new VerificationSignature(method_sig, true, this);
259 VerificationType[] sig_type = new VerificationType[2];
260 int sig_i = 0;
261 ArrayList<VerificationType> verif_types = sig_verif_types.sig_verif_types();
262 while (!sig_stream.atReturnType()) {
263 int n = change_sig_to_verificationType(sig_stream, sig_type, 0);
264 if (n > 2) verifyError("Unexpected signature type");
265 for (int x = 0; x < n; x++) {
266 verif_types.add(sig_type[x]);
267 }
268 sig_i += n;
269 sig_stream.next();
270 }
271 sig_verif_types.set_num_args(sig_i);
272 if (sig_stream.type() != BasicType.T_VOID) {
273 int n = change_sig_to_verificationType(sig_stream, sig_type, 0);
274 if (n > 2) verifyError("Unexpected signature return type");
275 for (int y = 0; y < n; y++) {
276 verif_types.add(sig_type[y]);
277 }
278 }
279 }
280
281 void create_method_sig_entry(sig_as_verification_types sig_verif_types, String method_sig) {
282 translate_signature(method_sig, sig_verif_types);
283 }
284
285 void verify_method(VerificationWrapper.MethodWrapper m, List<VerifyError> errorsCollector) {
286 try {
287 verify_method(m);
288 } catch (VerifyError err) {
289 errorsCollector.add(err);
290 } catch (Error | Exception e) {
291 errorsCollector.add(new VerifyError(e.toString()));
292 }
293 }
294
295 @SuppressWarnings("fallthrough")
296 void verify_method(VerificationWrapper.MethodWrapper m) {
297 _method = m;
298 log_info(_logger, "Verifying method %s%s", m.name(), m.descriptor());
299 byte[] codeArray = m.codeArray();
300 if (codeArray == null) verifyError("Missing Code attribute");
301 int max_locals = m.maxLocals();
302 int max_stack = m.maxStack();
303 byte[] stackmap_data = m.stackMapTableRawData();
304 var cp = m.constantPool();
305 if (!VerificationSignature.isValidMethodSignature(m.descriptor())) verifyError("Invalid method signature");
306 VerificationFrame current_frame = new VerificationFrame(max_locals, max_stack, this);
307 VerificationType return_type = current_frame.set_locals_from_arg(m, current_type());
308 int stackmap_index = 0;
309 int code_length = m.codeLength();
310 if (code_length < 1 || code_length > MAX_CODE_SIZE) {
311 verifyError(String.format("Invalid method Code length %d", code_length));
312 }
313 var code = RawBytecodeHelper.of(codeArray);
314 byte[] code_data = generate_code_data(code);
315 int ex_minmax[] = new int[] {code_length, -1};
316 verify_exception_handler_table(code_length, code_data, ex_minmax);
317 verify_local_variable_table(code_length, code_data);
318
319 var reader = new VerificationTable.StackMapReader(stackmap_data, code_data, code_length, current_frame,
320 (char) max_locals, (char) max_stack, cp, this);
321 VerificationTable stackmap_table = new VerificationTable(reader, cp, this);
322
323 var bcs = code.start();
324 boolean no_control_flow = false;
325 int opcode;
326 while (bcs.next()) {
327 opcode = bcs.opcode();
328 bci = bcs.bci();
329 current_frame.set_offset(bci);
330 current_frame.set_mark();
331 stackmap_index = verify_stackmap_table(stackmap_index, bci, current_frame, stackmap_table, no_control_flow);
332 boolean this_uninit = false;
333 boolean verified_exc_handlers = false;
334 {
335 int index;
336 int target;
337 VerificationType type, type2 = null;
338 VerificationType atype;
339 if (bcs.isWide()) {
340 if (opcode != IINC && opcode != ILOAD
341 && opcode != ALOAD && opcode != LLOAD
342 && opcode != ISTORE && opcode != ASTORE
343 && opcode != LSTORE && opcode != FLOAD
344 && opcode != DLOAD && opcode != FSTORE
345 && opcode != DSTORE) {
346 verifyError("Bad wide instruction");
347 }
348 }
349 if (VerificationBytecodes.is_store_into_local(opcode) && bci >= ex_minmax[0] && bci < ex_minmax[1]) {
350 verify_exception_handler_targets(bci, this_uninit, current_frame, stackmap_table);
351 verified_exc_handlers = true;
352 }
353 switch (opcode) {
354 case NOP :
355 no_control_flow = false; break;
356 case ACONST_NULL :
357 current_frame.push_stack(
358 VerificationType.null_type);
359 no_control_flow = false; break;
360 case ICONST_M1 :
361 case ICONST_0 :
362 case ICONST_1 :
363 case ICONST_2 :
364 case ICONST_3 :
365 case ICONST_4 :
366 case ICONST_5 :
367 current_frame.push_stack(
368 VerificationType.integer_type);
369 no_control_flow = false; break;
370 case LCONST_0 :
371 case LCONST_1 :
372 current_frame.push_stack_2(
373 VerificationType.long_type,
374 VerificationType.long2_type);
375 no_control_flow = false; break;
376 case FCONST_0 :
377 case FCONST_1 :
378 case FCONST_2 :
379 current_frame.push_stack(
380 VerificationType.float_type);
381 no_control_flow = false; break;
382 case DCONST_0 :
383 case DCONST_1 :
384 current_frame.push_stack_2(
385 VerificationType.double_type,
386 VerificationType.double2_type);
387 no_control_flow = false; break;
388 case SIPUSH :
389 case BIPUSH :
390 current_frame.push_stack(
391 VerificationType.integer_type);
392 no_control_flow = false; break;
393 case LDC :
394 verify_ldc(
395 opcode, bcs.getIndexU1(), current_frame,
396 cp, bci);
397 no_control_flow = false; break;
398 case LDC_W :
399 case LDC2_W :
400 verify_ldc(
401 opcode, bcs.getIndexU2(), current_frame,
402 cp, bci);
403 no_control_flow = false; break;
404 case ILOAD :
405 verify_iload(bcs.getIndex(), current_frame);
406 no_control_flow = false; break;
407 case ILOAD_0 :
408 case ILOAD_1 :
409 case ILOAD_2 :
410 case ILOAD_3 :
411 index = opcode - ILOAD_0;
412 verify_iload(index, current_frame);
413 no_control_flow = false; break;
414 case LLOAD :
415 verify_lload(bcs.getIndex(), current_frame);
416 no_control_flow = false; break;
417 case LLOAD_0 :
418 case LLOAD_1 :
419 case LLOAD_2 :
420 case LLOAD_3 :
421 index = opcode - LLOAD_0;
422 verify_lload(index, current_frame);
423 no_control_flow = false; break;
424 case FLOAD :
425 verify_fload(bcs.getIndex(), current_frame);
426 no_control_flow = false; break;
427 case FLOAD_0 :
428 case FLOAD_1 :
429 case FLOAD_2 :
430 case FLOAD_3 :
431 index = opcode - FLOAD_0;
432 verify_fload(index, current_frame);
433 no_control_flow = false; break;
434 case DLOAD :
435 verify_dload(bcs.getIndex(), current_frame);
436 no_control_flow = false; break;
437 case DLOAD_0 :
438 case DLOAD_1 :
439 case DLOAD_2 :
440 case DLOAD_3 :
441 index = opcode - DLOAD_0;
442 verify_dload(index, current_frame);
443 no_control_flow = false; break;
444 case ALOAD :
445 verify_aload(bcs.getIndex(), current_frame);
446 no_control_flow = false; break;
447 case ALOAD_0 :
448 case ALOAD_1 :
449 case ALOAD_2 :
450 case ALOAD_3 :
451 index = opcode - ALOAD_0;
452 verify_aload(index, current_frame);
453 no_control_flow = false; break;
454 case IALOAD :
455 type = current_frame.pop_stack(
456 VerificationType.integer_type);
457 atype = current_frame.pop_stack(
458 VerificationType.reference_check);
459 if (!atype.is_int_array()) {
460 verifyError("Bad type");
461 }
462 current_frame.push_stack(
463 VerificationType.integer_type);
464 no_control_flow = false; break;
465 case BALOAD :
466 type = current_frame.pop_stack(
467 VerificationType.integer_type);
468 atype = current_frame.pop_stack(
469 VerificationType.reference_check);
470 if (!atype.is_bool_array() && !atype.is_byte_array()) {
471 verifyError("Bad type");
472 }
473 current_frame.push_stack(
474 VerificationType.integer_type);
475 no_control_flow = false; break;
476 case CALOAD :
477 type = current_frame.pop_stack(
478 VerificationType.integer_type);
479 atype = current_frame.pop_stack(
480 VerificationType.reference_check);
481 if (!atype.is_char_array()) {
482 verifyError("Bad type");
483 }
484 current_frame.push_stack(
485 VerificationType.integer_type);
486 no_control_flow = false; break;
487 case SALOAD :
488 type = current_frame.pop_stack(
489 VerificationType.integer_type);
490 atype = current_frame.pop_stack(
491 VerificationType.reference_check);
492 if (!atype.is_short_array()) {
493 verifyError("Bad type");
494 }
495 current_frame.push_stack(
496 VerificationType.integer_type);
497 no_control_flow = false; break;
498 case LALOAD :
499 type = current_frame.pop_stack(
500 VerificationType.integer_type);
501 atype = current_frame.pop_stack(
502 VerificationType.reference_check);
503 if (!atype.is_long_array()) {
504 verifyError("Bad type");
505 }
506 current_frame.push_stack_2(
507 VerificationType.long_type,
508 VerificationType.long2_type);
509 no_control_flow = false; break;
510 case FALOAD :
511 type = current_frame.pop_stack(
512 VerificationType.integer_type);
513 atype = current_frame.pop_stack(
514 VerificationType.reference_check);
515 if (!atype.is_float_array()) {
516 verifyError("Bad type");
517 }
518 current_frame.push_stack(
519 VerificationType.float_type);
520 no_control_flow = false; break;
521 case DALOAD :
522 type = current_frame.pop_stack(
523 VerificationType.integer_type);
524 atype = current_frame.pop_stack(
525 VerificationType.reference_check);
526 if (!atype.is_double_array()) {
527 verifyError("Bad type");
528 }
529 current_frame.push_stack_2(
530 VerificationType.double_type,
531 VerificationType.double2_type);
532 no_control_flow = false; break;
533 case AALOAD : {
534 type = current_frame.pop_stack(
535 VerificationType.integer_type);
536 atype = current_frame.pop_stack(
537 VerificationType.reference_check);
538 if (!atype.is_reference_array()) {
539 verifyError("Bad type");
540 }
541 if (atype.is_null()) {
542 current_frame.push_stack(
543 VerificationType.null_type);
544 } else {
545 VerificationType component =
546 atype.get_component(this);
547 current_frame.push_stack(component);
548 }
549 no_control_flow = false; break;
550 }
551 case ISTORE :
552 verify_istore(bcs.getIndex(), current_frame);
553 no_control_flow = false; break;
554 case ISTORE_0 :
555 case ISTORE_1 :
556 case ISTORE_2 :
557 case ISTORE_3 :
558 index = opcode - ISTORE_0;
559 verify_istore(index, current_frame);
560 no_control_flow = false; break;
561 case LSTORE :
562 verify_lstore(bcs.getIndex(), current_frame);
563 no_control_flow = false; break;
564 case LSTORE_0 :
565 case LSTORE_1 :
566 case LSTORE_2 :
567 case LSTORE_3 :
568 index = opcode - LSTORE_0;
569 verify_lstore(index, current_frame);
570 no_control_flow = false; break;
571 case FSTORE :
572 verify_fstore(bcs.getIndex(), current_frame);
573 no_control_flow = false; break;
574 case FSTORE_0 :
575 case FSTORE_1 :
576 case FSTORE_2 :
577 case FSTORE_3 :
578 index = opcode - FSTORE_0;
579 verify_fstore(index, current_frame);
580 no_control_flow = false; break;
581 case DSTORE :
582 verify_dstore(bcs.getIndex(), current_frame);
583 no_control_flow = false; break;
584 case DSTORE_0 :
585 case DSTORE_1 :
586 case DSTORE_2 :
587 case DSTORE_3 :
588 index = opcode - DSTORE_0;
589 verify_dstore(index, current_frame);
590 no_control_flow = false; break;
591 case ASTORE :
592 verify_astore(bcs.getIndex(), current_frame);
593 no_control_flow = false; break;
594 case ASTORE_0 :
595 case ASTORE_1 :
596 case ASTORE_2 :
597 case ASTORE_3 :
598 index = opcode - ASTORE_0;
599 verify_astore(index, current_frame);
600 no_control_flow = false; break;
601 case IASTORE :
602 type = current_frame.pop_stack(
603 VerificationType.integer_type);
604 type2 = current_frame.pop_stack(
605 VerificationType.integer_type);
606 atype = current_frame.pop_stack(
607 VerificationType.reference_check);
608 if (!atype.is_int_array()) {
609 verifyError("Bad type");
610 }
611 no_control_flow = false; break;
612 case BASTORE :
613 type = current_frame.pop_stack(
614 VerificationType.integer_type);
615 type2 = current_frame.pop_stack(
616 VerificationType.integer_type);
617 atype = current_frame.pop_stack(
618 VerificationType.reference_check);
619 if (!atype.is_bool_array() && !atype.is_byte_array()) {
620 verifyError("Bad type");
621 }
622 no_control_flow = false; break;
623 case CASTORE :
624 current_frame.pop_stack(
625 VerificationType.integer_type);
626 current_frame.pop_stack(
627 VerificationType.integer_type);
628 atype = current_frame.pop_stack(
629 VerificationType.reference_check);
630 if (!atype.is_char_array()) {
631 verifyError("Bad type");
632 }
633 no_control_flow = false; break;
634 case SASTORE :
635 current_frame.pop_stack(
636 VerificationType.integer_type);
637 current_frame.pop_stack(
638 VerificationType.integer_type);
639 atype = current_frame.pop_stack(
640 VerificationType.reference_check);
641 if (!atype.is_short_array()) {
642 verifyError("Bad type");
643 }
644 no_control_flow = false; break;
645 case LASTORE :
646 current_frame.pop_stack_2(
647 VerificationType.long2_type,
648 VerificationType.long_type);
649 current_frame.pop_stack(
650 VerificationType.integer_type);
651 atype = current_frame.pop_stack(
652 VerificationType.reference_check);
653 if (!atype.is_long_array()) {
654 verifyError("Bad type");
655 }
656 no_control_flow = false; break;
657 case FASTORE :
658 current_frame.pop_stack(
659 VerificationType.float_type);
660 current_frame.pop_stack
661 (VerificationType.integer_type);
662 atype = current_frame.pop_stack(
663 VerificationType.reference_check);
664 if (!atype.is_float_array()) {
665 verifyError("Bad type");
666 }
667 no_control_flow = false; break;
668 case DASTORE :
669 current_frame.pop_stack_2(
670 VerificationType.double2_type,
671 VerificationType.double_type);
672 current_frame.pop_stack(
673 VerificationType.integer_type);
674 atype = current_frame.pop_stack(
675 VerificationType.reference_check);
676 if (!atype.is_double_array()) {
677 verifyError("Bad type");
678 }
679 no_control_flow = false; break;
680 case AASTORE :
681 type = current_frame.pop_stack(object_type());
682 type2 = current_frame.pop_stack(
683 VerificationType.integer_type);
684 atype = current_frame.pop_stack(
685 VerificationType.reference_check);
686 // more type-checking is done at runtime
687 if (!atype.is_reference_array()) {
688 verifyError("Bad type");
689 }
690 // 4938384: relaxed constraint in JVMS 3nd edition.
691 no_control_flow = false; break;
692 case POP :
693 current_frame.pop_stack(
694 VerificationType.category1_check);
695 no_control_flow = false; break;
696 case POP2 :
697 type = current_frame.pop_stack();
698 if (type.is_category1(this)) {
699 current_frame.pop_stack(
700 VerificationType.category1_check);
701 } else if (type.is_category2_2nd()) {
702 current_frame.pop_stack(
703 VerificationType.category2_check);
704 } else {
705 verifyError("Bad type");
706 }
707 no_control_flow = false; break;
708 case DUP :
709 type = current_frame.pop_stack(
710 VerificationType.category1_check);
711 current_frame.push_stack(type);
712 current_frame.push_stack(type);
713 no_control_flow = false; break;
714 case DUP_X1 :
715 type = current_frame.pop_stack(
716 VerificationType.category1_check);
717 type2 = current_frame.pop_stack(
718 VerificationType.category1_check);
719 current_frame.push_stack(type);
720 current_frame.push_stack(type2);
721 current_frame.push_stack(type);
722 no_control_flow = false; break;
723 case DUP_X2 :
724 {
725 VerificationType type3 = null;
726 type = current_frame.pop_stack(
727 VerificationType.category1_check);
728 type2 = current_frame.pop_stack();
729 if (type2.is_category1(this)) {
730 type3 = current_frame.pop_stack(
731 VerificationType.category1_check);
732 } else if (type2.is_category2_2nd()) {
733 type3 = current_frame.pop_stack(
734 VerificationType.category2_check);
735 } else {
736 verifyError("Bad type");
737 }
738 current_frame.push_stack(type);
739 current_frame.push_stack(type3);
740 current_frame.push_stack(type2);
741 current_frame.push_stack(type);
742 no_control_flow = false; break;
743 }
744 case DUP2 :
745 type = current_frame.pop_stack();
746 if (type.is_category1(this)) {
747 type2 = current_frame.pop_stack(
748 VerificationType.category1_check);
749 } else if (type.is_category2_2nd()) {
750 type2 = current_frame.pop_stack(
751 VerificationType.category2_check);
752 } else {
753 verifyError("Bad type");
754 }
755 current_frame.push_stack(type2);
756 current_frame.push_stack(type);
757 current_frame.push_stack(type2);
758 current_frame.push_stack(type);
759 no_control_flow = false; break;
760 case DUP2_X1 :
761 {
762 VerificationType type3;
763 type = current_frame.pop_stack();
764 if (type.is_category1(this)) {
765 type2 = current_frame.pop_stack(
766 VerificationType.category1_check);
767 } else if (type.is_category2_2nd()) {
768 type2 = current_frame.pop_stack(
769 VerificationType.category2_check);
770 } else {
771 verifyError("Bad type");
772 }
773 type3 = current_frame.pop_stack(
774 VerificationType.category1_check);
775 current_frame.push_stack(type2);
776 current_frame.push_stack(type);
777 current_frame.push_stack(type3);
778 current_frame.push_stack(type2);
779 current_frame.push_stack(type);
780 no_control_flow = false; break;
781 }
782 case DUP2_X2 :
783 VerificationType type3, type4 = null;
784 type = current_frame.pop_stack();
785 if (type.is_category1(this)) {
786 type2 = current_frame.pop_stack(
787 VerificationType.category1_check);
788 } else if (type.is_category2_2nd()) {
789 type2 = current_frame.pop_stack(
790 VerificationType.category2_check);
791 } else {
792 verifyError("Bad type");
793 }
794 type3 = current_frame.pop_stack();
795 if (type3.is_category1(this)) {
796 type4 = current_frame.pop_stack(
797 VerificationType.category1_check);
798 } else if (type3.is_category2_2nd()) {
799 type4 = current_frame.pop_stack(
800 VerificationType.category2_check);
801 } else {
802 verifyError("Bad type");
803 }
804 current_frame.push_stack(type2);
805 current_frame.push_stack(type);
806 current_frame.push_stack(type4);
807 current_frame.push_stack(type3);
808 current_frame.push_stack(type2);
809 current_frame.push_stack(type);
810 no_control_flow = false; break;
811 case SWAP :
812 type = current_frame.pop_stack(
813 VerificationType.category1_check);
814 type2 = current_frame.pop_stack(
815 VerificationType.category1_check);
816 current_frame.push_stack(type);
817 current_frame.push_stack(type2);
818 no_control_flow = false; break;
819 case IADD :
820 case ISUB :
821 case IMUL :
822 case IDIV :
823 case IREM :
824 case ISHL :
825 case ISHR :
826 case IUSHR :
827 case IOR :
828 case IXOR :
829 case IAND :
830 current_frame.pop_stack(
831 VerificationType.integer_type);
832 // fall through
833 case INEG :
834 current_frame.pop_stack(
835 VerificationType.integer_type);
836 current_frame.push_stack(
837 VerificationType.integer_type);
838 no_control_flow = false; break;
839 case LADD :
840 case LSUB :
841 case LMUL :
842 case LDIV :
843 case LREM :
844 case LAND :
845 case LOR :
846 case LXOR :
847 current_frame.pop_stack_2(
848 VerificationType.long2_type,
849 VerificationType.long_type);
850 // fall through
851 case LNEG :
852 current_frame.pop_stack_2(
853 VerificationType.long2_type,
854 VerificationType.long_type);
855 current_frame.push_stack_2(
856 VerificationType.long_type,
857 VerificationType.long2_type);
858 no_control_flow = false; break;
859 case LSHL :
860 case LSHR :
861 case LUSHR :
862 current_frame.pop_stack(
863 VerificationType.integer_type);
864 current_frame.pop_stack_2(
865 VerificationType.long2_type,
866 VerificationType.long_type);
867 current_frame.push_stack_2(
868 VerificationType.long_type,
869 VerificationType.long2_type);
870 no_control_flow = false; break;
871 case FADD :
872 case FSUB :
873 case FMUL :
874 case FDIV :
875 case FREM :
876 current_frame.pop_stack(
877 VerificationType.float_type);
878 // fall through
879 case FNEG :
880 current_frame.pop_stack(
881 VerificationType.float_type);
882 current_frame.push_stack(
883 VerificationType.float_type);
884 no_control_flow = false; break;
885 case DADD :
886 case DSUB :
887 case DMUL :
888 case DDIV :
889 case DREM :
890 current_frame.pop_stack_2(
891 VerificationType.double2_type,
892 VerificationType.double_type);
893 // fall through
894 case DNEG :
895 current_frame.pop_stack_2(
896 VerificationType.double2_type,
897 VerificationType.double_type);
898 current_frame.push_stack_2(
899 VerificationType.double_type,
900 VerificationType.double2_type);
901 no_control_flow = false; break;
902 case IINC :
903 verify_iinc(bcs.getIndex(), current_frame);
904 no_control_flow = false; break;
905 case I2L :
906 type = current_frame.pop_stack(
907 VerificationType.integer_type);
908 current_frame.push_stack_2(
909 VerificationType.long_type,
910 VerificationType.long2_type);
911 no_control_flow = false; break;
912 case L2I :
913 current_frame.pop_stack_2(
914 VerificationType.long2_type,
915 VerificationType.long_type);
916 current_frame.push_stack(
917 VerificationType.integer_type);
918 no_control_flow = false; break;
919 case I2F :
920 current_frame.pop_stack(
921 VerificationType.integer_type);
922 current_frame.push_stack(
923 VerificationType.float_type);
924 no_control_flow = false; break;
925 case I2D :
926 current_frame.pop_stack(
927 VerificationType.integer_type);
928 current_frame.push_stack_2(
929 VerificationType.double_type,
930 VerificationType.double2_type);
931 no_control_flow = false; break;
932 case L2F :
933 current_frame.pop_stack_2(
934 VerificationType.long2_type,
935 VerificationType.long_type);
936 current_frame.push_stack(
937 VerificationType.float_type);
938 no_control_flow = false; break;
939 case L2D :
940 current_frame.pop_stack_2(
941 VerificationType.long2_type,
942 VerificationType.long_type);
943 current_frame.push_stack_2(
944 VerificationType.double_type,
945 VerificationType.double2_type);
946 no_control_flow = false; break;
947 case F2I :
948 current_frame.pop_stack(
949 VerificationType.float_type);
950 current_frame.push_stack(
951 VerificationType.integer_type);
952 no_control_flow = false; break;
953 case F2L :
954 current_frame.pop_stack(
955 VerificationType.float_type);
956 current_frame.push_stack_2(
957 VerificationType.long_type,
958 VerificationType.long2_type);
959 no_control_flow = false; break;
960 case F2D :
961 current_frame.pop_stack(
962 VerificationType.float_type);
963 current_frame.push_stack_2(
964 VerificationType.double_type,
965 VerificationType.double2_type);
966 no_control_flow = false; break;
967 case D2I :
968 current_frame.pop_stack_2(
969 VerificationType.double2_type,
970 VerificationType.double_type);
971 current_frame.push_stack(
972 VerificationType.integer_type);
973 no_control_flow = false; break;
974 case D2L :
975 current_frame.pop_stack_2(
976 VerificationType.double2_type,
977 VerificationType.double_type);
978 current_frame.push_stack_2(
979 VerificationType.long_type,
980 VerificationType.long2_type);
981 no_control_flow = false; break;
982 case D2F :
983 current_frame.pop_stack_2(
984 VerificationType.double2_type,
985 VerificationType.double_type);
986 current_frame.push_stack(
987 VerificationType.float_type);
988 no_control_flow = false; break;
989 case I2B :
990 case I2C :
991 case I2S :
992 current_frame.pop_stack(
993 VerificationType.integer_type);
994 current_frame.push_stack(
995 VerificationType.integer_type);
996 no_control_flow = false; break;
997 case LCMP :
998 current_frame.pop_stack_2(
999 VerificationType.long2_type,
1000 VerificationType.long_type);
1001 current_frame.pop_stack_2(
1002 VerificationType.long2_type,
1003 VerificationType.long_type);
1004 current_frame.push_stack(
1005 VerificationType.integer_type);
1006 no_control_flow = false; break;
1007 case FCMPL :
1008 case FCMPG :
1009 current_frame.pop_stack(
1010 VerificationType.float_type);
1011 current_frame.pop_stack(
1012 VerificationType.float_type);
1013 current_frame.push_stack(
1014 VerificationType.integer_type);
1015 no_control_flow = false; break;
1016 case DCMPL :
1017 case DCMPG :
1018 current_frame.pop_stack_2(
1019 VerificationType.double2_type,
1020 VerificationType.double_type);
1021 current_frame.pop_stack_2(
1022 VerificationType.double2_type,
1023 VerificationType.double_type);
1024 current_frame.push_stack(
1025 VerificationType.integer_type);
1026 no_control_flow = false; break;
1027 case IF_ICMPEQ:
1028 case IF_ICMPNE:
1029 case IF_ICMPLT:
1030 case IF_ICMPGE:
1031 case IF_ICMPGT:
1032 case IF_ICMPLE:
1033 current_frame.pop_stack(
1034 VerificationType.integer_type);
1035 // fall through
1036 case IFEQ:
1037 case IFNE:
1038 case IFLT:
1039 case IFGE:
1040 case IFGT:
1041 case IFLE:
1042 current_frame.pop_stack(
1043 VerificationType.integer_type);
1044 target = bcs.dest();
1045 stackmap_table.check_jump_target(
1046 current_frame, target);
1047 no_control_flow = false; break;
1048 case IF_ACMPEQ :
1049 case IF_ACMPNE :
1050 current_frame.pop_stack(
1051 VerificationType.reference_check);
1052 // fall through
1053 case IFNULL :
1054 case IFNONNULL :
1055 current_frame.pop_stack(
1056 VerificationType.reference_check);
1057 target = bcs.dest();
1058 stackmap_table.check_jump_target
1059 (current_frame, target);
1060 no_control_flow = false; break;
1061 case GOTO :
1062 target = bcs.dest();
1063 stackmap_table.check_jump_target(
1064 current_frame, target);
1065 no_control_flow = true; break;
1066 case GOTO_W :
1067 target = bcs.destW();
1068 stackmap_table.check_jump_target(
1069 current_frame, target);
1070 no_control_flow = true; break;
1071 case TABLESWITCH :
1072 case LOOKUPSWITCH :
1073 verify_switch(
1074 bcs, code_length, code_data, current_frame,
1075 stackmap_table);
1076 no_control_flow = true; break;
1077 case IRETURN :
1078 type = current_frame.pop_stack(
1079 VerificationType.integer_type);
1080 verify_return_value(return_type, type, bci,
1081 current_frame);
1082 no_control_flow = true; break;
1083 case LRETURN :
1084 type2 = current_frame.pop_stack(
1085 VerificationType.long2_type);
1086 type = current_frame.pop_stack(
1087 VerificationType.long_type);
1088 verify_return_value(return_type, type, bci,
1089 current_frame);
1090 no_control_flow = true; break;
1091 case FRETURN :
1092 type = current_frame.pop_stack(
1093 VerificationType.float_type);
1094 verify_return_value(return_type, type, bci,
1095 current_frame);
1096 no_control_flow = true; break;
1097 case DRETURN :
1098 type2 = current_frame.pop_stack(
1099 VerificationType.double2_type);
1100 type = current_frame.pop_stack(
1101 VerificationType.double_type);
1102 verify_return_value(return_type, type, bci,
1103 current_frame);
1104 no_control_flow = true; break;
1105 case ARETURN :
1106 type = current_frame.pop_stack(
1107 VerificationType.reference_check);
1108 verify_return_value(return_type, type, bci,
1109 current_frame);
1110 no_control_flow = true; break;
1111 case RETURN:
1112 if (!return_type.is_bogus()) {
1113 verifyError("Method expects a return value");
1114 }
1115 if (object_initializer_name.equals(_method.name()) &&
1116 current_frame.flag_this_uninit()) {
1117 verifyError("Constructor must call super() or this() before return");
1118 }
1119 no_control_flow = true; break;
1120 case GETSTATIC :
1121 case PUTSTATIC :
1122 verify_field_instructions(bcs, current_frame, cp, true);
1123 no_control_flow = false; break;
1124 case GETFIELD :
1125 case PUTFIELD :
1126 verify_field_instructions(bcs, current_frame, cp, false);
1127 no_control_flow = false; break;
1128 case INVOKEVIRTUAL :
1129 case INVOKESPECIAL :
1130 case INVOKESTATIC :
1131 this_uninit = verify_invoke_instructions(bcs, code_length, current_frame, (bci >= ex_minmax[0] && bci < ex_minmax[1]), this_uninit, return_type, cp, stackmap_table);
1132 no_control_flow = false; break;
1133 case INVOKEINTERFACE :
1134 case INVOKEDYNAMIC :
1135 this_uninit = verify_invoke_instructions(bcs, code_length, current_frame, (bci >= ex_minmax[0] && bci < ex_minmax[1]), this_uninit, return_type, cp, stackmap_table);
1136 no_control_flow = false; break;
1137 case NEW :
1138 {
1139 index = bcs.getIndexU2();
1140 verify_cp_class_type(bci, index, cp);
1141 VerificationType new_class_type =
1142 cp_index_to_type(index, cp);
1143 if (!new_class_type.is_object()) {
1144 verifyError("Illegal new instruction");
1145 }
1146 type = VerificationType.uninitialized_type(bci);
1147 current_frame.push_stack(type);
1148 no_control_flow = false; break;
1149 }
1150 case NEWARRAY :
1151 type = get_newarray_type(bcs.getIndex(), bci);
1152 current_frame.pop_stack(
1153 VerificationType.integer_type);
1154 current_frame.push_stack(type);
1155 no_control_flow = false; break;
1156 case ANEWARRAY :
1157 verify_anewarray(bci, bcs.getIndexU2(), cp, current_frame);
1158 no_control_flow = false; break;
1159 case ARRAYLENGTH :
1160 type = current_frame.pop_stack(
1161 VerificationType.reference_check);
1162 if (!(type.is_null() || type.is_array())) {
1163 verifyError("Bad type");
1164 }
1165 current_frame.push_stack(
1166 VerificationType.integer_type);
1167 no_control_flow = false; break;
1168 case CHECKCAST :
1169 {
1170 index = bcs.getIndexU2();
1171 verify_cp_class_type(bci, index, cp);
1172 current_frame.pop_stack(object_type());
1173 VerificationType klass_type = cp_index_to_type(
1174 index, cp);
1175 current_frame.push_stack(klass_type);
1176 no_control_flow = false; break;
1177 }
1178 case INSTANCEOF : {
1179 index = bcs.getIndexU2();
1180 verify_cp_class_type(bci, index, cp);
1181 current_frame.pop_stack(object_type());
1182 current_frame.push_stack(
1183 VerificationType.integer_type);
1184 no_control_flow = false; break;
1185 }
1186 case MONITORENTER :
1187 case MONITOREXIT :
1188 current_frame.pop_stack(
1189 VerificationType.reference_check);
1190 no_control_flow = false; break;
1191 case MULTIANEWARRAY :
1192 {
1193 index = bcs.getIndexU2();
1194 int dim = _method.codeArray()[bcs.bci() +3] & 0xff;
1195 verify_cp_class_type(bci, index, cp);
1196 VerificationType new_array_type =
1197 cp_index_to_type(index, cp);
1198 if (!new_array_type.is_array()) {
1199 verifyError("Illegal constant pool index in multianewarray instruction");
1200 }
1201 if (dim < 1 || new_array_type.dimensions(this) < dim) {
1202 verifyError(String.format("Illegal dimension in multianewarray instruction: %d", dim));
1203 }
1204 for (int i = 0; i < dim; i++) {
1205 current_frame.pop_stack(
1206 VerificationType.integer_type);
1207 }
1208 current_frame.push_stack(new_array_type);
1209 no_control_flow = false; break;
1210 }
1211 case ATHROW :
1212 type = VerificationType.reference_type(java_lang_Throwable);
1213 current_frame.pop_stack(type);
1214 no_control_flow = true; break;
1215 default:
1216 verifyError(String.format("Bad instruction: %02x", opcode));
1217 }
1218 }
1219 if (verified_exc_handlers && this_uninit) verifyError("Exception handler targets got verified before this_uninit got set");
1220 if (!verified_exc_handlers && bci >= ex_minmax[0] && bci < ex_minmax[1]) {
1221 verify_exception_handler_targets(bci, this_uninit, current_frame, stackmap_table);
1222 }
1223 }
1224 if (!no_control_flow) {
1225 verifyError("Control flow falls through code end");
1226 }
1227 }
1228
1229 private byte[] generate_code_data(RawBytecodeHelper.CodeRange code) {
1230 byte[] code_data = new byte[code.length()];
1231 var bcs = code.start();
1232 while (bcs.next()) {
1233 if (bcs.opcode() != ILLEGAL) {
1234 int bci = bcs.bci();
1235 if (bcs.opcode() == NEW) {
1236 code_data[bci] = NEW_OFFSET;
1237 } else {
1238 code_data[bci] = BYTECODE_OFFSET;
1239 }
1240 } else {
1241 verifyError("Bad instruction");
1242 }
1243 }
1244 return code_data;
1245 }
1246
1247 void verify_exception_handler_table(int code_length, byte[] code_data, int[] minmax) {
1248 var cp = _method.constantPool();
1249 for (var exhandler : _method.exceptionTable()) {
1250 int start_pc = exhandler[0];
1251 int end_pc = exhandler[1];
1252 int handler_pc = exhandler[2];
1253 if (start_pc >= code_length || code_data[start_pc] == 0) {
1254 classError(String.format("Illegal exception table start_pc %d", start_pc));
1255 }
1256 if (end_pc != code_length) {
1257 if (end_pc > code_length || code_data[end_pc] == 0) {
1258 classError(String.format("Illegal exception table end_pc %d", end_pc));
1259 }
1260 }
1261 if (handler_pc >= code_length || code_data[handler_pc] == 0) {
1262 classError(String.format("Illegal exception table handler_pc %d", handler_pc));
1263 }
1264 int catch_type_index = exhandler[3];
1265 if (catch_type_index != 0) {
1266 VerificationType catch_type = cp_index_to_type(catch_type_index, cp);
1267 VerificationType throwable = VerificationType.reference_type(java_lang_Throwable);
1268 // 8267118 Not applicable here
1269 boolean is_subclass = throwable.is_assignable_from(catch_type, this);
1270 if (!is_subclass) {
1271 verifyError(String.format("Catch type is not a subclass of Throwable in exception handler %d", handler_pc));
1272 }
1273 }
1274 if (start_pc < minmax[0]) minmax[0] = start_pc;
1275 if (end_pc > minmax[1]) minmax[1] = end_pc;
1276 }
1277 }
1278
1279 void verify_local_variable_table(int code_length, byte[] code_data) {
1280 for (var lvte : _method.localVariableTable()) {
1281 int start_bci = lvte.startPc();
1282 int length = lvte.length();
1283 if (start_bci >= code_length || code_data[start_bci] == 0) {
1284 classError(String.format("Illegal local variable table start_pc %d", start_bci));
1285 }
1286 int end_bci = start_bci + length;
1287 if (end_bci != code_length) {
1288 if (end_bci >= code_length || code_data[end_bci] == 0) {
1289 classError(String.format("Illegal local variable table length %d", length));
1290 }
1291 }
1292 }
1293 }
1294
1295 int verify_stackmap_table(int stackmap_index, int bci, VerificationFrame current_frame, VerificationTable stackmap_table, boolean no_control_flow) {
1296 if (stackmap_index < stackmap_table.get_frame_count()) {
1297 int this_offset = stackmap_table.get_offset(stackmap_index);
1298 if (no_control_flow && this_offset > bci) {
1299 verifyError("Expecting a stack map frame");
1300 }
1301 if (this_offset == bci) {
1302 boolean matches = stackmap_table.match_stackmap(current_frame, this_offset, stackmap_index, !no_control_flow, true);
1303 if (!matches) {
1304 verifyError("Instruction type does not match stack map");
1305 }
1306 stackmap_index++;
1307 } else if (this_offset < bci) {
1308 classError(String.format("Bad stack map offset %d", this_offset));
1309 }
1310 } else if (no_control_flow) {
1311 verifyError("Expecting a stack map frame");
1312 }
1313 return stackmap_index;
1314 }
1315
1316 void verify_exception_handler_targets(int bci, boolean this_uninit, VerificationFrame current_frame, VerificationTable stackmap_table) {
1317 var cp = _method.constantPool();
1318 for(var exhandler : _method.exceptionTable()) {
1319 int start_pc = exhandler[0];
1320 int end_pc = exhandler[1];
1321 int handler_pc = exhandler[2];
1322 int catch_type_index = exhandler[3];
1323 if(bci >= start_pc && bci < end_pc) {
1324 int flags = current_frame.flags();
1325 if (this_uninit) { flags |= FLAG_THIS_UNINIT; }
1326 VerificationFrame new_frame = current_frame.frame_in_exception_handler(flags);
1327 if (catch_type_index != 0) {
1328 VerificationType catch_type = cp_index_to_type(catch_type_index, cp);
1329 new_frame.push_stack(catch_type);
1330 } else {
1331 VerificationType throwable = VerificationType.reference_type(java_lang_Throwable);
1332 new_frame.push_stack(throwable);
1333 }
1334 boolean matches = stackmap_table.match_stackmap(new_frame, handler_pc, true, false);
1335 if (!matches) {
1336 verifyError(String.format("Stack map does not match the one at exception handler %d", handler_pc));
1337 }
1338 }
1339 }
1340 }
1341
1342 void verify_cp_index(int bci, ConstantPoolWrapper cp, int index) {
1343 int nconstants = cp.entryCount();
1344 if ((index <= 0) || (index >= nconstants)) {
1345 verifyError(String.format("Illegal constant pool index %d", index));
1346 }
1347 }
1348
1349 void verify_cp_type(int bci, int index, ConstantPoolWrapper cp, int types) {
1350 verify_cp_index(bci, cp, index);
1351 int tag = cp.tagAt(index);
1352 if (tag > JVM_CONSTANT_ExternalMax || (types & (1 << tag))== 0) {
1353 verifyError(String.format("Illegal type at constant pool entry %d", index));
1354 }
1355 }
1356
1357 void verify_cp_class_type(int bci, int index, ConstantPoolWrapper cp) {
1358 verify_cp_index(bci, cp, index);
1359 int tag = cp.tagAt(index);
1360 if (tag != JVM_CONSTANT_Class) {
1361 verifyError(String.format("Illegal type at constant pool entry %d", index));
1362 }
1363 }
1364
1365 void verify_ldc(int opcode, int index, VerificationFrame current_frame, ConstantPoolWrapper cp, int bci) {
1366 verify_cp_index(bci, cp, index);
1367 int tag = cp.tagAt(index);
1368 int types = 0;
1369 if (opcode == LDC || opcode == LDC_W) {
1370 types = (1 << JVM_CONSTANT_Integer) | (1 << JVM_CONSTANT_Float)
1371 | (1 << JVM_CONSTANT_String) | (1 << JVM_CONSTANT_Class)
1372 | (1 << JVM_CONSTANT_MethodHandle) | (1 << JVM_CONSTANT_MethodType)
1373 | (1 << JVM_CONSTANT_Dynamic);
1374 verify_cp_type(bci, index, cp, types);
1375 } else {
1376 if (opcode != LDC2_W) verifyError("must be ldc2_w");
1377 types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long) | (1 << JVM_CONSTANT_Dynamic);
1378 verify_cp_type(bci, index, cp, types);
1379 }
1380 switch (tag) {
1381 case JVM_CONSTANT_Utf8 -> current_frame.push_stack(object_type());
1382 case JVM_CONSTANT_String -> current_frame.push_stack(VerificationType.reference_type(java_lang_String));
1383 case JVM_CONSTANT_Class -> current_frame.push_stack(VerificationType.reference_type(java_lang_Class));
1384 case JVM_CONSTANT_Integer -> current_frame.push_stack(VerificationType.integer_type);
1385 case JVM_CONSTANT_Float -> current_frame.push_stack(VerificationType.float_type);
1386 case JVM_CONSTANT_Double -> current_frame.push_stack_2(VerificationType.double_type, VerificationType.double2_type);
1387 case JVM_CONSTANT_Long -> current_frame.push_stack_2(VerificationType.long_type, VerificationType.long2_type);
1388 case JVM_CONSTANT_MethodHandle -> current_frame.push_stack(VerificationType.reference_type(java_lang_invoke_MethodHandle));
1389 case JVM_CONSTANT_MethodType -> current_frame.push_stack(VerificationType.reference_type(java_lang_invoke_MethodType));
1390 case JVM_CONSTANT_Dynamic -> {
1391 String constant_type = cp.dynamicConstantSignatureAt(index);
1392 if (!VerificationSignature.isValidTypeSignature(constant_type)) verifyError("Invalid type for dynamic constant");
1393 VerificationType[] v_constant_type = new VerificationType[2];
1394 var sig_stream = new VerificationSignature(constant_type, false, this);
1395 int n = change_sig_to_verificationType(sig_stream, v_constant_type, 0);
1396 int opcode_n = (opcode == LDC2_W ? 2 : 1);
1397 if (n != opcode_n) {
1398 types &= ~(1 << JVM_CONSTANT_Dynamic);
1399 verify_cp_type(bci, index, cp, types);
1400 }
1401 for (int i = 0; i < n; i++) {
1402 current_frame.push_stack(v_constant_type[i]);
1403 }
1404 }
1405 default -> verifyError("Invalid index in ldc");
1406 }
1407 }
1408
1409 void verify_switch(RawBytecodeHelper bcs, int code_length, byte[] code_data, VerificationFrame current_frame, VerificationTable stackmap_table) {
1410 int bci = bcs.bci();
1411 int aligned_bci = VerificationBytecodes.align(bci + 1);
1412 // 4639449 & 4647081: padding bytes must be 0
1413 if (_klass.majorVersion() < NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION) {
1414 int padding_offset = 1;
1415 while ((bci + padding_offset) < aligned_bci) {
1416 if (_method.codeArray()[bci + padding_offset] != 0) {
1417 verifyError("Nonzero padding byte in lookupswitch or tableswitch");
1418 }
1419 padding_offset++;
1420 }
1421 }
1422 int default_offset = bcs.getIntUnchecked(aligned_bci);
1423 int keys, delta;
1424 current_frame.pop_stack(VerificationType.integer_type);
1425 if (bcs.opcode() == TABLESWITCH) {
1426 int low = bcs.getIntUnchecked(aligned_bci + 4);
1427 int high = bcs.getIntUnchecked(aligned_bci + 2*4);
1428 if (low > high) {
1429 verifyError("low must be less than or equal to high in tableswitch");
1430 }
1431 long keys64 = ((long) high - low) + 1;
1432 if (keys64 > 65535) { // Max code length
1433 verifyError("too many keys in tableswitch");
1434 }
1435 keys = (int) keys64;
1436 delta = 1;
1437 } else {
1438 // Make sure that the lookupswitch items are sorted
1439 keys = bcs.getIntUnchecked(aligned_bci + 4);
1440 if (keys < 0) {
1441 verifyError("number of keys in lookupswitch less than 0");
1442 }
1443 delta = 2;
1444 for (int i = 0; i < (keys - 1); i++) {
1445 int this_key = bcs.getIntUnchecked(aligned_bci + (2+2*i)*4);
1446 int next_key = bcs.getIntUnchecked(aligned_bci + (2+2*i+2)*4);
1447 if (this_key >= next_key) {
1448 verifyError("Bad lookupswitch instruction");
1449 }
1450 }
1451 }
1452 int target = bci + default_offset;
1453 stackmap_table.check_jump_target(current_frame, target);
1454 for (int i = 0; i < keys; i++) {
1455 aligned_bci = VerificationBytecodes.align(bcs.bci() + 1);
1456 target = bci + bcs.getIntUnchecked(aligned_bci + (3+i*delta)*4);
1457 stackmap_table.check_jump_target(current_frame, target);
1458 }
1459 }
1460
1461 void verify_field_instructions(RawBytecodeHelper bcs, VerificationFrame current_frame, ConstantPoolWrapper cp, boolean allow_arrays) {
1462 int index = bcs.getIndexU2();
1463 verify_cp_type(bcs.bci(), index, cp, 1 << JVM_CONSTANT_Fieldref);
1464 String field_name = cp.refNameAt(index);
1465 String field_sig = cp.refSignatureAt(index);
1466 if (!VerificationSignature.isValidTypeSignature(field_sig)) verifyError("Invalid field signature");
1467 VerificationType ref_class_type = cp_ref_index_to_type(index, cp);
1468 if (!ref_class_type.is_object() &&
1469 (!allow_arrays || !ref_class_type.is_array())) {
1470 verifyError(String.format("Expecting reference to class in class %s at constant pool index %d", _klass.thisClassName(), index));
1471 }
1472 VerificationType target_class_type = ref_class_type;
1473 VerificationType[] field_type = new VerificationType[2];
1474 var sig_stream = new VerificationSignature(field_sig, false, this);
1475 VerificationType stack_object_type = null;
1476 int n = change_sig_to_verificationType(sig_stream, field_type, 0);
1477 boolean is_assignable;
1478 switch (bcs.opcode()) {
1479 case GETSTATIC -> {
1480 for (int i = 0; i < n; i++) {
1481 current_frame.push_stack(field_type[i]);
1482 }
1483 }
1484 case PUTSTATIC -> {
1485 for (int i = n - 1; i >= 0; i--) {
1486 current_frame.pop_stack(field_type[i]);
1487 }
1488 }
1489 case GETFIELD -> {
1490 stack_object_type = current_frame.pop_stack(
1491 target_class_type);
1492 // 8270398 Not applicable here
1493 for (int i = 0; i < n; i++) {
1494 current_frame.push_stack(field_type[i]);
1495 }
1496 }
1497 case PUTFIELD -> {
1498 for (int i = n - 1; i >= 0; i--) {
1499 current_frame.pop_stack(field_type[i]);
1500 }
1501 stack_object_type = current_frame.pop_stack();
1502 if (stack_object_type.is_uninitialized_this(this) &&
1503 target_class_type.equals(current_type()) &&
1504 _klass.findField(field_name, field_sig)) {
1505 stack_object_type = current_type();
1506 }
1507 is_assignable = target_class_type.is_assignable_from(stack_object_type, this);
1508 if (!is_assignable) {
1509 verifyError("Bad type on operand stack in putfield");
1510 }
1511 }
1512 default -> verifyError("Should not reach here");
1513 }
1514 }
1515
1516 boolean verify_invoke_init(RawBytecodeHelper bcs, int ref_class_index, VerificationType ref_class_type,
1517 VerificationFrame current_frame, int code_length, boolean in_try_block,
1518 boolean this_uninit, ConstantPoolWrapper cp, VerificationTable stackmap_table) {
1519 int bci = bcs.bci();
1520 VerificationType type = current_frame.pop_stack(VerificationType.reference_check);
1521 if (type.is_uninitialized_this(this)) {
1522 String superk_name = current_class().superclassName();
1523 if (!current_class().thisClassName().equals(ref_class_type.name()) &&
1524 !superk_name.equals(ref_class_type.name())) {
1525 verifyError("Bad <init> method call");
1526 }
1527 if (in_try_block) {
1528 verify_exception_handler_targets(bci, true, current_frame, stackmap_table);
1529 }
1530 current_frame.initialize_object(type, current_type());
1531 this_uninit = true;
1532 } else if (type.is_uninitialized()) {
1533 int new_offset = type.bci(this);
1534 if (new_offset > (code_length - 3) || (_method.codeArray()[new_offset] & 0xff) != NEW) {
1535 verifyError("Expecting new instruction");
1536 }
1537 int new_class_index = bcs.getU2(new_offset + 1);
1538 verify_cp_class_type(bci, new_class_index, cp);
1539 VerificationType new_class_type = cp_index_to_type(
1540 new_class_index, cp);
1541 if (!new_class_type.equals(ref_class_type)) {
1542 verifyError("Call to wrong <init> method");
1543 }
1544 if (in_try_block) {
1545 verify_exception_handler_targets(bci, this_uninit, current_frame,
1546 stackmap_table);
1547 }
1548 current_frame.initialize_object(type, new_class_type);
1549 } else {
1550 verifyError("Bad operand type when invoking <init>");
1551 }
1552 return this_uninit;
1553 }
1554
1555 static boolean is_same_or_direct_interface(VerificationWrapper klass, VerificationType klass_type, VerificationType ref_class_type) {
1556 if (ref_class_type.equals(klass_type)) return true;
1557 for (String k_name : klass.interfaceNames()) {
1558 if (ref_class_type.equals(VerificationType.reference_type(k_name))) {
1559 return true;
1560 }
1561 }
1562 return false;
1563 }
1564
1565 boolean verify_invoke_instructions(RawBytecodeHelper bcs, int code_length, VerificationFrame current_frame, boolean in_try_block, boolean this_uninit, VerificationType return_type, ConstantPoolWrapper cp, VerificationTable stackmap_table) {
1566 // Make sure the constant pool item is the right type
1567 int index = bcs.getIndexU2();
1568 int opcode = bcs.opcode();
1569 int types = 0;
1570 switch (opcode) {
1571 case INVOKEINTERFACE:
1572 types = 1 << JVM_CONSTANT_InterfaceMethodref;
1573 break;
1574 case INVOKEDYNAMIC:
1575 types = 1 << JVM_CONSTANT_InvokeDynamic;
1576 break;
1577 case INVOKESPECIAL:
1578 case INVOKESTATIC:
1579 types = (_klass.majorVersion() < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION) ?
1580 (1 << JVM_CONSTANT_Methodref) :
1581 ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref));
1582 break;
1583 default:
1584 types = 1 << JVM_CONSTANT_Methodref;
1585 }
1586 verify_cp_type(bcs.bci(), index, cp, types);
1587 String method_name = cp.refNameAt(index);
1588 String method_sig = cp.refSignatureAt(index);
1589 if (!VerificationSignature.isValidMethodSignature(method_sig)) verifyError("Invalid method signature");
1590 VerificationType ref_class_type = null;
1591 if (opcode == INVOKEDYNAMIC) {
1592 if (_klass.majorVersion() < INVOKEDYNAMIC_MAJOR_VERSION) {
1593 classError(String.format("invokedynamic instructions not supported by this class file version (%d), class %s", _klass.majorVersion(), _klass.thisClassName()));
1594 }
1595 } else {
1596 ref_class_type = cp_ref_index_to_type(index, cp);
1597 }
1598 String sig = cp.refSignatureAt(index);
1599 sig_as_verification_types mth_sig_verif_types;
1600 ArrayList<VerificationType> verif_types = new ArrayList<>(10);
1601 mth_sig_verif_types = new sig_as_verification_types(verif_types);
1602 create_method_sig_entry(mth_sig_verif_types, sig);
1603 int nargs = mth_sig_verif_types.num_args();
1604 int bci = bcs.bci();
1605 if (opcode == INVOKEINTERFACE) {
1606 if ((_method.codeArray()[bci+3] & 0xff) != (nargs+1)) {
1607 verifyError("Inconsistent args count operand in invokeinterface");
1608 }
1609 if ((_method.codeArray()[bci+4] & 0xff) != 0) {
1610 verifyError("Fourth operand byte of invokeinterface must be zero");
1611 }
1612 }
1613 if (opcode == INVOKEDYNAMIC) {
1614 if ((_method.codeArray()[bci+3] & 0xff) != 0 || (_method.codeArray()[bci+4] & 0xff) != 0) {
1615 verifyError("Third and fourth operand bytes of invokedynamic must be zero");
1616 }
1617 }
1618 if (method_name.charAt(0) == JVM_SIGNATURE_SPECIAL) {
1619 if (opcode != INVOKESPECIAL ||
1620 !object_initializer_name.equals(method_name)) {
1621 verifyError("Illegal call to internal method");
1622 }
1623 } else if (opcode == INVOKESPECIAL
1624 && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type)
1625 && !ref_class_type.equals(VerificationType.reference_type(
1626 current_class().superclassName()))) {
1627
1628 // We know it is not current class, direct superinterface or immediate superclass. That means it
1629 // could be:
1630 // - a totally unrelated class or interface
1631 // - an indirect superinterface
1632 // - an indirect superclass (including Object)
1633 // We use the assignability test to see if it is a superclass, or else an interface, and keep track
1634 // of the latter. Note that subtype can be true if we are dealing with an interface that is not actually
1635 // implemented as assignability treats all interfaces as Object.
1636
1637 boolean[] is_interface = {false}; // This can only be set true if the assignability check will return true
1638 // and we loaded the class. For any other "true" returns (e.g. same class
1639 // or Object) we either can't get here (same class already excluded above)
1640 // or we know it is not an interface (i.e. Object).
1641 boolean subtype = ref_class_type.is_reference_assignable_from(current_type(), this, is_interface);
1642 if (!subtype) { // Totally unrelated class
1643 verifyError("Bad invokespecial instruction: current class isn't assignable to reference class.");
1644 } else {
1645 // Indirect superclass (including Object), indirect interface, or unrelated interface.
1646 // Any interface use is an error.
1647 if (is_interface[0]) {
1648 verifyError("Bad invokespecial instruction: interface method to invoke is not in a direct superinterface.");
1649 }
1650 }
1651
1652 }
1653 ArrayList<VerificationType> sig_verif_types = mth_sig_verif_types.sig_verif_types();
1654 if (sig_verif_types == null) verifyError("Missing signature's array of verification types");
1655 for (int i = nargs - 1; i >= 0; i--) { // Run backwards
1656 current_frame.pop_stack(sig_verif_types.get(i));
1657 }
1658 if (opcode != INVOKESTATIC &&
1659 opcode != INVOKEDYNAMIC) {
1660 if (object_initializer_name.equals(method_name)) { // <init> method
1661 this_uninit = verify_invoke_init(bcs, index, ref_class_type, current_frame,
1662 code_length, in_try_block, this_uninit, cp, stackmap_table);
1663 } else {
1664 switch (opcode) {
1665 case INVOKESPECIAL ->
1666 current_frame.pop_stack(current_type());
1667 case INVOKEVIRTUAL -> {
1668 VerificationType stack_object_type =
1669 current_frame.pop_stack(ref_class_type);
1670 if (current_type() != stack_object_type) {
1671 cp.classNameAt(cp.refClassIndexAt(index));
1672 }
1673 }
1674 default -> {
1675 if (opcode != INVOKEINTERFACE)
1676 verifyError("Unexpected opcode encountered");
1677 current_frame.pop_stack(ref_class_type);
1678 }
1679 }
1680 }
1681 }
1682 int sig_verif_types_len = sig_verif_types.size();
1683 if (sig_verif_types_len > nargs) { // There's a return type
1684 if (object_initializer_name.equals(method_name)) {
1685 verifyError("Return type must be void in <init> method");
1686 }
1687
1688 if (sig_verif_types_len > nargs + 2) verifyError("Signature verification types array return type is bogus");
1689 for (int i = nargs; i < sig_verif_types_len; i++) {
1690 if (!(i == nargs || sig_verif_types.get(i).is_long2() || sig_verif_types.get(i).is_double2())) verifyError("Unexpected return verificationType");
1691 current_frame.push_stack(sig_verif_types.get(i));
1692 }
1693 }
1694 return this_uninit;
1695 }
1696
1697 VerificationType get_newarray_type(int index, int bci) {
1698 String[] from_bt = new String[] {
1699 null, null, null, null, "[Z", "[C", "[F", "[D", "[B", "[S", "[I", "[J",
1700 };
1701 if (index < T_BOOLEAN.type || index > T_LONG.type) {
1702 verifyError("Illegal newarray instruction");
1703 }
1704 String sig = from_bt[index];
1705 return VerificationType.reference_type(sig);
1706 }
1707
1708 void verify_anewarray(int bci, int index, ConstantPoolWrapper cp, VerificationFrame current_frame) {
1709 verify_cp_class_type(bci, index, cp);
1710 current_frame.pop_stack(VerificationType.integer_type);
1711 VerificationType component_type = cp_index_to_type(index, cp);
1712 int length;
1713 String arr_sig_str;
1714 if (component_type.is_array()) { // it's an array
1715 String component_name = component_type.name();
1716 length = component_name.length();
1717 if (length > MAX_ARRAY_DIMENSIONS &&
1718 component_name.charAt(MAX_ARRAY_DIMENSIONS - 1) == JVM_SIGNATURE_ARRAY) {
1719 verifyError("Illegal anewarray instruction, array has more than 255 dimensions");
1720 }
1721 length++;
1722 arr_sig_str = String.format("%c%s", JVM_SIGNATURE_ARRAY, component_name);
1723 if (arr_sig_str.length() != length) verifyError("Unexpected number of characters in string");
1724 } else { // it's an object or interface
1725 String component_name = component_type.name();
1726 length = component_name.length() + 3;
1727 arr_sig_str = String.format("%c%c%s;", JVM_SIGNATURE_ARRAY, JVM_SIGNATURE_CLASS, component_name);
1728 if (arr_sig_str.length() != length) verifyError("Unexpected number of characters in string");
1729 }
1730 VerificationType new_array_type = VerificationType.reference_type(arr_sig_str);
1731 current_frame.push_stack(new_array_type);
1732 }
1733
1734 void verify_iload(int index, VerificationFrame current_frame) {
1735 current_frame.get_local(
1736 index, VerificationType.integer_type);
1737 current_frame.push_stack(
1738 VerificationType.integer_type);
1739 }
1740
1741 void verify_lload(int index, VerificationFrame current_frame) {
1742 current_frame.get_local_2(
1743 index, VerificationType.long_type,
1744 VerificationType.long2_type);
1745 current_frame.push_stack_2(
1746 VerificationType.long_type,
1747 VerificationType.long2_type);
1748 }
1749
1750 void verify_fload(int index, VerificationFrame current_frame) {
1751 current_frame.get_local(
1752 index, VerificationType.float_type);
1753 current_frame.push_stack(
1754 VerificationType.float_type);
1755 }
1756
1757 void verify_dload(int index, VerificationFrame current_frame) {
1758 current_frame.get_local_2(
1759 index, VerificationType.double_type,
1760 VerificationType.double2_type);
1761 current_frame.push_stack_2(
1762 VerificationType.double_type,
1763 VerificationType.double2_type);
1764 }
1765
1766 void verify_aload(int index, VerificationFrame current_frame) {
1767 VerificationType type = current_frame.get_local(
1768 index, VerificationType.reference_check);
1769 current_frame.push_stack(type);
1770 }
1771
1772 void verify_istore(int index, VerificationFrame current_frame) {
1773 current_frame.pop_stack(
1774 VerificationType.integer_type);
1775 current_frame.set_local(
1776 index, VerificationType.integer_type);
1777 }
1778
1779 void verify_lstore(int index, VerificationFrame current_frame) {
1780 current_frame.pop_stack_2(
1781 VerificationType.long2_type,
1782 VerificationType.long_type);
1783 current_frame.set_local_2(
1784 index, VerificationType.long_type,
1785 VerificationType.long2_type);
1786 }
1787
1788 void verify_fstore(int index, VerificationFrame current_frame) {
1789 current_frame.pop_stack(
1790 VerificationType.float_type);
1791 current_frame.set_local(
1792 index, VerificationType.float_type);
1793 }
1794
1795 void verify_dstore(int index, VerificationFrame current_frame) {
1796 current_frame.pop_stack_2(
1797 VerificationType.double2_type,
1798 VerificationType.double_type);
1799 current_frame.set_local_2(
1800 index, VerificationType.double_type,
1801 VerificationType.double2_type);
1802 }
1803
1804 void verify_astore(int index, VerificationFrame current_frame) {
1805 VerificationType type = current_frame.pop_stack(
1806 VerificationType.reference_check);
1807 current_frame.set_local(index, type);
1808 }
1809
1810 void verify_iinc(int index, VerificationFrame current_frame) {
1811 VerificationType type = current_frame.get_local(
1812 index, VerificationType.integer_type);
1813 current_frame.set_local(index, type);
1814 }
1815
1816 void verify_return_value(VerificationType return_type, VerificationType type, int bci, VerificationFrame current_frame) {
1817 if (return_type.is_bogus()) {
1818 verifyError("Method does not expect a return value");
1819 }
1820 boolean match = return_type.is_assignable_from(type, this);
1821 if (!match) {
1822 verifyError("Bad return type");
1823 }
1824 }
1825
1826 private void dumpMethod() {
1827 if (_logger != null) ClassPrinter.toTree(_method.m, ClassPrinter.Verbosity.CRITICAL_ATTRIBUTES).toYaml(_logger);
1828 }
1829
1830 void verifyError(String msg) {
1831 dumpMethod();
1832 throw new VerifyError(String.format("%s in %s::%s(%s) @%d %s", msg, _klass.thisClassName(), _method.name(), _method.parameters(), bci, errorContext).trim());
1833 }
1834
1835 void verifyError(String msg, VerificationFrame from, VerificationFrame target) {
1836 dumpMethod();
1837 throw new VerifyError(String.format("%s in %s::%s(%s) @%d %s%n while assigning %s%n to %s", msg, _klass.thisClassName(), _method.name(), _method.parameters(), bci, errorContext, from, target));
1838 }
1839
1840 void classError(String msg) {
1841 dumpMethod();
1842 throw new VerifyError(String.format("%s in %s::%s(%s)", msg, _klass.thisClassName(), _method.name(), _method.parameters()));
1843 }
1844 }