1 /* Handle verification of bytecoded methods for the GNU compiler for
3 Copyright (C) 1997 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
29 #include "java-tree.h"
31 #include "java-opcodes.h"
33 #include "java-except.h"
36 extern int stack_pointer;
38 /* During verification, start of the current subroutine (jsr target). */
41 /* A list of pending blocks, chained using LABEL_PENDING_CHAIN.
42 A pending block is one that has LABEL_CHANGED set, which means
43 it requires (re-) verification. */
46 /* Append TARGET_LABEL to the pending_block stack unless already in it. */
49 push_pending_label (target_label)
52 if (! LABEL_CHANGED (target_label))
54 LABEL_PENDING_CHAIN (target_label) = pending_blocks;
55 pending_blocks = target_label;
56 LABEL_CHANGED (target_label) = 1;
60 /* Note that TARGET_LABEL is a possible successor instruction.
61 Merge the type state etc.
62 Return NULL on sucess, or an error message on failure. */
65 check_pending_block (target_label)
68 int changed = merge_type_state (target_label);
73 return "types could not be merged";
74 push_pending_label (target_label);
77 if (current_subr == NULL)
79 if (LABEL_IN_SUBR (target_label))
80 return "might transfer control into subroutine";
84 if (LABEL_IN_SUBR (target_label))
86 if (LABEL_SUBR_START (target_label) != current_subr)
87 return "transfer out of subroutine";
89 else if (! LABEL_VERIFIED (target_label))
91 LABEL_IN_SUBR (target_label) = 1;
92 LABEL_SUBR_START (target_label) = current_subr;
95 return "transfer out of subroutine";
100 /* Return the "merged" types of TYPE1 and TYPE2.
101 If either is primitive, the other must match (after promotion to int).
102 For reference types, return the common super-class.
103 Return TYPE_UNKNOWN if the types cannot be merged. */
106 merge_types (type1, type2)
111 if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
112 || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
114 if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
118 /* ptr_type_node is only used for a null reference,
119 which is compatible with any reference type. */
120 if (type1 == ptr_type_node || type2 == object_ptr_type_node)
122 if (type2 == ptr_type_node || type1 == object_ptr_type_node)
125 tt1 = HANDLE_TO_CLASS_TYPE (TREE_TYPE (type1));
126 tt2 = HANDLE_TO_CLASS_TYPE (TREE_TYPE (type2));
128 if (TYPE_ARRAY_P (tt1) || TYPE_ARRAY_P (tt2))
130 if (TYPE_ARRAY_P (tt1) == TYPE_ARRAY_P (tt2))
132 tree el_type1 = TYPE_ARRAY_ELEMENT (tt1);
133 tree el_type2 = TYPE_ARRAY_ELEMENT (tt2);
134 tree el_type = NULL_TREE;
135 if (el_type1 == el_type2)
137 else if (TREE_CODE (el_type1) == POINTER_TYPE
138 && TREE_CODE (el_type2) == POINTER_TYPE)
139 el_type = merge_types (el_type1, el_type2);
140 if (el_type != NULL_TREE)
142 HOST_WIDE_INT len1 = java_array_type_length (tt1);
143 HOST_WIDE_INT len2 = java_array_type_length (tt2);
146 else if (el_type1 == el_type2)
148 return promote_type (build_java_array_type (el_type, len1));
151 return object_ptr_type_node;
156 depth1 = class_depth (type1);
157 depth2 = class_depth (type2);
158 for ( ; depth1 > depth2; depth1--)
159 type1 = TYPE_BINFO_BASETYPE (type1, 0);
160 for ( ; depth2 > depth1; depth2--)
161 type2 = TYPE_BINFO_BASETYPE (type2, 0);
162 while (type1 != type2)
164 type1 = TYPE_BINFO_BASETYPE (type1, 0);
165 type2 = TYPE_BINFO_BASETYPE (type2, 0);
167 return promote_type (type1);
169 if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)
170 && TYPE_PRECISION (type1) <= 32 && TYPE_PRECISION (type2) <= 32)
171 return int_type_node;
175 /* Merge the current type state with that at LABEL.
176 Return -1 the the states are incompatible (i.e. on error),
177 0 if there was no change, and 1 if there was a change. */
180 merge_type_state (label)
183 int nlocals = DECL_MAX_LOCALS(current_function_decl);
184 int cur_length = stack_pointer + nlocals;
185 tree vec = LABEL_TYPE_STATE (label);
187 if (vec == NULL_TREE)
189 vec = make_tree_vec (cur_length);
190 LABEL_TYPE_STATE (label) = vec;
191 while (--cur_length >= 0)
192 TREE_VEC_ELT (vec, cur_length) = type_map [cur_length];
199 if (LABEL_IS_SUBR_START (label) && LABEL_VERIFIED (label)
200 && current_subr != label)
201 return_map = LABEL_RETURN_TYPE_STATE (label);
203 return_map = NULL_TREE;
204 if (TREE_VEC_LENGTH (vec) != cur_length)
208 for (i = 0; i < cur_length; i++)
210 tree old_type = TREE_VEC_ELT (vec, i);
211 tree new_type = merge_types (old_type, type_map [i]);
212 if (TREE_VEC_ELT (vec, i) != new_type)
214 /* If there has been a change, note that since we must re-verify.
215 However, if the label is the start of a subroutine,
216 we don't care about local variables that are neither
217 set nor used in the sub-routine. */
218 if (return_map == NULL_TREE || i >= nlocals
219 || TREE_VEC_ELT (return_map, i) != TYPE_UNUSED
220 || (TYPE_IS_WIDE (new_type)
221 && TREE_VEC_ELT (return_map, i+1) != TYPE_UNUSED))
224 TREE_VEC_ELT (vec, i) = new_type;
225 if (new_type == TYPE_UNKNOWN)
230 else if (TYPE_IS_WIDE (new_type))
237 /* Handle dup-like operations. */
240 type_stack_dup (size, offset)
245 if (size + offset > stack_pointer)
246 error ("stack underflow - dup* operation");
247 for (index = 0; index < size + offset; index++)
249 type[index] = stack_type_map[stack_pointer - 1];
250 if (type[index] == void_type_node)
253 type[index] = stack_type_map[stack_pointer - 2];
254 if (! TYPE_IS_WIDE (type[index]))
255 fatal ("internal error - dup operation");
256 if (index == size || index == size + offset)
257 fatal ("dup operation splits 64-bit number");
259 pop_type (type[index]);
261 for (index = size; --index >= 0; )
263 if (type[index] != void_type_node)
264 push_type (type[index]);
267 for (index = size + offset; --index >= 0; )
269 if (type[index] != void_type_node)
270 push_type (type[index]);
274 /* This causes the next iteration to ignore the next instruction
275 and look for some other unhandled instruction. */
276 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
277 #define INVALID_PC (-1)
279 #define VERIFICATION_ERROR(MESSAGE) \
280 do { message = MESSAGE; goto verify_error; } while (0)
282 #define PUSH_PENDING(LABEL) \
283 do { if ((message = check_pending_block (LABEL)) != NULL) \
284 goto verify_error; } while (0)
287 #define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; 1;})
289 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? \
290 (fatal("Bad byte codes.\n"), 0) : 1)
293 #define BCODE byte_ops
295 /* Verify the bytecodes of the current method.
296 Return 1 on sucess, 0 on failure. */
298 verify_jvm_instructions (jcf, byte_ops, length)
300 unsigned char* byte_ops;
307 int oldpc; /* PC of start of instruction. */
308 int prevpc; /* If >= 0, PC of previous instruction. */
311 register unsigned char *p;
312 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
313 struct eh_range *eh_ranges;
317 pending_blocks = NULL_TREE;
319 /* Handle the exception table. */
320 method_init_exceptions ();
321 JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
322 i = JCF_readu2 (jcf);
324 /* We read the exception backwards. */
325 p = jcf->read_ptr + 8 * i;
328 int start_pc = GET_u2 (p-8);
329 int end_pc = GET_u2 (p-6);
330 int handler_pc = GET_u2 (p-4);
331 int catch_type = GET_u2 (p-2);
334 if (start_pc < 0 || start_pc >= length
335 || end_pc < 0 || end_pc > length || start_pc >= end_pc
336 || handler_pc < 0 || handler_pc >= length
337 || (handler_pc >= start_pc && handler_pc < end_pc)
338 || ! (instruction_bits [start_pc] & BCODE_INSTRUCTION_START)
339 || ! (instruction_bits [end_pc] & BCODE_INSTRUCTION_START)
340 || ! (instruction_bits [handler_pc] & BCODE_INSTRUCTION_START))
342 error ("bad pc in exception_table");
346 if (! add_handler (start_pc, end_pc,
347 lookup_label (handler_pc),
348 catch_type == 0 ? NULL_TREE
349 : get_class_constant (jcf, catch_type)))
351 error ("overlapping exception ranges are not supported");
355 instruction_bits [handler_pc] |= BCODE_EXCEPTION_TARGET;
362 if (((PC != INVALID_PC
363 && instruction_bits [PC] & BCODE_TARGET) != 0)
366 PUSH_PENDING (lookup_label (PC));
369 if (PC == INVALID_PC)
371 label = pending_blocks;
372 if (label == NULL_TREE)
373 break; /* We're done! */
374 pending_blocks = LABEL_PENDING_CHAIN (label);
375 LABEL_CHANGED (label) = 0;
377 if (LABEL_IN_SUBR (label))
378 current_subr = LABEL_SUBR_START (label);
380 current_subr = NULL_TREE;
382 /* Restore type_map and stack_pointer from
383 LABEL_TYPE_STATE (label), and continue
384 compiling from there. */
385 load_type_state (label);
386 PC = LABEL_PC (label);
388 else if (PC >= length)
389 VERIFICATION_ERROR ("falling through end of method");
393 if (!(instruction_bits [PC] & BCODE_INSTRUCTION_START) && ! wide)
394 VERIFICATION_ERROR ("PC not at instruction start");
396 instruction_bits[PC] |= BCODE_VERIFIED;
398 eh_ranges = find_handler (oldpc);
400 op_code = byte_ops[PC++];
403 int is_static, is_putting;
406 case OPCODE_iconst_m1:
407 case OPCODE_iconst_0: case OPCODE_iconst_1: case OPCODE_iconst_2:
408 case OPCODE_iconst_3: case OPCODE_iconst_4: case OPCODE_iconst_5:
409 i = op_code - OPCODE_iconst_0;
412 if (byte_ops[PC] == OPCODE_newarray
413 || byte_ops[PC] == OPCODE_newarray)
415 push_type (int_type_node); break;
416 case OPCODE_lconst_0: case OPCODE_lconst_1:
417 push_type (long_type_node); break;
418 case OPCODE_fconst_0: case OPCODE_fconst_1: case OPCODE_fconst_2:
419 push_type (float_type_node); break;
420 case OPCODE_dconst_0: case OPCODE_dconst_1:
421 push_type (double_type_node); break;
428 case OPCODE_iload: type = int_type_node; goto general_load;
429 case OPCODE_lload: type = long_type_node; goto general_load;
430 case OPCODE_fload: type = float_type_node; goto general_load;
431 case OPCODE_dload: type = double_type_node; goto general_load;
432 case OPCODE_aload: type = ptr_type_node; goto general_load;
434 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
437 case OPCODE_iload_0: type = int_type_node; index = 0; goto load;
438 case OPCODE_iload_1: type = int_type_node; index = 1; goto load;
439 case OPCODE_iload_2: type = int_type_node; index = 2; goto load;
440 case OPCODE_iload_3: type = int_type_node; index = 3; goto load;
441 case OPCODE_lload_0: type = long_type_node; index = 0; goto load;
442 case OPCODE_lload_1: type = long_type_node; index = 1; goto load;
443 case OPCODE_lload_2: type = long_type_node; index = 2; goto load;
444 case OPCODE_lload_3: type = long_type_node; index = 3; goto load;
445 case OPCODE_fload_0: type = float_type_node; index = 0; goto load;
446 case OPCODE_fload_1: type = float_type_node; index = 1; goto load;
447 case OPCODE_fload_2: type = float_type_node; index = 2; goto load;
448 case OPCODE_fload_3: type = float_type_node; index = 3; goto load;
449 case OPCODE_dload_0: type = double_type_node; index = 0; goto load;
450 case OPCODE_dload_1: type = double_type_node; index = 1; goto load;
451 case OPCODE_dload_2: type = double_type_node; index = 2; goto load;
452 case OPCODE_dload_3: type = double_type_node; index = 3; goto load;
453 case OPCODE_aload_0: type = ptr_type_node; index = 0; goto load;
454 case OPCODE_aload_1: type = ptr_type_node; index = 1; goto load;
455 case OPCODE_aload_2: type = ptr_type_node; index = 2; goto load;
456 case OPCODE_aload_3: type = ptr_type_node; index = 3; goto load;
459 || (index + TYPE_IS_WIDE (type)
460 >= DECL_MAX_LOCALS (current_function_decl)))
461 VERIFICATION_ERROR ("invalid local variable index in load");
462 tmp = type_map[index];
463 if (tmp == TYPE_UNKNOWN || tmp == TYPE_SECOND
464 || (TYPE_IS_WIDE (type)
465 && type_map[index+1] != void_type_node)
466 || (type == ptr_type_node
467 ? TREE_CODE (tmp) != POINTER_TYPE
468 : type == int_type_node
469 ? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
471 VERIFICATION_ERROR("invalid local variable type in load");
474 case OPCODE_istore: type = int_type_node; goto general_store;
475 case OPCODE_lstore: type = long_type_node; goto general_store;
476 case OPCODE_fstore: type = float_type_node; goto general_store;
477 case OPCODE_dstore: type = double_type_node; goto general_store;
478 case OPCODE_astore: type = ptr_type_node; goto general_store;
480 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
483 case OPCODE_istore_0: type = int_type_node; index = 0; goto store;
484 case OPCODE_istore_1: type = int_type_node; index = 1; goto store;
485 case OPCODE_istore_2: type = int_type_node; index = 2; goto store;
486 case OPCODE_istore_3: type = int_type_node; index = 3; goto store;
487 case OPCODE_lstore_0: type = long_type_node; index=0; goto store;
488 case OPCODE_lstore_1: type = long_type_node; index=1; goto store;
489 case OPCODE_lstore_2: type = long_type_node; index=2; goto store;
490 case OPCODE_lstore_3: type = long_type_node; index=3; goto store;
491 case OPCODE_fstore_0: type=float_type_node; index=0; goto store;
492 case OPCODE_fstore_1: type=float_type_node; index=1; goto store;
493 case OPCODE_fstore_2: type=float_type_node; index=2; goto store;
494 case OPCODE_fstore_3: type=float_type_node; index=3; goto store;
495 case OPCODE_dstore_0: type=double_type_node; index=0; goto store;
496 case OPCODE_dstore_1: type=double_type_node; index=1; goto store;
497 case OPCODE_dstore_2: type=double_type_node; index=2; goto store;
498 case OPCODE_dstore_3: type=double_type_node; index=3; goto store;
499 case OPCODE_astore_0: type = ptr_type_node; index = 0; goto store;
500 case OPCODE_astore_1: type = ptr_type_node; index = 1; goto store;
501 case OPCODE_astore_2: type = ptr_type_node; index = 2; goto store;
502 case OPCODE_astore_3: type = ptr_type_node; index = 3; goto store;
505 || (index + TYPE_IS_WIDE (type)
506 >= DECL_MAX_LOCALS (current_function_decl)))
508 VERIFICATION_ERROR ("invalid local variable index in store");
511 type = pop_type (type);
512 type_map[index] = type;
514 /* If local variable changed, we need to reconsider eh handlers. */
515 prev_eh_ranges = NULL_EH_RANGE;
517 /* Allocate decl and rtx for this variable now, so if we're not
518 optmizing, we get a temporary that survives the whole method. */
519 find_local_variable (index, type, oldpc);
521 if (TYPE_IS_WIDE (type))
522 type_map[index+1] = TYPE_SECOND;
523 /* ... fall through to note_used ... */
525 /* For store or load, note that local variable INDEX is used.
526 This is needed to verify try-finally sub-routines. */
529 tree vec = LABEL_RETURN_TYPE_STATE (current_subr);
530 tree subr_vec = LABEL_TYPE_STATE (current_subr);
531 int len = 1 + TYPE_IS_WIDE (type);
534 if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)
535 TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);
550 type = int_type_node; goto binop;
555 type = int_type_node; goto unop;
564 type = long_type_node; goto binop;
566 type = long_type_node; goto unop;
567 case OPCODE_fadd: case OPCODE_fsub:
568 case OPCODE_fmul: case OPCODE_fdiv: case OPCODE_frem:
569 type = float_type_node; goto binop;
571 type = float_type_node; goto unop;
572 case OPCODE_dadd: case OPCODE_dsub:
573 case OPCODE_dmul: case OPCODE_ddiv: case OPCODE_drem:
574 type = double_type_node; goto binop;
576 type = double_type_node; goto unop;
589 pop_type (int_type_node);
590 pop_type (long_type_node);
591 push_type (long_type_node);
594 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
597 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))
598 VERIFICATION_ERROR ("invalid local variable index in iinc");
599 tmp = type_map[index];
600 if (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
601 VERIFICATION_ERROR ("invalid local variable type in iinc");
604 pop_type (int_type_node); push_type (long_type_node); break;
606 pop_type (int_type_node); push_type (float_type_node); break;
608 pop_type (int_type_node); push_type (double_type_node); break;
610 pop_type (long_type_node); push_type (int_type_node); break;
612 pop_type (long_type_node); push_type (float_type_node); break;
614 pop_type (long_type_node); push_type (double_type_node); break;
616 pop_type (float_type_node); push_type (int_type_node); break;
618 pop_type (float_type_node); push_type (long_type_node); break;
620 pop_type (float_type_node); push_type (double_type_node); break;
622 pop_type (double_type_node); push_type (int_type_node); break;
624 pop_type (double_type_node); push_type (long_type_node); break;
626 pop_type (double_type_node); push_type (float_type_node); break;
628 type = long_type_node; goto compare;
631 type = float_type_node; goto compare;
634 type = double_type_node; goto compare;
636 pop_type (type); pop_type (type);
637 push_type (int_type_node); break;
644 pop_type (int_type_node); goto cond;
646 case OPCODE_ifnonnull:
647 pop_type (ptr_type_node ); goto cond;
648 case OPCODE_if_icmpeq:
649 case OPCODE_if_icmpne:
650 case OPCODE_if_icmplt:
651 case OPCODE_if_icmpge:
652 case OPCODE_if_icmpgt:
653 case OPCODE_if_icmple:
654 pop_type (int_type_node); pop_type (int_type_node); goto cond;
655 case OPCODE_if_acmpeq:
656 case OPCODE_if_acmpne:
657 pop_type (object_ptr_type_node); pop_type (object_ptr_type_node);
660 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
663 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
667 switch (byte_ops[PC])
669 case OPCODE_iload: case OPCODE_lload:
670 case OPCODE_fload: case OPCODE_dload: case OPCODE_aload:
671 case OPCODE_istore: case OPCODE_lstore:
672 case OPCODE_fstore: case OPCODE_dstore: case OPCODE_astore:
678 VERIFICATION_ERROR ("invalid use of wide instruction");
681 case OPCODE_ireturn: type = int_type_node; goto ret;
682 case OPCODE_lreturn: type = long_type_node; goto ret;
683 case OPCODE_freturn: type = float_type_node; goto ret;
684 case OPCODE_dreturn: type = double_type_node; goto ret;
685 case OPCODE_areturn: type = ptr_type_node; goto ret;
688 /* ... fall through ... */
692 case OPCODE_getstatic: is_putting = 0; is_static = 1; goto field;
693 case OPCODE_putstatic: is_putting = 1; is_static = 1; goto field;
694 case OPCODE_getfield: is_putting = 0; is_static = 0; goto field;
695 case OPCODE_putfield: is_putting = 1; is_static = 0; goto field;
698 int index = IMMEDIATE_u2;
699 tree self_type = get_class_constant
700 (jcf, COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool, index));
701 tree field_name = COMPONENT_REF_NAME (¤t_jcf->cpool, index);
702 tree field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, index);
703 tree field_type = get_type_from_signature (field_signature);
705 pop_type (field_type);
708 /* Defer actual checking until next pass. */
709 pop_type (ptr_type_node);
712 push_type (field_type);
716 push_type (get_class_constant (jcf, IMMEDIATE_u2));
718 case OPCODE_dup: type_stack_dup (1, 0); break;
719 case OPCODE_dup_x1: type_stack_dup (1, 1); break;
720 case OPCODE_dup_x2: type_stack_dup (1, 2); break;
721 case OPCODE_dup2: type_stack_dup (2, 0); break;
722 case OPCODE_dup2_x1: type_stack_dup (2, 1); break;
723 case OPCODE_dup2_x2: type_stack_dup (2, 2); break;
724 case OPCODE_pop: index = 1; goto pop;
725 case OPCODE_pop2: index = 2; goto pop;
727 if (stack_pointer < index)
728 VERIFICATION_ERROR ("stack underflow");
729 stack_pointer -= index;
732 if (stack_pointer < 2)
733 VERIFICATION_ERROR ("stack underflow (in swap)");
736 tree type1 = stack_type_map[stack_pointer - 1];
737 tree type2 = stack_type_map[stack_pointer - 2];
738 if (type1 == void_type_node || type2 == void_type_node)
739 VERIFICATION_ERROR ("verifier (swap): double or long value");
740 stack_type_map[stack_pointer - 2] = type1;
741 stack_type_map[stack_pointer - 1] = type2;
744 case OPCODE_ldc: index = IMMEDIATE_u1; goto ldc;
747 index = IMMEDIATE_u2; goto ldc;
749 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
750 VERIFICATION_ERROR ("bad constant pool index in ldc");
752 switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)
754 case CONSTANT_Integer: type = int_type_node; goto check_ldc;
755 case CONSTANT_Float: type = float_type_node; goto check_ldc;
756 case CONSTANT_String: type = string_type_node; goto check_ldc;
757 case CONSTANT_Long: type = long_type_node; goto check_ldc;
758 case CONSTANT_Double: type = double_type_node; goto check_ldc;
760 if (TYPE_IS_WIDE (type) == (op_code == OPCODE_ldc2_w))
762 /* ... else fall through ... */
765 VERIFICATION_ERROR ("bad constant pool tag in ldc");
767 if (type == int_type_node)
769 i = TREE_INT_CST_LOW (get_constant (current_jcf, index));
775 case OPCODE_invokevirtual:
776 case OPCODE_invokespecial:
777 case OPCODE_invokestatic:
778 case OPCODE_invokeinterface:
780 int index = IMMEDIATE_u2;
781 tree sig = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, index);
782 tree self_type = get_class_constant
783 (current_jcf, COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool,
785 tree method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, index);
787 method_type = parse_signature_string (IDENTIFIER_POINTER (sig),
788 IDENTIFIER_LENGTH (sig));
789 if (TREE_CODE (method_type) != FUNCTION_TYPE)
790 VERIFICATION_ERROR ("bad method signature");
791 pop_argument_types (TYPE_ARG_TYPES (method_type));
793 /* Can't invoke <clinit> */
794 if (method_name == clinit_identifier_node)
795 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
796 /* Apart invokespecial, can't invoke <init> */
797 if (op_code != OPCODE_invokespecial
798 && method_name == init_identifier_node)
799 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
801 if (op_code != OPCODE_invokestatic)
802 pop_type (self_type);
806 case OPCODE_invokeinterface:
808 int nargs = IMMEDIATE_u1;
809 int notZero = IMMEDIATE_u1;
811 if (!nargs || notZero)
813 ("invalid argument number in invokeinterface");
818 if (TREE_TYPE (method_type) != void_type_node)
819 push_type (TREE_TYPE (method_type));
823 case OPCODE_arraylength:
824 /* Type checking actually made during code generation */
825 pop_type( ptr_type_node );
826 push_type( int_type_node );
829 /* Q&D verification *or* more checking done during code generation
830 for byte/boolean/char/short, the value popped is a int coerced
831 into the right type before being stored. */
832 case OPCODE_iastore: type = int_type_node; goto astore;
833 case OPCODE_lastore: type = long_type_node; goto astore;
834 case OPCODE_fastore: type = float_type_node; goto astore;
835 case OPCODE_dastore: type = double_type_node; goto astore;
836 case OPCODE_aastore: type = ptr_type_node; goto astore;
837 case OPCODE_bastore: type = int_type_node; goto astore;
838 case OPCODE_castore: type = int_type_node; goto astore;
839 case OPCODE_sastore: type = int_type_node; goto astore;
841 /* FIXME - need better verification here */
842 pop_type (type); /* new value */
843 pop_type (int_type_node); /* index */
844 pop_type (ptr_type_node); /* array */
847 /* Q&D verification *or* more checking done during code generation
848 for byte/boolean/char/short, the value pushed is a int. */
849 case OPCODE_iaload: type = int_type_node; goto aload;
850 case OPCODE_laload: type = long_type_node; goto aload;
851 case OPCODE_faload: type = float_type_node; goto aload;
852 case OPCODE_daload: type = double_type_node; goto aload;
853 case OPCODE_aaload: type = ptr_type_node; goto aload;
854 case OPCODE_baload: type = promote_type (byte_type_node); goto aload;
855 case OPCODE_caload: type = promote_type (char_type_node); goto aload;
856 case OPCODE_saload: type = promote_type (short_type_node); goto aload;
858 pop_type (int_type_node);
859 type = pop_type (ptr_type_node);
860 if (! is_array_type_p (type))
861 VERIFICATION_ERROR ("array load from non-array type");
862 push_type (TYPE_ARRAY_ELEMENT (TREE_TYPE (type)));
865 case OPCODE_anewarray:
866 type = get_class_constant (current_jcf, IMMEDIATE_u2);
867 type = promote_type (type);
870 case OPCODE_newarray:
871 index = IMMEDIATE_u1;
872 type = decode_newarray_type (index);
873 if (type == NULL_TREE)
874 VERIFICATION_ERROR ("invalid type code in newarray opcode");
878 if (int_value >= 0 && prevpc >= 0)
880 /* If previous instruction pushed int constant,
881 we want to use it. */
882 switch (byte_ops[prevpc])
884 case OPCODE_iconst_0: case OPCODE_iconst_1:
885 case OPCODE_iconst_2: case OPCODE_iconst_3:
886 case OPCODE_iconst_4: case OPCODE_iconst_5:
887 case OPCODE_bipush: case OPCODE_sipush:
888 case OPCODE_ldc: case OPCODE_ldc_w:
896 type = build_java_array_type (type, int_value);
897 pop_type (int_type_node);
901 case OPCODE_multianewarray:
904 index = IMMEDIATE_u2;
908 VERIFICATION_ERROR ("number of dimension lower that 1 in multianewarray" );
910 for( i = 0; i < ndim; i++ )
911 pop_type (int_type_node);
912 push_type (get_class_constant (current_jcf, index));
916 case OPCODE_aconst_null:
917 push_type (ptr_type_node);
921 pop_type (throwable_type_node);
925 case OPCODE_checkcast:
926 pop_type (ptr_type_node);
927 type = get_class_constant (current_jcf, IMMEDIATE_u2);
930 case OPCODE_instanceof:
931 pop_type (ptr_type_node);
932 get_class_constant (current_jcf, IMMEDIATE_u2);
933 push_type (int_type_node);
936 case OPCODE_tableswitch:
938 jint default_val, low, high;
940 pop_type (int_type_node);
944 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
946 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
951 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
953 while (low++ <= high)
954 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
958 case OPCODE_lookupswitch:
960 jint npairs, last, not_registered = 1;
962 pop_type (int_type_node);
966 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
969 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
970 npairs = IMMEDIATE_s4;
973 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
977 int match = IMMEDIATE_s4;
980 else if (last >= match)
981 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
984 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
989 case OPCODE_monitorenter:
991 case OPCODE_monitorexit:
992 pop_type (ptr_type_node);
996 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1002 tree target = lookup_label (oldpc + IMMEDIATE_s2);
1003 tree return_label = lookup_label (PC);
1004 push_type (return_address_type_node);
1005 if (! LABEL_VERIFIED (target))
1007 /* first time seen */
1008 tree return_type_map;
1009 int nlocals = DECL_MAX_LOCALS (current_function_decl);
1010 index = nlocals + DECL_MAX_STACK (current_function_decl);
1011 return_type_map = make_tree_vec (index);
1012 while (--index >= nlocals)
1013 TREE_VEC_ELT (return_type_map, index) = TYPE_UNKNOWN;
1014 while (--index >= 0)
1015 TREE_VEC_ELT (return_type_map, index) = TYPE_UNUSED;
1016 LABEL_RETURN_LABEL (target)
1017 = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
1018 LABEL_PC (LABEL_RETURN_LABEL (target)) = -1;
1019 LABEL_RETURN_TYPE_STATE (target) = return_type_map;
1020 LABEL_IS_SUBR_START (target) = 1;
1021 LABEL_IN_SUBR (target) = 1;
1022 LABEL_SUBR_START (target) = target;
1023 LABEL_SUBR_CONTEXT (target) = current_subr;
1025 else if (! LABEL_IS_SUBR_START (target)
1026 || LABEL_SUBR_CONTEXT (target) != current_subr)
1027 VERIFICATION_ERROR ("label part of different subroutines");
1029 i = merge_type_state (target);
1033 VERIFICATION_ERROR ("types could not be merged at jsr");
1034 push_pending_label (target);
1036 current_subr = target;
1038 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1039 if (! value_member (return_label, LABEL_RETURN_LABELS (target)))
1041 LABEL_RETURN_LABELS (target)
1042 = tree_cons (NULL_TREE, return_label,
1043 LABEL_RETURN_LABELS (target));
1046 if (LABEL_VERIFIED (target))
1048 tree return_map = LABEL_RETURN_TYPE_STATE (target);
1049 int len = TREE_VEC_LENGTH (return_map);
1050 stack_pointer = len - DECL_MAX_LOCALS (current_function_decl);
1053 if (TREE_VEC_ELT (return_map, len) != TYPE_UNUSED)
1054 type_map[len] = TREE_VEC_ELT (return_map, len);
1056 current_subr = LABEL_SUBR_CONTEXT (target);
1057 PUSH_PENDING (return_label);
1064 if (current_subr == NULL)
1065 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1068 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
1069 tree caller = LABEL_SUBR_CONTEXT (current_subr);
1070 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
1071 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
1074 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl)
1075 || type_map[index] != TYPE_RETURN_ADDR)
1076 VERIFICATION_ERROR ("invalid ret index");
1078 /* The next chunk of code is similar to an inlined version of
1079 * merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1080 * The main differences are that LABEL_RETURN_LABEL is
1081 * pre-allocated by the jsr (but we don't know the size then);
1082 * and that we have to handle TYPE_UNUSED. */
1084 if (! RETURN_MAP_ADJUSTED (ret_map))
1085 { /* First return from this subroutine - fix stack pointer. */
1086 TREE_VEC_LENGTH (ret_map) = size;
1087 for (index = size; --index >= 0; )
1089 if (TREE_VEC_ELT (ret_map, index) != TYPE_UNUSED)
1090 TREE_VEC_ELT (ret_map, index) = type_map[index];
1092 RETURN_MAP_ADJUSTED (ret_map) = 1;
1096 if (TREE_VEC_LENGTH (ret_map) != size)
1097 VERIFICATION_ERROR ("inconsistent stack size on ret");
1098 for (index = 0; index < size; index++)
1100 tree type = TREE_VEC_ELT (ret_map, index);
1101 if (type != TYPE_UNUSED)
1103 type = merge_types (type, type_map [index]);
1104 TREE_VEC_ELT (ret_map, index) = type;
1105 if (type == TYPE_UNKNOWN)
1107 if (index >= size - stack_pointer)
1109 ("inconsistent types on ret from jsr");
1111 else if (TYPE_IS_WIDE (type))
1117 /* Check if there are any more pending blocks in this subroutine.
1118 Because we push pending blocks in a last-in-first-out order,
1119 and because we don't push anything from our caller until we
1120 are done with this subroutine or anything nested in it,
1121 then we are done if the top of the pending_blocks stack is
1122 not in a subroutine, or it is in our caller. */
1123 if (pending_blocks == NULL_TREE
1124 || ! LABEL_IN_SUBR (pending_blocks)
1125 || LABEL_SUBR_START (pending_blocks) == caller)
1127 /* Since we are done with this subroutine (i.e. this is the
1128 last ret from it), set up the (so far known) return
1129 address as pending - with the merged type state. */
1130 tmp = LABEL_RETURN_LABELS (current_subr);
1131 current_subr = caller;
1132 for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
1134 tree return_label = TREE_VALUE (tmp);
1135 tree return_state = LABEL_TYPE_STATE (return_label);
1136 if (return_state == NULL_TREE)
1138 /* This means means we had not verified the
1139 subroutine earlier, so this is the first jsr to
1140 call it. In this case, the type_map of the return
1141 address is just the current type_map - and that
1142 is handled by the following PUSH_PENDING. */
1146 /* In this case we have to do a merge. But first
1147 restore the type_map for unused slots to those
1148 that were in effect at the jsr. */
1149 for (index = size; --index >= 0; )
1151 type_map[index] = TREE_VEC_ELT (ret_map, index);
1152 if (type_map[index] == TYPE_UNUSED)
1154 = TREE_VEC_ELT (return_state, index);
1157 PUSH_PENDING (return_label);
1165 error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
1171 /* The following test is true if we have entered or exited an exception
1172 handler range *or* we have done a store to a local variable.
1173 In either case we need to consider any exception handlers that
1174 might "follow" this instruction. */
1176 if (eh_ranges != prev_eh_ranges)
1178 int save_stack_pointer = stack_pointer;
1179 int index = DECL_MAX_LOCALS (current_function_decl);
1180 tree save_type = type_map[index];
1181 tree save_current_subr = current_subr;
1182 struct eh_range *ranges = find_handler (oldpc);
1184 for (; ranges != NULL_EH_RANGE; ranges = ranges->outer)
1186 tree chain = ranges->handlers;
1188 /* We need to determine if the handler is part of current_subr.
1189 The are two cases: (1) The exception catch range
1190 is entirely within current_subr. In that case the handler
1191 is also part of current_subr.
1192 (2) Some of the catch range is not in current_subr.
1193 In that case, the handler is *not* part of current_subr.
1195 Figuring out which is the case is not necessarily obvious,
1196 in the presence of clever code generators (and obfuscators).
1197 We make a simplifying assumption that in case (2) we
1198 have that the current_subr is entirely within the catch range.
1199 In that case we can assume if that if a caller (the jsr) of
1200 a subroutine is within the catch range, then the handler is
1201 *not* part of the subroutine, and vice versa. */
1203 current_subr = save_current_subr;
1204 for ( ; current_subr != NULL_TREE;
1205 current_subr = LABEL_SUBR_CONTEXT (current_subr))
1207 tree return_labels = LABEL_RETURN_LABELS (current_subr);
1208 /* There could be multiple return_labels, but
1209 we only need to check one. */
1210 int return_pc = LABEL_PC (TREE_VALUE (return_labels));
1211 if (return_pc <= ranges->start_pc
1212 || return_pc > ranges->end_pc)
1216 for ( ; chain != NULL_TREE; chain = TREE_CHAIN (chain))
1218 tree handler = TREE_VALUE (chain);
1219 tree type = TREE_PURPOSE (chain);
1220 if (type == NULL_TREE) /* a finally handler */
1221 type = throwable_type_node;
1222 type_map[index] = promote_type (type);
1224 PUSH_PENDING (handler);
1227 stack_pointer = save_stack_pointer;
1228 current_subr = save_current_subr;
1229 type_map[index] = save_type;
1230 prev_eh_ranges = eh_ranges;
1235 message = "program counter out of range";
1238 error ("verification error at PC=%d: %s", oldpc, message);