1 /*
2 * Copyright (c) 2022, 2026, 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(object_type());
1051 // fall through
1052 case IFNULL :
1053 case IFNONNULL :
1054 current_frame.pop_stack(object_type());
1055 target = bcs.dest();
1056 stackmap_table.check_jump_target
1057 (current_frame, target);
1058 no_control_flow = false; break;
1059 case GOTO :
1060 target = bcs.dest();
1061 stackmap_table.check_jump_target(
1062 current_frame, target);
1063 no_control_flow = true; break;
1064 case GOTO_W :
1065 target = bcs.destW();
1066 stackmap_table.check_jump_target(
1067 current_frame, target);
1068 no_control_flow = true; break;
1069 case TABLESWITCH :
1070 case LOOKUPSWITCH :
1071 verify_switch(
1072 bcs, code_length, code_data, current_frame,
1073 stackmap_table);
1074 no_control_flow = true; break;
1075 case IRETURN :
1076 type = current_frame.pop_stack(
1077 VerificationType.integer_type);
1078 verify_return_value(return_type, type, bci,
1079 current_frame);
1080 no_control_flow = true; break;
1081 case LRETURN :
1082 type2 = current_frame.pop_stack(
1083 VerificationType.long2_type);
1084 type = current_frame.pop_stack(
1085 VerificationType.long_type);
1086 verify_return_value(return_type, type, bci,
1087 current_frame);
1088 no_control_flow = true; break;
1089 case FRETURN :
1090 type = current_frame.pop_stack(
1091 VerificationType.float_type);
1092 verify_return_value(return_type, type, bci,
1093 current_frame);
1094 no_control_flow = true; break;
1095 case DRETURN :
1096 type2 = current_frame.pop_stack(
1097 VerificationType.double2_type);
1098 type = current_frame.pop_stack(
1099 VerificationType.double_type);
1100 verify_return_value(return_type, type, bci,
1101 current_frame);
1102 no_control_flow = true; break;
1103 case ARETURN :
1104 type = current_frame.pop_stack(
1105 VerificationType.reference_check);
1106 verify_return_value(return_type, type, bci,
1107 current_frame);
1108 no_control_flow = true; break;
1109 case RETURN:
1110 if (!return_type.is_bogus()) {
1111 verifyError("Method expects a return value");
1112 }
1113 if (object_initializer_name.equals(_method.name()) &&
1114 current_frame.flag_this_uninit()) {
1115 verifyError("Constructor must call super() or this() before return");
1116 }
1117 no_control_flow = true; break;
1118 case GETSTATIC :
1119 case PUTSTATIC :
1120 verify_field_instructions(bcs, current_frame, cp, true);
1121 no_control_flow = false; break;
1122 case GETFIELD :
1123 case PUTFIELD :
1124 verify_field_instructions(bcs, current_frame, cp, false);
1125 no_control_flow = false; break;
1126 case INVOKEVIRTUAL :
1127 case INVOKESPECIAL :
1128 case INVOKESTATIC :
1129 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);
1130 no_control_flow = false; break;
1131 case INVOKEINTERFACE :
1132 case INVOKEDYNAMIC :
1133 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);
1134 no_control_flow = false; break;
1135 case NEW :
1136 {
1137 index = bcs.getIndexU2();
1138 verify_cp_class_type(bci, index, cp);
1139 VerificationType new_class_type =
1140 cp_index_to_type(index, cp);
1141 if (!new_class_type.is_object()) {
1142 verifyError("Illegal new instruction");
1143 }
1144 type = VerificationType.uninitialized_type(bci);
1145 current_frame.push_stack(type);
1146 no_control_flow = false; break;
1147 }
1148 case NEWARRAY :
1149 type = get_newarray_type(bcs.getIndex(), bci);
1150 current_frame.pop_stack(
1151 VerificationType.integer_type);
1152 current_frame.push_stack(type);
1153 no_control_flow = false; break;
1154 case ANEWARRAY :
1155 verify_anewarray(bci, bcs.getIndexU2(), cp, current_frame);
1156 no_control_flow = false; break;
1157 case ARRAYLENGTH :
1158 type = current_frame.pop_stack(
1159 VerificationType.reference_check);
1160 if (!(type.is_null() || type.is_array())) {
1161 verifyError("Bad type");
1162 }
1163 current_frame.push_stack(
1164 VerificationType.integer_type);
1165 no_control_flow = false; break;
1166 case CHECKCAST :
1167 {
1168 index = bcs.getIndexU2();
1169 verify_cp_class_type(bci, index, cp);
1170 current_frame.pop_stack(object_type());
1171 VerificationType klass_type = cp_index_to_type(
1172 index, cp);
1173 current_frame.push_stack(klass_type);
1174 no_control_flow = false; break;
1175 }
1176 case INSTANCEOF : {
1177 index = bcs.getIndexU2();
1178 verify_cp_class_type(bci, index, cp);
1179 current_frame.pop_stack(object_type());
1180 current_frame.push_stack(
1181 VerificationType.integer_type);
1182 no_control_flow = false; break;
1183 }
1184 case MONITORENTER :
1185 case MONITOREXIT :
1186 current_frame.pop_stack(
1187 VerificationType.reference_check);
1188 no_control_flow = false; break;
1189 case MULTIANEWARRAY :
1190 {
1191 index = bcs.getIndexU2();
1192 int dim = _method.codeArray()[bcs.bci() +3] & 0xff;
1193 verify_cp_class_type(bci, index, cp);
1194 VerificationType new_array_type =
1195 cp_index_to_type(index, cp);
1196 if (!new_array_type.is_array()) {
1197 verifyError("Illegal constant pool index in multianewarray instruction");
1198 }
1199 if (dim < 1 || new_array_type.dimensions(this) < dim) {
1200 verifyError(String.format("Illegal dimension in multianewarray instruction: %d", dim));
1201 }
1202 for (int i = 0; i < dim; i++) {
1203 current_frame.pop_stack(
1204 VerificationType.integer_type);
1205 }
1206 current_frame.push_stack(new_array_type);
1207 no_control_flow = false; break;
1208 }
1209 case ATHROW :
1210 type = VerificationType.reference_type(java_lang_Throwable);
1211 current_frame.pop_stack(type);
1212 no_control_flow = true; break;
1213 default:
1214 verifyError(String.format("Bad instruction: %02x", opcode));
1215 }
1216 }
1217 if (verified_exc_handlers && this_uninit) verifyError("Exception handler targets got verified before this_uninit got set");
1218 if (!verified_exc_handlers && bci >= ex_minmax[0] && bci < ex_minmax[1]) {
1219 verify_exception_handler_targets(bci, this_uninit, current_frame, stackmap_table);
1220 }
1221 }
1222 if (!no_control_flow) {
1223 verifyError("Control flow falls through code end");
1224 }
1225 }
1226
1227 private byte[] generate_code_data(RawBytecodeHelper.CodeRange code) {
1228 byte[] code_data = new byte[code.length()];
1229 var bcs = code.start();
1230 while (bcs.next()) {
1231 if (bcs.opcode() != ILLEGAL) {
1232 int bci = bcs.bci();
1233 if (bcs.opcode() == NEW) {
1234 code_data[bci] = NEW_OFFSET;
1235 } else {
1236 code_data[bci] = BYTECODE_OFFSET;
1237 }
1238 } else {
1239 verifyError("Bad instruction");
1240 }
1241 }
1242 return code_data;
1243 }
1244
1245 void verify_exception_handler_table(int code_length, byte[] code_data, int[] minmax) {
1246 var cp = _method.constantPool();
1247 for (var exhandler : _method.exceptionTable()) {
1248 int start_pc = exhandler[0];
1249 int end_pc = exhandler[1];
1250 int handler_pc = exhandler[2];
1251 if (start_pc >= code_length || code_data[start_pc] == 0) {
1252 classError(String.format("Illegal exception table start_pc %d", start_pc));
1253 }
1254 if (end_pc != code_length) {
1255 if (end_pc > code_length || code_data[end_pc] == 0) {
1256 classError(String.format("Illegal exception table end_pc %d", end_pc));
1257 }
1258 }
1259 if (handler_pc >= code_length || code_data[handler_pc] == 0) {
1260 classError(String.format("Illegal exception table handler_pc %d", handler_pc));
1261 }
1262 int catch_type_index = exhandler[3];
1263 if (catch_type_index != 0) {
1264 VerificationType catch_type = cp_index_to_type(catch_type_index, cp);
1265 VerificationType throwable = VerificationType.reference_type(java_lang_Throwable);
1266 // 8267118 Not applicable here
1267 boolean is_subclass = throwable.is_assignable_from(catch_type, this);
1268 if (!is_subclass) {
1269 verifyError(String.format("Catch type is not a subclass of Throwable in exception handler %d", handler_pc));
1270 }
1271 }
1272 if (start_pc < minmax[0]) minmax[0] = start_pc;
1273 if (end_pc > minmax[1]) minmax[1] = end_pc;
1274 }
1275 }
1276
1277 void verify_local_variable_table(int code_length, byte[] code_data) {
1278 for (var lvte : _method.localVariableTable()) {
1279 int start_bci = lvte.startPc();
1280 int length = lvte.length();
1281 if (start_bci >= code_length || code_data[start_bci] == 0) {
1282 classError(String.format("Illegal local variable table start_pc %d", start_bci));
1283 }
1284 int end_bci = start_bci + length;
1285 if (end_bci != code_length) {
1286 if (end_bci >= code_length || code_data[end_bci] == 0) {
1287 classError(String.format("Illegal local variable table length %d", length));
1288 }
1289 }
1290 }
1291 }
1292
1293 int verify_stackmap_table(int stackmap_index, int bci, VerificationFrame current_frame, VerificationTable stackmap_table, boolean no_control_flow) {
1294 if (stackmap_index < stackmap_table.get_frame_count()) {
1295 int this_offset = stackmap_table.get_offset(stackmap_index);
1296 if (no_control_flow && this_offset > bci) {
1297 verifyError("Expecting a stack map frame");
1298 }
1299 if (this_offset == bci) {
1300 boolean matches = stackmap_table.match_stackmap(current_frame, this_offset, stackmap_index, !no_control_flow, true);
1301 if (!matches) {
1302 verifyError("Instruction type does not match stack map");
1303 }
1304 stackmap_index++;
1305 } else if (this_offset < bci) {
1306 classError(String.format("Bad stack map offset %d", this_offset));
1307 }
1308 } else if (no_control_flow) {
1309 verifyError("Expecting a stack map frame");
1310 }
1311 return stackmap_index;
1312 }
1313
1314 void verify_exception_handler_targets(int bci, boolean this_uninit, VerificationFrame current_frame, VerificationTable stackmap_table) {
1315 var cp = _method.constantPool();
1316 for(var exhandler : _method.exceptionTable()) {
1317 int start_pc = exhandler[0];
1318 int end_pc = exhandler[1];
1319 int handler_pc = exhandler[2];
1320 int catch_type_index = exhandler[3];
1321 if(bci >= start_pc && bci < end_pc) {
1322 int flags = current_frame.flags();
1323 if (this_uninit) { flags |= FLAG_THIS_UNINIT; }
1324 VerificationFrame new_frame = current_frame.frame_in_exception_handler(flags);
1325 if (catch_type_index != 0) {
1326 VerificationType catch_type = cp_index_to_type(catch_type_index, cp);
1327 new_frame.push_stack(catch_type);
1328 } else {
1329 VerificationType throwable = VerificationType.reference_type(java_lang_Throwable);
1330 new_frame.push_stack(throwable);
1331 }
1332 boolean matches = stackmap_table.match_stackmap(new_frame, handler_pc, true, false);
1333 if (!matches) {
1334 verifyError(String.format("Stack map does not match the one at exception handler %d", handler_pc));
1335 }
1336 }
1337 }
1338 }
1339
1340 void verify_cp_index(int bci, ConstantPoolWrapper cp, int index) {
1341 int nconstants = cp.entryCount();
1342 if ((index <= 0) || (index >= nconstants)) {
1343 verifyError(String.format("Illegal constant pool index %d", index));
1344 }
1345 }
1346
1347 void verify_cp_type(int bci, int index, ConstantPoolWrapper cp, int types) {
1348 verify_cp_index(bci, cp, index);
1349 int tag = cp.tagAt(index);
1350 if (tag > JVM_CONSTANT_ExternalMax || (types & (1 << tag))== 0) {
1351 verifyError(String.format("Illegal type at constant pool entry %d", index));
1352 }
1353 }
1354
1355 void verify_cp_class_type(int bci, int index, ConstantPoolWrapper cp) {
1356 verify_cp_index(bci, cp, index);
1357 int tag = cp.tagAt(index);
1358 if (tag != JVM_CONSTANT_Class) {
1359 verifyError(String.format("Illegal type at constant pool entry %d", index));
1360 }
1361 }
1362
1363 void verify_ldc(int opcode, int index, VerificationFrame current_frame, ConstantPoolWrapper cp, int bci) {
1364 verify_cp_index(bci, cp, index);
1365 int tag = cp.tagAt(index);
1366 int types = 0;
1367 if (opcode == LDC || opcode == LDC_W) {
1368 types = (1 << JVM_CONSTANT_Integer) | (1 << JVM_CONSTANT_Float)
1369 | (1 << JVM_CONSTANT_String) | (1 << JVM_CONSTANT_Class)
1370 | (1 << JVM_CONSTANT_MethodHandle) | (1 << JVM_CONSTANT_MethodType)
1371 | (1 << JVM_CONSTANT_Dynamic);
1372 verify_cp_type(bci, index, cp, types);
1373 } else {
1374 if (opcode != LDC2_W) verifyError("must be ldc2_w");
1375 types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long) | (1 << JVM_CONSTANT_Dynamic);
1376 verify_cp_type(bci, index, cp, types);
1377 }
1378 switch (tag) {
1379 case JVM_CONSTANT_Utf8 -> current_frame.push_stack(object_type());
1380 case JVM_CONSTANT_String -> current_frame.push_stack(VerificationType.reference_type(java_lang_String));
1381 case JVM_CONSTANT_Class -> current_frame.push_stack(VerificationType.reference_type(java_lang_Class));
1382 case JVM_CONSTANT_Integer -> current_frame.push_stack(VerificationType.integer_type);
1383 case JVM_CONSTANT_Float -> current_frame.push_stack(VerificationType.float_type);
1384 case JVM_CONSTANT_Double -> current_frame.push_stack_2(VerificationType.double_type, VerificationType.double2_type);
1385 case JVM_CONSTANT_Long -> current_frame.push_stack_2(VerificationType.long_type, VerificationType.long2_type);
1386 case JVM_CONSTANT_MethodHandle -> current_frame.push_stack(VerificationType.reference_type(java_lang_invoke_MethodHandle));
1387 case JVM_CONSTANT_MethodType -> current_frame.push_stack(VerificationType.reference_type(java_lang_invoke_MethodType));
1388 case JVM_CONSTANT_Dynamic -> {
1389 String constant_type = cp.dynamicConstantSignatureAt(index);
1390 if (!VerificationSignature.isValidTypeSignature(constant_type)) verifyError("Invalid type for dynamic constant");
1391 VerificationType[] v_constant_type = new VerificationType[2];
1392 var sig_stream = new VerificationSignature(constant_type, false, this);
1393 int n = change_sig_to_verificationType(sig_stream, v_constant_type, 0);
1394 int opcode_n = (opcode == LDC2_W ? 2 : 1);
1395 if (n != opcode_n) {
1396 types &= ~(1 << JVM_CONSTANT_Dynamic);
1397 verify_cp_type(bci, index, cp, types);
1398 }
1399 for (int i = 0; i < n; i++) {
1400 current_frame.push_stack(v_constant_type[i]);
1401 }
1402 }
1403 default -> verifyError("Invalid index in ldc");
1404 }
1405 }
1406
1407 void verify_switch(RawBytecodeHelper bcs, int code_length, byte[] code_data, VerificationFrame current_frame, VerificationTable stackmap_table) {
1408 int bci = bcs.bci();
1409 int aligned_bci = VerificationBytecodes.align(bci + 1);
1410 // 4639449 & 4647081: padding bytes must be 0
1411 if (_klass.majorVersion() < NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION) {
1412 int padding_offset = 1;
1413 while ((bci + padding_offset) < aligned_bci) {
1414 if (_method.codeArray()[bci + padding_offset] != 0) {
1415 verifyError("Nonzero padding byte in lookupswitch or tableswitch");
1416 }
1417 padding_offset++;
1418 }
1419 }
1420 int default_offset = bcs.getIntUnchecked(aligned_bci);
1421 int keys, delta;
1422 current_frame.pop_stack(VerificationType.integer_type);
1423 if (bcs.opcode() == TABLESWITCH) {
1424 int low = bcs.getIntUnchecked(aligned_bci + 4);
1425 int high = bcs.getIntUnchecked(aligned_bci + 2*4);
1426 if (low > high) {
1427 verifyError("low must be less than or equal to high in tableswitch");
1428 }
1429 long keys64 = ((long) high - low) + 1;
1430 if (keys64 > 65535) { // Max code length
1431 verifyError("too many keys in tableswitch");
1432 }
1433 keys = (int) keys64;
1434 delta = 1;
1435 } else {
1436 // Make sure that the lookupswitch items are sorted
1437 keys = bcs.getIntUnchecked(aligned_bci + 4);
1438 if (keys < 0) {
1439 verifyError("number of keys in lookupswitch less than 0");
1440 }
1441 delta = 2;
1442 for (int i = 0; i < (keys - 1); i++) {
1443 int this_key = bcs.getIntUnchecked(aligned_bci + (2+2*i)*4);
1444 int next_key = bcs.getIntUnchecked(aligned_bci + (2+2*i+2)*4);
1445 if (this_key >= next_key) {
1446 verifyError("Bad lookupswitch instruction");
1447 }
1448 }
1449 }
1450 int target = bci + default_offset;
1451 stackmap_table.check_jump_target(current_frame, target);
1452 for (int i = 0; i < keys; i++) {
1453 aligned_bci = VerificationBytecodes.align(bcs.bci() + 1);
1454 target = bci + bcs.getIntUnchecked(aligned_bci + (3+i*delta)*4);
1455 stackmap_table.check_jump_target(current_frame, target);
1456 }
1457 }
1458
1459 void verify_field_instructions(RawBytecodeHelper bcs, VerificationFrame current_frame, ConstantPoolWrapper cp, boolean allow_arrays) {
1460 int index = bcs.getIndexU2();
1461 verify_cp_type(bcs.bci(), index, cp, 1 << JVM_CONSTANT_Fieldref);
1462 String field_name = cp.refNameAt(index);
1463 String field_sig = cp.refSignatureAt(index);
1464 if (!VerificationSignature.isValidTypeSignature(field_sig)) verifyError("Invalid field signature");
1465 VerificationType ref_class_type = cp_ref_index_to_type(index, cp);
1466 if (!ref_class_type.is_object() &&
1467 (!allow_arrays || !ref_class_type.is_array())) {
1468 verifyError(String.format("Expecting reference to class in class %s at constant pool index %d", _klass.thisClassName(), index));
1469 }
1470 VerificationType target_class_type = ref_class_type;
1471 VerificationType[] field_type = new VerificationType[2];
1472 var sig_stream = new VerificationSignature(field_sig, false, this);
1473 VerificationType stack_object_type = null;
1474 int n = change_sig_to_verificationType(sig_stream, field_type, 0);
1475 boolean is_assignable;
1476 switch (bcs.opcode()) {
1477 case GETSTATIC -> {
1478 for (int i = 0; i < n; i++) {
1479 current_frame.push_stack(field_type[i]);
1480 }
1481 }
1482 case PUTSTATIC -> {
1483 for (int i = n - 1; i >= 0; i--) {
1484 current_frame.pop_stack(field_type[i]);
1485 }
1486 }
1487 case GETFIELD -> {
1488 stack_object_type = current_frame.pop_stack(
1489 target_class_type);
1490 // 8270398 Not applicable here
1491 for (int i = 0; i < n; i++) {
1492 current_frame.push_stack(field_type[i]);
1493 }
1494 }
1495 case PUTFIELD -> {
1496 for (int i = n - 1; i >= 0; i--) {
1497 current_frame.pop_stack(field_type[i]);
1498 }
1499 stack_object_type = current_frame.pop_stack();
1500 if (stack_object_type.is_uninitialized_this(this) &&
1501 target_class_type.equals(current_type()) &&
1502 _klass.findField(field_name, field_sig)) {
1503 stack_object_type = current_type();
1504 }
1505 is_assignable = target_class_type.is_assignable_from(stack_object_type, this);
1506 if (!is_assignable) {
1507 verifyError("Bad type on operand stack in putfield");
1508 }
1509 }
1510 default -> verifyError("Should not reach here");
1511 }
1512 }
1513
1514 boolean verify_invoke_init(RawBytecodeHelper bcs, int ref_class_index, VerificationType ref_class_type,
1515 VerificationFrame current_frame, int code_length, boolean in_try_block,
1516 boolean this_uninit, ConstantPoolWrapper cp, VerificationTable stackmap_table) {
1517 int bci = bcs.bci();
1518 VerificationType type = current_frame.pop_stack(VerificationType.reference_check);
1519 if (type.is_uninitialized_this(this)) {
1520 String superk_name = current_class().superclassName();
1521 if (!current_class().thisClassName().equals(ref_class_type.name()) &&
1522 !superk_name.equals(ref_class_type.name())) {
1523 verifyError("Bad <init> method call");
1524 }
1525 if (in_try_block) {
1526 verify_exception_handler_targets(bci, true, current_frame, stackmap_table);
1527 }
1528 current_frame.initialize_object(type, current_type());
1529 this_uninit = true;
1530 } else if (type.is_uninitialized()) {
1531 int new_offset = type.bci(this);
1532 if (new_offset > (code_length - 3) || (_method.codeArray()[new_offset] & 0xff) != NEW) {
1533 verifyError("Expecting new instruction");
1534 }
1535 int new_class_index = bcs.getU2(new_offset + 1);
1536 verify_cp_class_type(bci, new_class_index, cp);
1537 VerificationType new_class_type = cp_index_to_type(
1538 new_class_index, cp);
1539 if (!new_class_type.equals(ref_class_type)) {
1540 verifyError("Call to wrong <init> method");
1541 }
1542 if (in_try_block) {
1543 verify_exception_handler_targets(bci, this_uninit, current_frame,
1544 stackmap_table);
1545 }
1546 current_frame.initialize_object(type, new_class_type);
1547 } else {
1548 verifyError("Bad operand type when invoking <init>");
1549 }
1550 return this_uninit;
1551 }
1552
1553 static boolean is_same_or_direct_interface(VerificationWrapper klass, VerificationType klass_type, VerificationType ref_class_type) {
1554 if (ref_class_type.equals(klass_type)) return true;
1555 for (String k_name : klass.interfaceNames()) {
1556 if (ref_class_type.equals(VerificationType.reference_type(k_name))) {
1557 return true;
1558 }
1559 }
1560 return false;
1561 }
1562
1563 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) {
1564 // Make sure the constant pool item is the right type
1565 int index = bcs.getIndexU2();
1566 int opcode = bcs.opcode();
1567 int types = 0;
1568 switch (opcode) {
1569 case INVOKEINTERFACE:
1570 types = 1 << JVM_CONSTANT_InterfaceMethodref;
1571 break;
1572 case INVOKEDYNAMIC:
1573 types = 1 << JVM_CONSTANT_InvokeDynamic;
1574 break;
1575 case INVOKESPECIAL:
1576 case INVOKESTATIC:
1577 types = (_klass.majorVersion() < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION) ?
1578 (1 << JVM_CONSTANT_Methodref) :
1579 ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref));
1580 break;
1581 default:
1582 types = 1 << JVM_CONSTANT_Methodref;
1583 }
1584 verify_cp_type(bcs.bci(), index, cp, types);
1585 String method_name = cp.refNameAt(index);
1586 String method_sig = cp.refSignatureAt(index);
1587 if (!VerificationSignature.isValidMethodSignature(method_sig)) verifyError("Invalid method signature");
1588 VerificationType ref_class_type = null;
1589 if (opcode == INVOKEDYNAMIC) {
1590 if (_klass.majorVersion() < INVOKEDYNAMIC_MAJOR_VERSION) {
1591 classError(String.format("invokedynamic instructions not supported by this class file version (%d), class %s", _klass.majorVersion(), _klass.thisClassName()));
1592 }
1593 } else {
1594 ref_class_type = cp_ref_index_to_type(index, cp);
1595 }
1596 String sig = cp.refSignatureAt(index);
1597 sig_as_verification_types mth_sig_verif_types;
1598 ArrayList<VerificationType> verif_types = new ArrayList<>(10);
1599 mth_sig_verif_types = new sig_as_verification_types(verif_types);
1600 create_method_sig_entry(mth_sig_verif_types, sig);
1601 int nargs = mth_sig_verif_types.num_args();
1602 int bci = bcs.bci();
1603 if (opcode == INVOKEINTERFACE) {
1604 if ((_method.codeArray()[bci+3] & 0xff) != (nargs+1)) {
1605 verifyError("Inconsistent args count operand in invokeinterface");
1606 }
1607 if ((_method.codeArray()[bci+4] & 0xff) != 0) {
1608 verifyError("Fourth operand byte of invokeinterface must be zero");
1609 }
1610 }
1611 if (opcode == INVOKEDYNAMIC) {
1612 if ((_method.codeArray()[bci+3] & 0xff) != 0 || (_method.codeArray()[bci+4] & 0xff) != 0) {
1613 verifyError("Third and fourth operand bytes of invokedynamic must be zero");
1614 }
1615 }
1616 if (method_name.charAt(0) == JVM_SIGNATURE_SPECIAL) {
1617 if (opcode != INVOKESPECIAL ||
1618 !object_initializer_name.equals(method_name)) {
1619 verifyError("Illegal call to internal method");
1620 }
1621 } else if (opcode == INVOKESPECIAL
1622 && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type)
1623 && !ref_class_type.equals(VerificationType.reference_type(
1624 current_class().superclassName()))) {
1625
1626 // We know it is not current class, direct superinterface or immediate superclass. That means it
1627 // could be:
1628 // - a totally unrelated class or interface
1629 // - an indirect superinterface
1630 // - an indirect superclass (including Object)
1631 // We use the assignability test to see if it is a superclass, or else an interface, and keep track
1632 // of the latter. Note that subtype can be true if we are dealing with an interface that is not actually
1633 // implemented as assignability treats all interfaces as Object.
1634
1635 boolean[] is_interface = {false}; // This can only be set true if the assignability check will return true
1636 // and we loaded the class. For any other "true" returns (e.g. same class
1637 // or Object) we either can't get here (same class already excluded above)
1638 // or we know it is not an interface (i.e. Object).
1639 boolean subtype = ref_class_type.is_reference_assignable_from(current_type(), this, is_interface);
1640 if (!subtype) { // Totally unrelated class
1641 verifyError("Bad invokespecial instruction: current class isn't assignable to reference class.");
1642 } else {
1643 // Indirect superclass (including Object), indirect interface, or unrelated interface.
1644 // Any interface use is an error.
1645 if (is_interface[0]) {
1646 verifyError("Bad invokespecial instruction: interface method to invoke is not in a direct superinterface.");
1647 }
1648 }
1649
1650 }
1651 ArrayList<VerificationType> sig_verif_types = mth_sig_verif_types.sig_verif_types();
1652 if (sig_verif_types == null) verifyError("Missing signature's array of verification types");
1653 for (int i = nargs - 1; i >= 0; i--) { // Run backwards
1654 current_frame.pop_stack(sig_verif_types.get(i));
1655 }
1656 if (opcode != INVOKESTATIC &&
1657 opcode != INVOKEDYNAMIC) {
1658 if (object_initializer_name.equals(method_name)) { // <init> method
1659 this_uninit = verify_invoke_init(bcs, index, ref_class_type, current_frame,
1660 code_length, in_try_block, this_uninit, cp, stackmap_table);
1661 } else {
1662 switch (opcode) {
1663 case INVOKESPECIAL ->
1664 current_frame.pop_stack(current_type());
1665 case INVOKEVIRTUAL -> {
1666 VerificationType stack_object_type =
1667 current_frame.pop_stack(ref_class_type);
1668 if (current_type() != stack_object_type) {
1669 cp.classNameAt(cp.refClassIndexAt(index));
1670 }
1671 }
1672 default -> {
1673 if (opcode != INVOKEINTERFACE)
1674 verifyError("Unexpected opcode encountered");
1675 current_frame.pop_stack(ref_class_type);
1676 }
1677 }
1678 }
1679 }
1680 int sig_verif_types_len = sig_verif_types.size();
1681 if (sig_verif_types_len > nargs) { // There's a return type
1682 if (object_initializer_name.equals(method_name)) {
1683 verifyError("Return type must be void in <init> method");
1684 }
1685
1686 if (sig_verif_types_len > nargs + 2) verifyError("Signature verification types array return type is bogus");
1687 for (int i = nargs; i < sig_verif_types_len; i++) {
1688 if (!(i == nargs || sig_verif_types.get(i).is_long2() || sig_verif_types.get(i).is_double2())) verifyError("Unexpected return verificationType");
1689 current_frame.push_stack(sig_verif_types.get(i));
1690 }
1691 }
1692 return this_uninit;
1693 }
1694
1695 VerificationType get_newarray_type(int index, int bci) {
1696 String[] from_bt = new String[] {
1697 null, null, null, null, "[Z", "[C", "[F", "[D", "[B", "[S", "[I", "[J",
1698 };
1699 if (index < T_BOOLEAN.type || index > T_LONG.type) {
1700 verifyError("Illegal newarray instruction");
1701 }
1702 String sig = from_bt[index];
1703 return VerificationType.reference_type(sig);
1704 }
1705
1706 void verify_anewarray(int bci, int index, ConstantPoolWrapper cp, VerificationFrame current_frame) {
1707 verify_cp_class_type(bci, index, cp);
1708 current_frame.pop_stack(VerificationType.integer_type);
1709 VerificationType component_type = cp_index_to_type(index, cp);
1710 int length;
1711 String arr_sig_str;
1712 if (component_type.is_array()) { // it's an array
1713 String component_name = component_type.name();
1714 length = component_name.length();
1715 if (length > MAX_ARRAY_DIMENSIONS &&
1716 component_name.charAt(MAX_ARRAY_DIMENSIONS - 1) == JVM_SIGNATURE_ARRAY) {
1717 verifyError("Illegal anewarray instruction, array has more than 255 dimensions");
1718 }
1719 length++;
1720 arr_sig_str = String.format("%c%s", JVM_SIGNATURE_ARRAY, component_name);
1721 if (arr_sig_str.length() != length) verifyError("Unexpected number of characters in string");
1722 } else { // it's an object or interface
1723 String component_name = component_type.name();
1724 length = component_name.length() + 3;
1725 arr_sig_str = String.format("%c%c%s;", JVM_SIGNATURE_ARRAY, JVM_SIGNATURE_CLASS, component_name);
1726 if (arr_sig_str.length() != length) verifyError("Unexpected number of characters in string");
1727 }
1728 VerificationType new_array_type = VerificationType.reference_type(arr_sig_str);
1729 current_frame.push_stack(new_array_type);
1730 }
1731
1732 void verify_iload(int index, VerificationFrame current_frame) {
1733 current_frame.get_local(
1734 index, VerificationType.integer_type);
1735 current_frame.push_stack(
1736 VerificationType.integer_type);
1737 }
1738
1739 void verify_lload(int index, VerificationFrame current_frame) {
1740 current_frame.get_local_2(
1741 index, VerificationType.long_type,
1742 VerificationType.long2_type);
1743 current_frame.push_stack_2(
1744 VerificationType.long_type,
1745 VerificationType.long2_type);
1746 }
1747
1748 void verify_fload(int index, VerificationFrame current_frame) {
1749 current_frame.get_local(
1750 index, VerificationType.float_type);
1751 current_frame.push_stack(
1752 VerificationType.float_type);
1753 }
1754
1755 void verify_dload(int index, VerificationFrame current_frame) {
1756 current_frame.get_local_2(
1757 index, VerificationType.double_type,
1758 VerificationType.double2_type);
1759 current_frame.push_stack_2(
1760 VerificationType.double_type,
1761 VerificationType.double2_type);
1762 }
1763
1764 void verify_aload(int index, VerificationFrame current_frame) {
1765 VerificationType type = current_frame.get_local(
1766 index, VerificationType.reference_check);
1767 current_frame.push_stack(type);
1768 }
1769
1770 void verify_istore(int index, VerificationFrame current_frame) {
1771 current_frame.pop_stack(
1772 VerificationType.integer_type);
1773 current_frame.set_local(
1774 index, VerificationType.integer_type);
1775 }
1776
1777 void verify_lstore(int index, VerificationFrame current_frame) {
1778 current_frame.pop_stack_2(
1779 VerificationType.long2_type,
1780 VerificationType.long_type);
1781 current_frame.set_local_2(
1782 index, VerificationType.long_type,
1783 VerificationType.long2_type);
1784 }
1785
1786 void verify_fstore(int index, VerificationFrame current_frame) {
1787 current_frame.pop_stack(
1788 VerificationType.float_type);
1789 current_frame.set_local(
1790 index, VerificationType.float_type);
1791 }
1792
1793 void verify_dstore(int index, VerificationFrame current_frame) {
1794 current_frame.pop_stack_2(
1795 VerificationType.double2_type,
1796 VerificationType.double_type);
1797 current_frame.set_local_2(
1798 index, VerificationType.double_type,
1799 VerificationType.double2_type);
1800 }
1801
1802 void verify_astore(int index, VerificationFrame current_frame) {
1803 VerificationType type = current_frame.pop_stack(
1804 VerificationType.reference_check);
1805 current_frame.set_local(index, type);
1806 }
1807
1808 void verify_iinc(int index, VerificationFrame current_frame) {
1809 VerificationType type = current_frame.get_local(
1810 index, VerificationType.integer_type);
1811 current_frame.set_local(index, type);
1812 }
1813
1814 void verify_return_value(VerificationType return_type, VerificationType type, int bci, VerificationFrame current_frame) {
1815 if (return_type.is_bogus()) {
1816 verifyError("Method does not expect a return value");
1817 }
1818 boolean match = return_type.is_assignable_from(type, this);
1819 if (!match) {
1820 verifyError("Bad return type");
1821 }
1822 }
1823
1824 private void dumpMethod() {
1825 if (_logger != null) ClassPrinter.toTree(_method.m, ClassPrinter.Verbosity.CRITICAL_ATTRIBUTES).toYaml(_logger);
1826 }
1827
1828 void verifyError(String msg) {
1829 dumpMethod();
1830 throw new VerifyError(String.format("%s in %s::%s(%s) @%d %s", msg, _klass.thisClassName(), _method.name(), _method.parameters(), bci, errorContext).trim());
1831 }
1832
1833 void verifyError(String msg, VerificationFrame from, VerificationFrame target) {
1834 dumpMethod();
1835 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));
1836 }
1837
1838 void classError(String msg) {
1839 dumpMethod();
1840 throw new VerifyError(String.format("%s in %s::%s(%s)", msg, _klass.thisClassName(), _method.name(), _method.parameters()));
1841 }
1842 }