1 /* Handle verification of bytecoded methods for the GNU compiler for
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
23 Java and all Java-based marks are trademarks or registered trademarks
24 of Sun Microsystems, Inc. in the United States and other countries.
25 The Free Software Foundation is independent of Sun Microsystems, Inc. */
27 /* This bytecode verifier is an implementation of the bytecode
28 verification process described in section 4.9 of "The Java(TM) Virtual
29 Machine Specification", Second Edition, by Tim Lindholm and Frank Yellin,
30 published by Addison-Wesley in 1999. */
34 #include "coretypes.h"
37 #include "java-tree.h"
39 #include "java-opcodes.h"
41 #include "java-except.h"
44 static void push_pending_label (tree);
45 static tree merge_types (tree, tree);
46 static const char *check_pending_block (tree);
47 static void type_stack_dup (int, int);
48 static int start_pc_cmp (const void *, const void *);
49 static char *pop_argument_types (tree);
51 extern int stack_pointer;
53 /* During verification, start of the current subroutine (jsr target). */
56 /* A list of pending blocks, chained using LABEL_PENDING_CHAIN.
57 A pending block is one that has LABEL_CHANGED set, which means
58 it requires (re-) verification. */
61 /* Append TARGET_LABEL to the pending_block stack unless already in it. */
64 push_pending_label (tree target_label)
66 if (! LABEL_CHANGED (target_label))
68 LABEL_PENDING_CHAIN (target_label) = pending_blocks;
69 pending_blocks = target_label;
70 LABEL_CHANGED (target_label) = 1;
74 /* Note that TARGET_LABEL is a possible successor instruction.
75 Merge the type state etc.
76 Return NULL on success, or an error message on failure. */
79 check_pending_block (tree target_label)
81 int changed = merge_type_state (target_label);
86 return "types could not be merged";
87 push_pending_label (target_label);
90 if (current_subr == NULL_TREE)
92 /* if (LABEL_IN_SUBR (target_label)) */
93 /* return "might transfer control into subroutine"; */
97 if (LABEL_IN_SUBR (target_label))
99 /* if (LABEL_SUBR_START (target_label) != current_subr) */
100 /* return "transfer out of subroutine"; */
102 else if (! LABEL_VERIFIED (target_label))
104 LABEL_IN_SUBR (target_label) = 1;
105 LABEL_SUBR_START (target_label) = current_subr;
108 /* return "transfer out of subroutine"; */
113 /* Count the number of nested jsr calls needed to reach LABEL. */
116 subroutine_nesting (tree label)
119 while (label != NULL_TREE && LABEL_IN_SUBR (label))
121 if (! LABEL_IS_SUBR_START (label))
122 label = LABEL_SUBR_START (label);
123 label = LABEL_SUBR_CONTEXT (label);
130 defer_merging (tree type1, tree type2)
132 // FIXME: This is just a placeholder until we replace the verifier
133 // altogether. We really need to ouput a type assertion for all of
134 // the types, every time they are used.
135 return object_ptr_type_node;
137 if (TREE_CODE (type1) == POINTER_TYPE)
138 type1 = TREE_TYPE (type1);
139 if (TREE_CODE (type2) == POINTER_TYPE)
140 type2 = TREE_TYPE (type2);
142 if (TREE_CODE (type1) == RECORD_TYPE && TREE_CODE (type2) == RECORD_TYPE)
144 tree list = build_tree_list (type1, NULL_TREE);
145 list = tree_cons (type2, NULL_TREE, list);
149 if (TREE_CODE (type1) == TREE_LIST && TREE_CODE (type2) == TREE_LIST)
151 return chainon (copy_list (type1), copy_list (type2));
154 if (TREE_CODE (type1) == TREE_LIST && TREE_CODE (type2) == RECORD_TYPE)
159 if (TREE_PURPOSE (tmp) == type2)
161 tmp = TREE_CHAIN (tmp);
165 return tree_cons (type2, NULL_TREE, copy_list (type1));
168 if (TREE_CODE (type2) == TREE_LIST && TREE_CODE (type1) == RECORD_TYPE)
170 return defer_merging (type2, type1);
177 /* Return the "merged" types of TYPE1 and TYPE2.
178 If either is primitive, the other must match (after promotion to int).
179 For reference types, return the common super-class.
180 Return TYPE_UNKNOWN if the types cannot be merged. */
183 merge_types (tree type1, tree type2)
187 if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
188 || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
191 if (TREE_CODE (type1) == TREE_LIST || TREE_CODE (type2) == TREE_LIST)
192 return defer_merging (type1, type2);
194 if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
198 /* ptr_type_node is only used for a null reference,
199 which is compatible with any reference type. */
200 if (type1 == ptr_type_node || type2 == object_ptr_type_node)
202 if (type2 == ptr_type_node || type1 == object_ptr_type_node)
205 tt1 = TREE_TYPE (type1);
206 tt2 = TREE_TYPE (type2);
208 if (TYPE_DUMMY (tt1) || TYPE_DUMMY (tt2))
209 return defer_merging (tt1, tt2);
211 /* If tt{1,2} haven't been properly loaded, now is a good time
213 if (!TYPE_SIZE (tt1))
216 safe_layout_class (tt1);
219 if (!TYPE_SIZE (tt2))
222 safe_layout_class (tt2);
225 if (TYPE_ARRAY_P (tt1) || TYPE_ARRAY_P (tt2))
227 if (TYPE_ARRAY_P (tt1) == TYPE_ARRAY_P (tt2))
229 tree el_type1 = TYPE_ARRAY_ELEMENT (tt1);
230 tree el_type2 = TYPE_ARRAY_ELEMENT (tt2);
231 tree el_type = NULL_TREE;
232 if (el_type1 == el_type2)
234 else if (TREE_CODE (el_type1) == POINTER_TYPE
235 && TREE_CODE (el_type2) == POINTER_TYPE)
236 el_type = merge_types (el_type1, el_type2);
237 if (el_type != NULL_TREE)
239 HOST_WIDE_INT len1 = java_array_type_length (tt1);
240 HOST_WIDE_INT len2 = java_array_type_length (tt2);
243 else if (el_type1 == el_type2)
245 return promote_type (build_java_array_type (el_type, len1));
248 return object_ptr_type_node;
251 if (CLASS_INTERFACE (TYPE_NAME (tt1))
252 || (CLASS_INTERFACE (TYPE_NAME (tt2))))
254 return object_ptr_type_node;
260 depth1 = class_depth (type1);
261 depth2 = class_depth (type2);
262 for ( ; depth1 > depth2; depth1--)
263 type1 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type1), 0));
264 for ( ; depth2 > depth1; depth2--)
265 type2 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type2), 0));
266 while (type1 != type2)
268 type1 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type1), 0));
269 type2 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type2), 0));
271 return promote_type (type1);
273 if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)
274 && TYPE_PRECISION (type1) <= 32 && TYPE_PRECISION (type2) <= 32)
275 return int_type_node;
279 /* Merge the current type state with that at LABEL.
280 Return -1 if the states are incompatible (i.e. on error),
281 0 if there was no change, and 1 if there was a change. */
284 merge_type_state (tree label)
286 int nlocals = DECL_MAX_LOCALS (current_function_decl);
287 int cur_length = stack_pointer + nlocals;
288 tree vec = LABEL_TYPE_STATE (label);
290 if (vec == NULL_TREE)
292 vec = make_tree_vec (cur_length);
293 LABEL_TYPE_STATE (label) = vec;
295 while (--cur_length >= 0)
296 TREE_VEC_ELT (vec, cur_length) = type_map[cur_length];
303 if (LABEL_IS_SUBR_START (label) && LABEL_VERIFIED (label)
304 && current_subr != label)
305 return_map = LABEL_RETURN_TYPE_STATE (label);
307 return_map = NULL_TREE;
308 if (TREE_VEC_LENGTH (vec) != cur_length)
312 for (i = 0; i < cur_length; i++)
314 tree old_type = TREE_VEC_ELT (vec, i);
315 tree new_type = merge_types (old_type, type_map[i]);
316 if (TREE_VEC_ELT (vec, i) != new_type)
318 /* If there has been a change, note that since we must re-verify.
319 However, if the label is the start of a subroutine,
320 we don't care about local variables that are neither
321 set nor used in the subroutine. */
322 if (return_map == NULL_TREE || i >= nlocals
323 || TREE_VEC_ELT (return_map, i) != TYPE_UNUSED
324 || (TYPE_IS_WIDE (new_type)
325 && TREE_VEC_ELT (return_map, i+1) != TYPE_UNUSED))
328 TREE_VEC_ELT (vec, i) = new_type;
329 if (new_type == TYPE_UNKNOWN)
334 else if (TYPE_IS_WIDE (new_type))
341 /* Handle dup-like operations. */
344 type_stack_dup (int size, int offset)
348 for (index = 0; index < size + offset; index++)
350 type[index] = stack_type_map[stack_pointer - 1];
351 if (type[index] == void_type_node)
354 type[index] = stack_type_map[stack_pointer - 2];
355 if (! TYPE_IS_WIDE (type[index]))
357 if (index == size || index == size + offset)
358 /* Dup operation splits 64-bit number. */
361 pop_type (type[index]);
363 for (index = size; --index >= 0; )
365 if (type[index] != void_type_node)
366 push_type (type[index]);
369 for (index = size + offset; --index >= 0; )
371 if (type[index] != void_type_node)
372 push_type (type[index]);
376 /* This keeps track of a start PC and corresponding initial index. */
383 /* A helper that is used when sorting exception ranges. */
385 start_pc_cmp (const void *xp, const void *yp)
387 const struct pc_index *x = (const struct pc_index *) xp;
388 const struct pc_index *y = (const struct pc_index *) yp;
389 return x->start_pc - y->start_pc;
392 /* This causes the next iteration to ignore the next instruction
393 and look for some other unhandled instruction. */
394 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
395 #define INVALID_PC (-1)
397 #define VERIFICATION_ERROR(MESSAGE) \
398 do { message = MESSAGE; goto verify_error; } while (0)
400 #define VERIFICATION_ERROR_WITH_INDEX(MESSAGE) \
401 do { message = MESSAGE; goto error_with_index; } while (0)
403 /* Recursive helper function to pop argument types during verification.
404 ARG_TYPES is the list of formal parameter types.
405 Return NULL on success and a freshly malloc'd error message on failure. */
408 pop_argument_types (tree arg_types)
410 if (arg_types == end_params_node)
412 if (TREE_CODE (arg_types) == TREE_LIST)
414 char *message = pop_argument_types (TREE_CHAIN (arg_types));
416 pop_type_0 (TREE_VALUE (arg_types), &message);
422 #define POP_TYPE(TYPE, MESSAGE) \
423 do { pmessage = NULL; pop_type_0 (TYPE, &pmessage); \
424 if (pmessage != NULL) goto pop_type_error; \
427 #define POP_TYPE_CONV(TYPE, POPPED_TYPE, MESSAGE) \
428 do { pmessage = NULL; POPPED_TYPE = pop_type_0 (TYPE, &pmessage); \
429 if (pmessage != NULL) goto pop_type_error; \
432 #define PUSH_TYPE(TYPE) \
433 do { if (! push_type_0 (TYPE)) { goto stack_overflow; }} while (0)
435 #define PUSH_PENDING(LABEL) \
436 do { tree tmplab = LABEL; \
437 if ((message = check_pending_block (tmplab)) != NULL) \
438 { oldpc = LABEL_PC (tmplab); goto verify_error; }} while (0)
441 #define CHECK_PC_IN_RANGE(PC) __extension__ \
442 ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
444 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? (abort (), 0) : 1)
447 #define BCODE byte_ops
450 /* Verify the bytecodes of the current method, with the instructions
451 starting at BYTE_OPS and LENGTH in number, from the class file pointed to
453 Return 1 on success, 0 on failure. */
455 verify_jvm_instructions (JCF* jcf, const unsigned char *byte_ops, long length)
461 int oldpc = 0; /* PC of start of instruction. */
462 int prevpc = 0; /* If >= 0, PC of previous instruction. */
463 const char *message = 0;
468 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
469 struct eh_range *eh_ranges;
470 tree return_type = TREE_TYPE (TREE_TYPE (current_function_decl));
471 struct pc_index *starts;
476 pending_blocks = NULL_TREE;
478 current_subr = NULL_TREE;
480 /* Handle the exception table. */
481 method_init_exceptions ();
482 JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
483 eh_count = JCF_readu2 (jcf);
485 /* We read the exception handlers in order of increasing start PC.
486 To do this we first read and sort the start PCs. */
487 starts = xmalloc (eh_count * sizeof (struct pc_index));
488 for (i = 0; i < eh_count; ++i)
490 starts[i].start_pc = GET_u2 (jcf->read_ptr + 8 * i);
493 qsort (starts, eh_count, sizeof (struct pc_index), start_pc_cmp);
495 for (i = 0; i < eh_count; ++i)
497 int start_pc, end_pc, handler_pc, catch_type;
499 p = jcf->read_ptr + 8 * starts[i].index;
501 start_pc = GET_u2 (p);
502 end_pc = GET_u2 (p+2);
503 handler_pc = GET_u2 (p+4);
504 catch_type = GET_u2 (p+6);
506 if (start_pc < 0 || start_pc >= length
507 || end_pc < 0 || end_pc > length || start_pc >= end_pc
508 || handler_pc < 0 || handler_pc >= length
509 || ! (instruction_bits[start_pc] & BCODE_INSTRUCTION_START)
510 || (end_pc < length &&
511 ! (instruction_bits[end_pc] & BCODE_INSTRUCTION_START))
512 || ! (instruction_bits[handler_pc] & BCODE_INSTRUCTION_START))
514 error ("bad pc in exception_table");
519 add_handler (start_pc, end_pc,
520 lookup_label (handler_pc),
521 catch_type == 0 ? NULL_TREE
522 : get_class_constant (jcf, catch_type));
524 instruction_bits[handler_pc] |= BCODE_EXCEPTION_TARGET;
528 handle_nested_ranges ();
534 if (((PC != INVALID_PC
535 && instruction_bits[PC] & BCODE_TARGET) != 0)
538 PUSH_PENDING (lookup_label (PC));
542 /* Check if there are any more pending blocks in the current
543 subroutine. Because we push pending blocks in a
544 last-in-first-out order, and because we don't push anything
545 from our caller until we are done with this subroutine or
546 anything nested in it, we are done if the top of the
547 pending_blocks stack is not in a subroutine, or it is in our
549 if (current_subr && PC == INVALID_PC)
551 if (pending_blocks == NULL_TREE
552 || (subroutine_nesting (pending_blocks)
553 < subroutine_nesting (current_subr)))
556 = DECL_MAX_LOCALS (current_function_decl) + stack_pointer;
558 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
559 tmp = LABEL_RETURN_LABELS (current_subr);
561 /* FIXME: If we exit a subroutine via a throw, we might
562 have returned to an earlier caller. Obviously a
563 "ret" can only return one level, but a throw may
564 return many levels. */
565 current_subr = LABEL_SUBR_CONTEXT (current_subr);
567 if (RETURN_MAP_ADJUSTED (ret_map))
569 /* Since we are done with this subroutine, set up
570 the (so far known) return address as pending -
571 with the merged type state. */
572 for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
574 tree return_label = TREE_VALUE (tmp);
575 tree return_state = LABEL_TYPE_STATE (return_label);
576 if (return_state == NULL_TREE)
578 /* This means we had not verified the subroutine
579 earlier, so this is the first jsr to call it.
580 In this case, the type_map of the return
581 address is just the current type_map - and that
582 is handled by the following PUSH_PENDING. */
586 /* In this case we have to do a merge. But first
587 restore the type_map for unused slots to those
588 that were in effect at the jsr. */
589 for (index = size; --index >= 0; )
592 = TREE_VEC_ELT (ret_map, index);
594 if (type_map[index] == TYPE_UNUSED)
596 = TREE_VEC_ELT (return_state, index);
599 PUSH_PENDING (return_label);
605 if (PC == INVALID_PC)
607 label = pending_blocks;
609 if (label == NULL_TREE)
610 break; /* We're done! */
612 pending_blocks = LABEL_PENDING_CHAIN (label);
613 LABEL_CHANGED (label) = 0;
615 if (LABEL_IN_SUBR (label))
616 current_subr = LABEL_SUBR_START (label);
618 current_subr = NULL_TREE;
620 /* Restore type_map and stack_pointer from
621 LABEL_TYPE_STATE (label), and continue
622 compiling from there. */
623 load_type_state (label);
625 PC = LABEL_PC (label);
627 else if (PC >= length)
628 VERIFICATION_ERROR ("falling through the end of the method");
633 if (! (instruction_bits[PC] & BCODE_INSTRUCTION_START) && ! wide)
634 VERIFICATION_ERROR ("PC not at instruction start");
636 instruction_bits[PC] |= BCODE_VERIFIED;
638 eh_ranges = find_handler (oldpc);
640 op_code = byte_ops[PC++];
643 int is_static, is_putting;
648 case OPCODE_iconst_m1:
649 case OPCODE_iconst_0: case OPCODE_iconst_1: case OPCODE_iconst_2:
650 case OPCODE_iconst_3: case OPCODE_iconst_4: case OPCODE_iconst_5:
651 i = op_code - OPCODE_iconst_0;
654 if (byte_ops[PC] == OPCODE_newarray
655 || byte_ops[PC] == OPCODE_anewarray)
657 PUSH_TYPE (int_type_node); break;
659 case OPCODE_lconst_0: case OPCODE_lconst_1:
660 PUSH_TYPE (long_type_node); break;
662 case OPCODE_fconst_0: case OPCODE_fconst_1: case OPCODE_fconst_2:
663 PUSH_TYPE (float_type_node); break;
665 case OPCODE_dconst_0: case OPCODE_dconst_1:
666 PUSH_TYPE (double_type_node); break;
676 case OPCODE_iload: type = int_type_node; goto general_load;
677 case OPCODE_lload: type = long_type_node; goto general_load;
678 case OPCODE_fload: type = float_type_node; goto general_load;
679 case OPCODE_dload: type = double_type_node; goto general_load;
680 case OPCODE_aload: type = ptr_type_node; goto general_load;
682 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
685 case OPCODE_iload_0: type = int_type_node; index = 0; goto load;
686 case OPCODE_iload_1: type = int_type_node; index = 1; goto load;
687 case OPCODE_iload_2: type = int_type_node; index = 2; goto load;
688 case OPCODE_iload_3: type = int_type_node; index = 3; goto load;
689 case OPCODE_lload_0: type = long_type_node; index = 0; goto load;
690 case OPCODE_lload_1: type = long_type_node; index = 1; goto load;
691 case OPCODE_lload_2: type = long_type_node; index = 2; goto load;
692 case OPCODE_lload_3: type = long_type_node; index = 3; goto load;
693 case OPCODE_fload_0: type = float_type_node; index = 0; goto load;
694 case OPCODE_fload_1: type = float_type_node; index = 1; goto load;
695 case OPCODE_fload_2: type = float_type_node; index = 2; goto load;
696 case OPCODE_fload_3: type = float_type_node; index = 3; goto load;
697 case OPCODE_dload_0: type = double_type_node; index = 0; goto load;
698 case OPCODE_dload_1: type = double_type_node; index = 1; goto load;
699 case OPCODE_dload_2: type = double_type_node; index = 2; goto load;
700 case OPCODE_dload_3: type = double_type_node; index = 3; goto load;
701 case OPCODE_aload_0: type = ptr_type_node; index = 0; goto load;
702 case OPCODE_aload_1: type = ptr_type_node; index = 1; goto load;
703 case OPCODE_aload_2: type = ptr_type_node; index = 2; goto load;
704 case OPCODE_aload_3: type = ptr_type_node; index = 3; goto load;
707 || (index + TYPE_IS_WIDE (type)
708 >= DECL_MAX_LOCALS (current_function_decl)))
709 VERIFICATION_ERROR_WITH_INDEX
710 ("invalid local variable index %d in load");
711 tmp = type_map[index];
712 if (TREE_CODE (tmp) != TREE_LIST)
714 if (tmp == TYPE_UNKNOWN)
715 VERIFICATION_ERROR_WITH_INDEX
716 ("loading local variable %d which has unknown type");
717 else if (tmp == TYPE_SECOND
718 || (TYPE_IS_WIDE (type)
719 && type_map[index+1] != void_type_node)
720 || (type == ptr_type_node
721 ? TREE_CODE (tmp) != POINTER_TYPE
722 : type == int_type_node
723 ? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
725 VERIFICATION_ERROR_WITH_INDEX
726 ("loading local variable %d which has invalid type");
730 case OPCODE_istore: type = int_type_node; goto general_store;
731 case OPCODE_lstore: type = long_type_node; goto general_store;
732 case OPCODE_fstore: type = float_type_node; goto general_store;
733 case OPCODE_dstore: type = double_type_node; goto general_store;
734 case OPCODE_astore: type = object_ptr_type_node; goto general_store;
736 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
739 case OPCODE_istore_0: type = int_type_node; index = 0; goto store;
740 case OPCODE_istore_1: type = int_type_node; index = 1; goto store;
741 case OPCODE_istore_2: type = int_type_node; index = 2; goto store;
742 case OPCODE_istore_3: type = int_type_node; index = 3; goto store;
743 case OPCODE_lstore_0: type = long_type_node; index=0; goto store;
744 case OPCODE_lstore_1: type = long_type_node; index=1; goto store;
745 case OPCODE_lstore_2: type = long_type_node; index=2; goto store;
746 case OPCODE_lstore_3: type = long_type_node; index=3; goto store;
747 case OPCODE_fstore_0: type=float_type_node; index=0; goto store;
748 case OPCODE_fstore_1: type=float_type_node; index=1; goto store;
749 case OPCODE_fstore_2: type=float_type_node; index=2; goto store;
750 case OPCODE_fstore_3: type=float_type_node; index=3; goto store;
751 case OPCODE_dstore_0: type=double_type_node; index=0; goto store;
752 case OPCODE_dstore_1: type=double_type_node; index=1; goto store;
753 case OPCODE_dstore_2: type=double_type_node; index=2; goto store;
754 case OPCODE_dstore_3: type=double_type_node; index=3; goto store;
755 case OPCODE_astore_0: type = ptr_type_node; index = 0; goto store;
756 case OPCODE_astore_1: type = ptr_type_node; index = 1; goto store;
757 case OPCODE_astore_2: type = ptr_type_node; index = 2; goto store;
758 case OPCODE_astore_3: type = ptr_type_node; index = 3; goto store;
761 || (index + TYPE_IS_WIDE (type)
762 >= DECL_MAX_LOCALS (current_function_decl)))
764 VERIFICATION_ERROR_WITH_INDEX
765 ("invalid local variable index %d in store");
768 POP_TYPE_CONV (type, type, NULL);
769 type_map[index] = type;
771 /* If a local variable has changed, we need to reconsider exception
773 prev_eh_ranges = NULL_EH_RANGE;
775 /* Allocate decl for this variable now, so we get a temporary
776 that survives the whole method. */
777 find_local_variable (index, type, oldpc);
779 if (TYPE_IS_WIDE (type))
780 type_map[index+1] = TYPE_SECOND;
782 /* ... fall through to note_used ... */
784 /* For store or load, note that local variable INDEX is used.
785 This is needed to verify try-finally subroutines. */
788 tree vec = LABEL_RETURN_TYPE_STATE (current_subr);
789 tree subr_vec = LABEL_TYPE_STATE (current_subr);
790 int len = 1 + TYPE_IS_WIDE (type);
793 if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)
794 TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);
809 type = int_type_node; goto binop;
814 type = int_type_node; goto unop;
823 type = long_type_node; goto binop;
825 type = long_type_node; goto unop;
826 case OPCODE_fadd: case OPCODE_fsub:
827 case OPCODE_fmul: case OPCODE_fdiv: case OPCODE_frem:
828 type = float_type_node; goto binop;
830 type = float_type_node; goto unop;
831 case OPCODE_dadd: case OPCODE_dsub:
832 case OPCODE_dmul: case OPCODE_ddiv: case OPCODE_drem:
833 type = double_type_node; goto binop;
835 type = double_type_node; goto unop;
851 pop_type (int_type_node);
852 pop_type (long_type_node);
853 PUSH_TYPE (long_type_node);
857 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
860 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))
861 VERIFICATION_ERROR ("invalid local variable index in iinc");
862 tmp = type_map[index];
864 || ! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
865 VERIFICATION_ERROR ("invalid local variable type in iinc");
869 pop_type (int_type_node); PUSH_TYPE (long_type_node); break;
871 pop_type (int_type_node); PUSH_TYPE (float_type_node); break;
873 pop_type (int_type_node); PUSH_TYPE (double_type_node); break;
875 pop_type (long_type_node); PUSH_TYPE (int_type_node); break;
877 pop_type (long_type_node); PUSH_TYPE (float_type_node); break;
879 pop_type (long_type_node); PUSH_TYPE (double_type_node); break;
881 pop_type (float_type_node); PUSH_TYPE (int_type_node); break;
883 pop_type (float_type_node); PUSH_TYPE (long_type_node); break;
885 pop_type (float_type_node); PUSH_TYPE (double_type_node); break;
887 pop_type (double_type_node); PUSH_TYPE (int_type_node); break;
889 pop_type (double_type_node); PUSH_TYPE (long_type_node); break;
891 pop_type (double_type_node); PUSH_TYPE (float_type_node); break;
894 type = long_type_node; goto compare;
897 type = float_type_node; goto compare;
900 type = double_type_node; goto compare;
902 pop_type (type); pop_type (type);
903 PUSH_TYPE (int_type_node); break;
911 pop_type (int_type_node); goto cond;
913 case OPCODE_ifnonnull:
914 pop_type (ptr_type_node ); goto cond;
915 case OPCODE_if_icmpeq:
916 case OPCODE_if_icmpne:
917 case OPCODE_if_icmplt:
918 case OPCODE_if_icmpge:
919 case OPCODE_if_icmpgt:
920 case OPCODE_if_icmple:
921 pop_type (int_type_node); pop_type (int_type_node); goto cond;
922 case OPCODE_if_acmpeq:
923 case OPCODE_if_acmpne:
924 pop_type (object_ptr_type_node); pop_type (object_ptr_type_node);
928 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
932 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
937 switch (byte_ops[PC])
939 case OPCODE_iload: case OPCODE_lload:
940 case OPCODE_fload: case OPCODE_dload: case OPCODE_aload:
941 case OPCODE_istore: case OPCODE_lstore:
942 case OPCODE_fstore: case OPCODE_dstore: case OPCODE_astore:
948 VERIFICATION_ERROR ("invalid use of wide instruction");
952 case OPCODE_return: type = void_type_node; goto ret;
954 if ((TREE_CODE (return_type) == BOOLEAN_TYPE
955 || TREE_CODE (return_type) == CHAR_TYPE
956 || TREE_CODE (return_type) == INTEGER_TYPE)
957 && TYPE_PRECISION (return_type) <= 32)
962 case OPCODE_lreturn: type = long_type_node; goto ret;
963 case OPCODE_freturn: type = float_type_node; goto ret;
964 case OPCODE_dreturn: type = double_type_node; goto ret;
966 if (TREE_CODE (return_type) == POINTER_TYPE)
973 if (type != return_type)
974 VERIFICATION_ERROR ("incorrect ?return opcode");
975 if (type != void_type_node)
976 POP_TYPE (type, "return value has wrong type");
980 case OPCODE_getstatic: is_putting = 0; is_static = 1; goto field;
981 case OPCODE_putstatic: is_putting = 1; is_static = 1; goto field;
982 case OPCODE_getfield: is_putting = 0; is_static = 0; goto field;
983 case OPCODE_putfield: is_putting = 1; is_static = 0; goto field;
986 tree field_signature, field_type;
987 index = IMMEDIATE_u2;
989 if (index <= 0 || index >= JPOOL_SIZE (current_jcf))
990 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d");
992 if (JPOOL_TAG (current_jcf, index) != CONSTANT_Fieldref)
994 ("field instruction does not reference a Fieldref");
997 = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, index);
999 field_type = get_type_from_signature (field_signature);
1002 POP_TYPE (field_type, "incorrect type for field");
1007 = COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool, index);
1009 tree self_type = get_class_constant (current_jcf, clindex);
1011 /* Defer actual checking until next pass. */
1012 POP_TYPE (self_type, "incorrect type for field reference");
1016 PUSH_TYPE (field_type);
1021 PUSH_TYPE (get_class_constant (jcf, IMMEDIATE_u2));
1024 case OPCODE_dup: wide = 1; index = 0; goto dup;
1025 case OPCODE_dup_x1: wide = 1; index = 1; goto dup;
1026 case OPCODE_dup_x2: wide = 1; index = 2; goto dup;
1027 case OPCODE_dup2: wide = 2; index = 0; goto dup;
1028 case OPCODE_dup2_x1: wide = 2; index = 1; goto dup;
1029 case OPCODE_dup2_x2: wide = 2; index = 2; goto dup;
1032 if (wide + index > stack_pointer)
1033 VERIFICATION_ERROR ("stack underflow - dup* operation");
1034 type_stack_dup (wide, index);
1038 case OPCODE_pop: index = 1; goto pop;
1039 case OPCODE_pop2: index = 2; goto pop;
1042 if (stack_pointer < index)
1043 VERIFICATION_ERROR ("stack underflow");
1044 stack_pointer -= index;
1048 if (stack_pointer < 2)
1049 VERIFICATION_ERROR ("stack underflow (in swap)");
1052 tree type1 = stack_type_map[stack_pointer - 1];
1053 tree type2 = stack_type_map[stack_pointer - 2];
1055 if (type1 == void_type_node || type2 == void_type_node)
1056 VERIFICATION_ERROR ("verifier (swap): double or long value");
1058 stack_type_map[stack_pointer - 2] = type1;
1059 stack_type_map[stack_pointer - 1] = type2;
1063 case OPCODE_ldc: index = IMMEDIATE_u1; goto ldc;
1066 index = IMMEDIATE_u2; goto ldc;
1069 if (index <= 0 || index >= JPOOL_SIZE (current_jcf))
1070 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d in ldc");
1073 switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)
1075 case CONSTANT_Integer: type = int_type_node; goto check_ldc;
1076 case CONSTANT_Float: type = float_type_node; goto check_ldc;
1077 case CONSTANT_String: type = string_type_node; goto check_ldc;
1078 case CONSTANT_Long: type = long_type_node; goto check_ldc;
1079 case CONSTANT_Double: type = double_type_node; goto check_ldc;
1081 if (TYPE_IS_WIDE (type) == (op_code == OPCODE_ldc2_w))
1083 /* ... else fall through ... */
1085 VERIFICATION_ERROR ("bad constant pool tag in ldc");
1087 if (type == int_type_node)
1089 i = TREE_INT_CST_LOW (get_constant (current_jcf, index));
1095 case OPCODE_invokevirtual:
1096 case OPCODE_invokespecial:
1097 case OPCODE_invokestatic:
1098 case OPCODE_invokeinterface:
1100 tree sig, method_name, method_type, self_type;
1101 int self_is_interface, tag;
1102 index = IMMEDIATE_u2;
1104 if (index <= 0 || index >= JPOOL_SIZE (current_jcf))
1105 VERIFICATION_ERROR_WITH_INDEX
1106 ("bad constant pool index %d for invoke");
1108 tag = JPOOL_TAG (current_jcf, index);
1110 if (op_code == OPCODE_invokeinterface)
1112 if (tag != CONSTANT_InterfaceMethodref)
1114 ("invokeinterface does not reference an InterfaceMethodref");
1118 if (tag != CONSTANT_Methodref)
1119 VERIFICATION_ERROR ("invoke does not reference a Methodref");
1122 sig = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, index);
1125 = get_class_constant (current_jcf,
1126 COMPONENT_REF_CLASS_INDEX
1127 (¤t_jcf->cpool, index));
1129 if (! CLASS_LOADED_P (self_type))
1130 load_class (self_type, 1);
1132 if (TYPE_DUMMY (self_type) && op_code == OPCODE_invokeinterface)
1133 /* Assume we are an interface. */
1134 CLASS_INTERFACE (TYPE_NAME (self_type)) = 1;
1136 self_is_interface = CLASS_INTERFACE (TYPE_NAME (self_type));
1137 method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, index);
1138 method_type = parse_signature_string ((const unsigned char *) IDENTIFIER_POINTER (sig),
1139 IDENTIFIER_LENGTH (sig));
1141 if (TREE_CODE (method_type) != FUNCTION_TYPE)
1142 VERIFICATION_ERROR ("bad method signature");
1144 pmessage = pop_argument_types (TYPE_ARG_TYPES (method_type));
1145 if (pmessage != NULL)
1147 message = "invalid argument type";
1148 goto pop_type_error;
1151 /* Can't invoke <clinit>. */
1152 if (ID_CLINIT_P (method_name))
1153 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
1155 /* Apart from invokespecial, can't invoke <init>. */
1156 if (op_code != OPCODE_invokespecial && ID_INIT_P (method_name))
1157 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
1159 if (op_code != OPCODE_invokestatic)
1160 POP_TYPE (self_type,
1161 "stack type not subclass of invoked method's class");
1165 case OPCODE_invokeinterface:
1167 int nargs = IMMEDIATE_u1;
1168 int notZero = IMMEDIATE_u1;
1170 if (!nargs || notZero)
1172 ("invalid argument number in invokeinterface");
1173 /* If we verify/resolve the constant pool, as we should,
1174 this test (and the one just following) are redundant. */
1175 if (! self_is_interface)
1177 ("invokeinterface calls method not in interface");
1181 if (self_is_interface)
1182 VERIFICATION_ERROR ("method in interface called");
1186 if (TREE_TYPE (method_type) != void_type_node)
1187 PUSH_TYPE (TREE_TYPE (method_type));
1191 case OPCODE_arraylength:
1192 /* Type checking actually made during code generation. */
1193 pop_type (ptr_type_node);
1194 PUSH_TYPE (int_type_node);
1197 /* Q&D verification *or* more checking done during code generation
1198 for byte/boolean/char/short, the value popped is a int coerced
1199 into the right type before being stored. */
1200 case OPCODE_iastore: type = int_type_node; goto astore;
1201 case OPCODE_lastore: type = long_type_node; goto astore;
1202 case OPCODE_fastore: type = float_type_node; goto astore;
1203 case OPCODE_dastore: type = double_type_node; goto astore;
1204 case OPCODE_aastore: type = ptr_type_node; goto astore;
1205 case OPCODE_bastore: type = int_type_node; goto astore;
1206 case OPCODE_castore: type = int_type_node; goto astore;
1207 case OPCODE_sastore: type = int_type_node; goto astore;
1210 /* FIXME - need better verification here. */
1211 pop_type (type); /* new value */
1212 pop_type (int_type_node); /* index */
1213 pop_type (ptr_type_node); /* array */
1216 /* Q&D verification *or* more checking done during code generation
1217 for byte/boolean/char/short, the value pushed is a int. */
1218 case OPCODE_iaload: type = int_type_node; goto aload;
1219 case OPCODE_laload: type = long_type_node; goto aload;
1220 case OPCODE_faload: type = float_type_node; goto aload;
1221 case OPCODE_daload: type = double_type_node; goto aload;
1222 case OPCODE_aaload: type = ptr_type_node; goto aload;
1223 case OPCODE_baload: type = promote_type (byte_type_node); goto aload;
1224 case OPCODE_caload: type = promote_type (char_type_node); goto aload;
1225 case OPCODE_saload: type = promote_type (short_type_node); goto aload;
1228 pop_type (int_type_node);
1229 tmp = pop_type (ptr_type_node);
1230 if (is_array_type_p (tmp))
1231 type = TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp));
1232 else if (tmp != TYPE_NULL)
1233 VERIFICATION_ERROR ("array load from non-array type");
1237 case OPCODE_anewarray:
1238 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1239 type = promote_type (type);
1242 case OPCODE_newarray:
1243 index = IMMEDIATE_u1;
1244 type = decode_newarray_type (index);
1245 if (type == NULL_TREE)
1246 VERIFICATION_ERROR ("invalid type code in newarray opcode");
1250 if (int_value >= 0 && prevpc >= 0)
1252 /* If the previous instruction pushed an int constant,
1253 we want to use it. */
1254 switch (byte_ops[prevpc])
1256 case OPCODE_iconst_0: case OPCODE_iconst_1:
1257 case OPCODE_iconst_2: case OPCODE_iconst_3:
1258 case OPCODE_iconst_4: case OPCODE_iconst_5:
1259 case OPCODE_bipush: case OPCODE_sipush:
1260 case OPCODE_ldc: case OPCODE_ldc_w:
1269 type = build_java_array_type (type, int_value);
1270 pop_type (int_type_node);
1274 case OPCODE_multianewarray:
1277 index = IMMEDIATE_u2;
1278 ndim = IMMEDIATE_u1;
1282 ("number of dimension lower that 1 in multianewarray" );
1284 for (i = 0; i < ndim; i++)
1285 pop_type (int_type_node);
1287 PUSH_TYPE (get_class_constant (current_jcf, index));
1291 case OPCODE_aconst_null:
1292 PUSH_TYPE (ptr_type_node);
1296 /* FIXME: athrow also empties the stack. */
1297 POP_TYPE (throwable_type_node, "missing throwable at athrow" );
1301 case OPCODE_checkcast:
1302 POP_TYPE (object_ptr_type_node,
1303 "checkcast operand is not a pointer");
1304 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1308 case OPCODE_instanceof:
1309 POP_TYPE (object_ptr_type_node,
1310 "instanceof operand is not a pointer");
1311 get_class_constant (current_jcf, IMMEDIATE_u2);
1312 PUSH_TYPE (int_type_node);
1315 case OPCODE_tableswitch:
1319 POP_TYPE (int_type_node, "missing int for tableswitch");
1324 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
1327 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1329 high = IMMEDIATE_s4;
1332 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
1334 while (low++ <= high)
1335 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1341 case OPCODE_lookupswitch:
1343 jint npairs, last = 0, not_registered = 1;
1345 POP_TYPE (int_type_node, "missing int for lookupswitch");
1350 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
1353 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1354 npairs = IMMEDIATE_s4;
1357 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1361 int match = IMMEDIATE_s4;
1365 else if (last >= match)
1366 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1369 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1375 case OPCODE_monitorenter:
1377 case OPCODE_monitorexit:
1378 pop_type (ptr_type_node);
1382 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1388 tree target = lookup_label (oldpc + IMMEDIATE_s2);
1389 tree return_label = lookup_label (PC);
1390 PUSH_TYPE (return_address_type_node);
1391 /* The return label chain will be null if this is the first
1392 time we've seen this jsr target. */
1393 if (LABEL_RETURN_LABEL (target) == NULL_TREE)
1395 tree return_type_map;
1396 int nlocals = DECL_MAX_LOCALS (current_function_decl);
1397 index = nlocals + DECL_MAX_STACK (current_function_decl);
1398 return_type_map = make_tree_vec (index);
1400 while (index > nlocals)
1401 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
1404 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
1406 LABEL_RETURN_LABEL (target)
1407 = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
1408 LABEL_PC (LABEL_RETURN_LABEL (target)) = INVALID_PC;
1409 LABEL_RETURN_TYPE_STATE (target) = return_type_map;
1410 LABEL_IS_SUBR_START (target) = 1;
1411 LABEL_IN_SUBR (target) = 1;
1412 LABEL_SUBR_START (target) = target;
1413 LABEL_SUBR_CONTEXT (target) = current_subr;
1415 else if (! LABEL_IS_SUBR_START (target)
1416 || LABEL_SUBR_CONTEXT (target) != current_subr)
1417 VERIFICATION_ERROR ("label part of different subroutines");
1419 i = merge_type_state (target);
1423 VERIFICATION_ERROR ("types could not be merged at jsr");
1424 push_pending_label (target);
1426 current_subr = target;
1428 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1429 if (! value_member (return_label, LABEL_RETURN_LABELS (target)))
1431 LABEL_RETURN_LABELS (target)
1432 = tree_cons (NULL_TREE, return_label,
1433 LABEL_RETURN_LABELS (target));
1436 if (LABEL_VERIFIED (target))
1438 tree return_map = LABEL_RETURN_TYPE_STATE (target);
1439 int len = TREE_VEC_LENGTH (return_map);
1440 stack_pointer = len - DECL_MAX_LOCALS (current_function_decl);
1443 if (TREE_VEC_ELT (return_map, len) != TYPE_UNUSED)
1444 type_map[len] = TREE_VEC_ELT (return_map, len);
1446 current_subr = LABEL_SUBR_CONTEXT (target);
1447 if (RETURN_MAP_ADJUSTED (return_map))
1448 PUSH_PENDING (return_label);
1456 if (current_subr == NULL_TREE)
1457 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1460 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
1462 = DECL_MAX_LOCALS (current_function_decl) + stack_pointer;
1463 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
1466 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl)
1467 || type_map[index] != TYPE_RETURN_ADDR)
1468 VERIFICATION_ERROR ("invalid ret index");
1470 /* The next chunk of code is similar to an inlined version of
1471 merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1472 The main differences are that LABEL_RETURN_LABEL is
1473 pre-allocated by the jsr (but we don't know the size then);
1474 and that we have to handle TYPE_UNUSED. */
1476 if (! RETURN_MAP_ADJUSTED (ret_map))
1478 /* First return from this subroutine - fix stack
1480 TREE_VEC_LENGTH (ret_map) = size;
1481 for (index = size; --index >= 0; )
1483 if (TREE_VEC_ELT (ret_map, index) != TYPE_UNUSED)
1484 TREE_VEC_ELT (ret_map, index) = type_map[index];
1486 RETURN_MAP_ADJUSTED (ret_map) = 1;
1490 if (TREE_VEC_LENGTH (ret_map) != size)
1491 VERIFICATION_ERROR ("inconsistent stack size on ret");
1492 for (index = 0; index < size; index++)
1494 tree type = TREE_VEC_ELT (ret_map, index);
1495 if (type != TYPE_UNUSED)
1497 type = merge_types (type, type_map[index]);
1498 TREE_VEC_ELT (ret_map, index) = type;
1499 if (type == TYPE_UNKNOWN)
1501 if (index >= size - stack_pointer)
1503 ("inconsistent types on ret from jsr");
1505 else if (TYPE_IS_WIDE (type))
1516 error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
1522 /* The following test is true if we have entered or exited an exception
1523 handler range *or* we have done a store to a local variable.
1524 In either case we need to consider any exception handlers that
1525 might "follow" this instruction. */
1527 if (eh_ranges != prev_eh_ranges)
1529 int save_stack_pointer = stack_pointer;
1530 int index = DECL_MAX_LOCALS (current_function_decl);
1531 tree save_type = type_map[index];
1532 tree save_current_subr = current_subr;
1533 struct eh_range *ranges = find_handler (oldpc);
1536 for ( ; ranges != NULL_EH_RANGE; ranges = ranges->outer)
1538 tree chain = ranges->handlers;
1540 /* We need to determine if the handler is part of current_subr.
1541 The are two cases: (1) The exception catch range
1542 is entirely within current_subr. In that case the handler
1543 is also part of current_subr.
1544 (2) Some of the catch range is not in current_subr.
1545 In that case, the handler is *not* part of current_subr.
1547 Figuring out which is the case is not necessarily obvious,
1548 in the presence of clever code generators (and obfuscators).
1549 We make a simplifying assumption that in case (2) we
1550 have that the current_subr is entirely within the catch range.
1551 In that case we can assume if that if a caller (the jsr) of
1552 a subroutine is within the catch range, then the handler is
1553 *not* part of the subroutine, and vice versa. */
1555 current_subr = save_current_subr;
1556 for ( ; current_subr != NULL_TREE;
1557 current_subr = LABEL_SUBR_CONTEXT (current_subr))
1559 tree return_labels = LABEL_RETURN_LABELS (current_subr);
1560 /* There could be multiple return_labels, but
1561 we only need to check one. */
1562 int return_pc = LABEL_PC (TREE_VALUE (return_labels));
1563 if (return_pc <= ranges->start_pc
1564 || return_pc > ranges->end_pc)
1568 for ( ; chain != NULL_TREE; chain = TREE_CHAIN (chain))
1570 tree handler = TREE_VALUE (chain);
1571 tree type = TREE_PURPOSE (chain);
1573 if (type == NULL_TREE) /* a finally handler */
1574 type = throwable_type_node;
1576 type_map[index] = promote_type (type);
1578 PUSH_PENDING (handler);
1581 stack_pointer = save_stack_pointer;
1582 current_subr = save_current_subr;
1583 type_map[index] = save_type;
1584 prev_eh_ranges = eh_ranges;
1591 error ("verification error at PC=%d", oldpc);
1592 if (message != NULL)
1593 error ("%s", message);
1594 error ("%s", pmessage);
1599 message = "stack overflow";
1603 message = "program counter out of range";
1607 error ("verification error at PC=%d", oldpc);
1608 error (message, index);
1612 error ("verification error at PC=%d", oldpc);
1613 error ("%s", message);