]> gcc.gnu.org Git - gcc.git/blob - gcc/java/verify.c
verify.c (verify_jvm_instructions): Allow exception handler inside code that is being...
[gcc.git] / gcc / java / verify.c
1 /* Handle verification of bytecoded methods for the GNU compiler for
2 the Java(TM) language.
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
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)
10 any later version.
11
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.
16
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.
21
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. */
25
26 #include "config.h"
27 #include "system.h"
28 #include "tree.h"
29 #include "java-tree.h"
30 #include "javaop.h"
31 #include "java-opcodes.h"
32 #include "jcf.h"
33 #include "java-except.h"
34 #include "toplev.h"
35
36 static void push_pending_label PARAMS ((tree));
37 static tree merge_types PARAMS ((tree, tree));
38 static const char *check_pending_block PARAMS ((tree));
39 static void type_stack_dup PARAMS ((int, int));
40 static int start_pc_cmp PARAMS ((const PTR, const PTR));
41 static char *pop_argument_types PARAMS ((tree));
42
43 extern int stack_pointer;
44
45 /* During verification, start of the current subroutine (jsr target). */
46 tree current_subr;
47
48 /* A list of pending blocks, chained using LABEL_PENDING_CHAIN.
49 A pending block is one that has LABEL_CHANGED set, which means
50 it requires (re-) verification. */
51 tree pending_blocks;
52
53 /* Append TARGET_LABEL to the pending_block stack unless already in it. */
54
55 static void
56 push_pending_label (target_label)
57 tree target_label;
58 {
59 if (! LABEL_CHANGED (target_label))
60 {
61 LABEL_PENDING_CHAIN (target_label) = pending_blocks;
62 pending_blocks = target_label;
63 LABEL_CHANGED (target_label) = 1;
64 }
65 }
66
67 /* Note that TARGET_LABEL is a possible successor instruction.
68 Merge the type state etc.
69 Return NULL on success, or an error message on failure. */
70
71 static const char *
72 check_pending_block (target_label)
73 tree target_label;
74 {
75 int changed = merge_type_state (target_label);
76
77 if (changed)
78 {
79 if (changed < 0)
80 return "types could not be merged";
81 push_pending_label (target_label);
82 }
83
84 if (current_subr == NULL)
85 {
86 if (LABEL_IN_SUBR (target_label))
87 return "might transfer control into subroutine";
88 }
89 else
90 {
91 if (LABEL_IN_SUBR (target_label))
92 {
93 if (LABEL_SUBR_START (target_label) != current_subr)
94 return "transfer out of subroutine";
95 }
96 else if (! LABEL_VERIFIED (target_label))
97 {
98 LABEL_IN_SUBR (target_label) = 1;
99 LABEL_SUBR_START (target_label) = current_subr;
100 }
101 else
102 return "transfer out of subroutine";
103 }
104 return NULL;
105 }
106
107 /* Count the number of nested jsr calls needed to reach LABEL. */
108
109 static int
110 subroutine_nesting (tree label)
111 {
112 int nesting = 0;
113 while (label != NULL_TREE && LABEL_IN_SUBR (label))
114 {
115 if (! LABEL_IS_SUBR_START(label))
116 label = LABEL_SUBR_START (label);
117 label = LABEL_SUBR_CONTEXT (label);
118 nesting++;
119 }
120 return nesting;
121 }
122
123 /* Return the "merged" types of TYPE1 and TYPE2.
124 If either is primitive, the other must match (after promotion to int).
125 For reference types, return the common super-class.
126 Return TYPE_UNKNOWN if the types cannot be merged. */
127
128 static tree
129 merge_types (type1, type2)
130 tree type1, type2;
131 {
132 if (type1 == type2)
133 return type1;
134 if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
135 || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
136 return TYPE_UNKNOWN;
137 if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
138 {
139 int depth1, depth2;
140 tree tt1, tt2;
141 /* ptr_type_node is only used for a null reference,
142 which is compatible with any reference type. */
143 if (type1 == ptr_type_node || type2 == object_ptr_type_node)
144 return type2;
145 if (type2 == ptr_type_node || type1 == object_ptr_type_node)
146 return type1;
147
148 tt1 = TREE_TYPE (type1);
149 tt2 = TREE_TYPE (type2);
150
151 /* If tt{1,2} haven't been properly loaded, now is a good time
152 to do it. */
153 if (!TYPE_SIZE (tt1))
154 {
155 load_class (tt1, 1);
156 safe_layout_class (tt1);
157 }
158
159 if (!TYPE_SIZE (tt2))
160 {
161 load_class (tt2, 1);
162 safe_layout_class (tt2);
163 }
164
165 if (TYPE_ARRAY_P (tt1) || TYPE_ARRAY_P (tt2))
166 {
167 if (TYPE_ARRAY_P (tt1) == TYPE_ARRAY_P (tt2))
168 {
169 tree el_type1 = TYPE_ARRAY_ELEMENT (tt1);
170 tree el_type2 = TYPE_ARRAY_ELEMENT (tt2);
171 tree el_type = NULL_TREE;
172 if (el_type1 == el_type2)
173 el_type = el_type1;
174 else if (TREE_CODE (el_type1) == POINTER_TYPE
175 && TREE_CODE (el_type2) == POINTER_TYPE)
176 el_type = merge_types (el_type1, el_type2);
177 if (el_type != NULL_TREE)
178 {
179 HOST_WIDE_INT len1 = java_array_type_length (tt1);
180 HOST_WIDE_INT len2 = java_array_type_length (tt2);
181 if (len1 != len2)
182 len1 = -1;
183 else if (el_type1 == el_type2)
184 return type1;
185 return promote_type (build_java_array_type (el_type, len1));
186 }
187 }
188 return object_ptr_type_node;
189 }
190
191 if (CLASS_INTERFACE (TYPE_NAME (tt1)))
192 {
193 /* FIXME: should see if two interfaces have a common
194 superinterface. */
195 if (CLASS_INTERFACE (TYPE_NAME (tt2)))
196 {
197 /* This is a kludge, but matches what Sun's verifier does.
198 It can be tricked, but is safe as long as type errors
199 (i.e. interface method calls) are caught at run-time. */
200 return object_ptr_type_node;
201 }
202 else
203 {
204 if (can_widen_reference_to (tt2, tt1))
205 return type1;
206 else
207 return object_ptr_type_node;
208 }
209 }
210 else if (CLASS_INTERFACE (TYPE_NAME (tt2)))
211 {
212 if (can_widen_reference_to (tt1, tt2))
213 return type2;
214 else
215 return object_ptr_type_node;
216 }
217
218 type1 = tt1;
219 type2 = tt2;
220
221 depth1 = class_depth (type1);
222 depth2 = class_depth (type2);
223 for ( ; depth1 > depth2; depth1--)
224 type1 = TYPE_BINFO_BASETYPE (type1, 0);
225 for ( ; depth2 > depth1; depth2--)
226 type2 = TYPE_BINFO_BASETYPE (type2, 0);
227 while (type1 != type2)
228 {
229 type1 = TYPE_BINFO_BASETYPE (type1, 0);
230 type2 = TYPE_BINFO_BASETYPE (type2, 0);
231 }
232 return promote_type (type1);
233 }
234 if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)
235 && TYPE_PRECISION (type1) <= 32 && TYPE_PRECISION (type2) <= 32)
236 return int_type_node;
237 return TYPE_UNKNOWN;
238 }
239
240 /* Merge the current type state with that at LABEL.
241 Return -1 the the states are incompatible (i.e. on error),
242 0 if there was no change, and 1 if there was a change. */
243
244 int
245 merge_type_state (label)
246 tree label;
247 {
248 int nlocals = DECL_MAX_LOCALS (current_function_decl);
249 int cur_length = stack_pointer + nlocals;
250 tree vec = LABEL_TYPE_STATE (label);
251 tree return_map;
252 if (vec == NULL_TREE)
253 {
254 if (!vec)
255 {
256 vec = make_tree_vec (cur_length);
257 LABEL_TYPE_STATE (label) = vec;
258 }
259 while (--cur_length >= 0)
260 TREE_VEC_ELT (vec, cur_length) = type_map [cur_length];
261 return 1;
262 }
263 else
264 {
265 int i;
266 int changed = 0;
267 if (LABEL_IS_SUBR_START (label) && LABEL_VERIFIED (label)
268 && current_subr != label)
269 return_map = LABEL_RETURN_TYPE_STATE (label);
270 else
271 return_map = NULL_TREE;
272 if (TREE_VEC_LENGTH (vec) != cur_length)
273 {
274 return -1;
275 }
276 for (i = 0; i < cur_length; i++)
277 {
278 tree old_type = TREE_VEC_ELT (vec, i);
279 tree new_type = merge_types (old_type, type_map [i]);
280 if (TREE_VEC_ELT (vec, i) != new_type)
281 {
282 /* If there has been a change, note that since we must re-verify.
283 However, if the label is the start of a subroutine,
284 we don't care about local variables that are neither
285 set nor used in the sub-routine. */
286 if (return_map == NULL_TREE || i >= nlocals
287 || TREE_VEC_ELT (return_map, i) != TYPE_UNUSED
288 || (TYPE_IS_WIDE (new_type)
289 && TREE_VEC_ELT (return_map, i+1) != TYPE_UNUSED))
290 changed = 1;
291 }
292 TREE_VEC_ELT (vec, i) = new_type;
293 if (new_type == TYPE_UNKNOWN)
294 {
295 if (i >= nlocals)
296 return -1;
297 }
298 else if (TYPE_IS_WIDE (new_type))
299 i++;
300 }
301 return changed;
302 }
303 }
304
305 /* Handle dup-like operations. */
306
307 static void
308 type_stack_dup (size, offset)
309 int size, offset;
310 {
311 tree type[4];
312 int index;
313 for (index = 0; index < size + offset; index++)
314 {
315 type[index] = stack_type_map[stack_pointer - 1];
316 if (type[index] == void_type_node)
317 {
318 index++;
319 type[index] = stack_type_map[stack_pointer - 2];
320 if (! TYPE_IS_WIDE (type[index]))
321 abort ();
322 if (index == size || index == size + offset)
323 /* Dup operation splits 64-bit number. */
324 abort ();
325 }
326 pop_type (type[index]);
327 }
328 for (index = size; --index >= 0; )
329 {
330 if (type[index] != void_type_node)
331 push_type (type[index]);
332 }
333
334 for (index = size + offset; --index >= 0; )
335 {
336 if (type[index] != void_type_node)
337 push_type (type[index]);
338 }
339 }
340
341 /* This keeps track of a start PC and corresponding initial index. */
342 struct pc_index
343 {
344 int start_pc;
345 int index;
346 };
347
348 /* A helper that is used when sorting exception ranges. */
349 static int
350 start_pc_cmp (xp, yp)
351 const PTR xp;
352 const PTR yp;
353 {
354 const struct pc_index *x = (const struct pc_index *) xp;
355 const struct pc_index *y = (const struct pc_index *) yp;
356 return x->start_pc - y->start_pc;
357 }
358
359 /* This causes the next iteration to ignore the next instruction
360 and look for some other unhandled instruction. */
361 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
362 #define INVALID_PC (-1)
363
364 #define VERIFICATION_ERROR(MESSAGE) \
365 do { message = MESSAGE; goto verify_error; } while (0)
366
367 #define VERIFICATION_ERROR_WITH_INDEX(MESSAGE) \
368 do { message = MESSAGE; goto error_with_index; } while (0)
369
370 /* Recursive helper function to pop argument types during verifiation.
371 ARG_TYPES is the list of formal parameter types.
372 Return NULL on success and a freshly malloc'd error message on failure. */
373
374 static char *
375 pop_argument_types (arg_types)
376 tree arg_types;
377 {
378 if (arg_types == end_params_node)
379 return NULL;
380 if (TREE_CODE (arg_types) == TREE_LIST)
381 {
382 char *message = pop_argument_types (TREE_CHAIN (arg_types));
383 if (message == NULL)
384 pop_type_0 (TREE_VALUE (arg_types), &message);
385 return message;
386 }
387 abort ();
388 }
389
390 #define POP_TYPE(TYPE, MESSAGE) \
391 do { pmessage = NULL; pop_type_0 (TYPE, &pmessage); \
392 if (pmessage != NULL) goto pop_type_error; \
393 } while (0)
394
395 #define POP_TYPE_CONV(TYPE, POPPED_TYPE, MESSAGE) \
396 do { pmessage = NULL; POPPED_TYPE = pop_type_0 (TYPE, &pmessage); \
397 if (pmessage != NULL) goto pop_type_error; \
398 } while (0)
399
400 #define PUSH_TYPE(TYPE) \
401 do { if (! push_type_0 (TYPE)) { goto stack_overflow; }} while (0)
402
403 #define PUSH_PENDING(LABEL) \
404 do { tree tmplab = LABEL; \
405 if ((message = check_pending_block (tmplab)) != NULL) \
406 { oldpc = LABEL_PC (tmplab); goto verify_error; }} while (0)
407
408 #ifdef __GNUC__
409 #define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
410 #else
411 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? (abort (), 0) : 1)
412 #endif
413
414 #define BCODE byte_ops
415
416 /* Verify the bytecodes of the current method.
417 Return 1 on success, 0 on failure. */
418 int
419 verify_jvm_instructions (jcf, byte_ops, length)
420 JCF* jcf;
421 const unsigned char *byte_ops;
422 long length;
423 {
424 tree label;
425 int wide = 0;
426 int op_code;
427 int PC;
428 int oldpc = 0; /* PC of start of instruction. */
429 int prevpc = 0; /* If >= 0, PC of previous instruction. */
430 const char *message = 0;
431 char *pmessage;
432 int i;
433 int index;
434 register unsigned char *p;
435 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
436 struct eh_range *eh_ranges;
437 tree return_type = TREE_TYPE (TREE_TYPE (current_function_decl));
438 struct pc_index *starts;
439 int eh_count;
440
441 jint int_value = -1;
442
443 pending_blocks = NULL_TREE;
444
445 /* Handle the exception table. */
446 method_init_exceptions ();
447 JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
448 eh_count = JCF_readu2 (jcf);
449
450 /* We read the exception handlers in order of increasing start PC.
451 To do this we first read and sort the start PCs. */
452 starts = (struct pc_index *) xmalloc (eh_count * sizeof (struct pc_index));
453 for (i = 0; i < eh_count; ++i)
454 {
455 starts[i].start_pc = GET_u2 (jcf->read_ptr + 8 * i);
456 starts[i].index = i;
457 }
458 qsort (starts, eh_count, sizeof (struct pc_index), start_pc_cmp);
459
460 for (i = 0; i < eh_count; ++i)
461 {
462 int start_pc, end_pc, handler_pc, catch_type;
463
464 p = jcf->read_ptr + 8 * starts[i].index;
465
466 start_pc = GET_u2 (p);
467 end_pc = GET_u2 (p+2);
468 handler_pc = GET_u2 (p+4);
469 catch_type = GET_u2 (p+6);
470
471 if (start_pc < 0 || start_pc >= length
472 || end_pc < 0 || end_pc > length || start_pc >= end_pc
473 || handler_pc < 0 || handler_pc >= length
474 || ! (instruction_bits [start_pc] & BCODE_INSTRUCTION_START)
475 || (end_pc < length &&
476 ! (instruction_bits [end_pc] & BCODE_INSTRUCTION_START))
477 || ! (instruction_bits [handler_pc] & BCODE_INSTRUCTION_START))
478 {
479 error ("bad pc in exception_table");
480 free (starts);
481 return 0;
482 }
483
484 if (handler_pc >= start_pc && handler_pc < end_pc)
485 warning ("exception handler inside code that is being protected");
486
487 add_handler (start_pc, end_pc,
488 lookup_label (handler_pc),
489 catch_type == 0 ? NULL_TREE
490 : get_class_constant (jcf, catch_type));
491
492 instruction_bits [handler_pc] |= BCODE_EXCEPTION_TARGET;
493 }
494
495 free (starts);
496 handle_nested_ranges ();
497
498 for (PC = 0;;)
499 {
500 tree type, tmp;
501 if (((PC != INVALID_PC
502 && instruction_bits [PC] & BCODE_TARGET) != 0)
503 || PC == 0)
504 {
505 PUSH_PENDING (lookup_label (PC));
506 INVALIDATE_PC;
507 }
508 /* Check if there are any more pending blocks in the current
509 subroutine. Because we push pending blocks in a
510 last-in-first-out order, and because we don't push anything
511 from our caller until we are done with this subroutine or
512 anything nested in it, then we are done if the top of the
513 pending_blocks stack is not in a subroutine, or it is in our
514 caller. */
515 if (current_subr
516 && PC == INVALID_PC)
517 {
518 if (pending_blocks == NULL_TREE
519 || (subroutine_nesting (pending_blocks)
520 < subroutine_nesting (current_subr)))
521 {
522 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
523 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
524 tmp = LABEL_RETURN_LABELS (current_subr);
525
526 /* FIXME: If we exit a subroutine via a throw, we might
527 have returned to an earlier caller. Obviously a
528 "ret" can only return one level, but a throw may
529 return many levels.*/
530 current_subr = LABEL_SUBR_CONTEXT (current_subr);
531
532 if (RETURN_MAP_ADJUSTED (ret_map))
533 {
534 /* Since we are done with this subroutine , set up
535 the (so far known) return address as pending -
536 with the merged type state. */
537 for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
538 {
539 tree return_label = TREE_VALUE (tmp);
540 tree return_state = LABEL_TYPE_STATE (return_label);
541 if (return_state == NULL_TREE)
542 {
543 /* This means means we had not verified the
544 subroutine earlier, so this is the first jsr to
545 call it. In this case, the type_map of the return
546 address is just the current type_map - and that
547 is handled by the following PUSH_PENDING. */
548 }
549 else
550 {
551 /* In this case we have to do a merge. But first
552 restore the type_map for unused slots to those
553 that were in effect at the jsr. */
554 for (index = size; --index >= 0; )
555 {
556 type_map[index] = TREE_VEC_ELT (ret_map, index);
557 if (type_map[index] == TYPE_UNUSED)
558 type_map[index]
559 = TREE_VEC_ELT (return_state, index);
560 }
561 }
562 PUSH_PENDING (return_label);
563 }
564 }
565 }
566 }
567 if (PC == INVALID_PC)
568 {
569 label = pending_blocks;
570 if (label == NULL_TREE)
571 break; /* We're done! */
572 pending_blocks = LABEL_PENDING_CHAIN (label);
573 LABEL_CHANGED (label) = 0;
574
575 if (LABEL_IN_SUBR (label))
576 current_subr = LABEL_SUBR_START (label);
577 else
578 current_subr = NULL_TREE;
579
580 /* Restore type_map and stack_pointer from
581 LABEL_TYPE_STATE (label), and continue
582 compiling from there. */
583 load_type_state (label);
584 PC = LABEL_PC (label);
585 }
586 else if (PC >= length)
587 VERIFICATION_ERROR ("falling through end of method");
588
589 /* fprintf (stderr, "** %d\n", PC); */
590
591 oldpc = PC;
592
593 if (!(instruction_bits [PC] & BCODE_INSTRUCTION_START) && ! wide)
594 VERIFICATION_ERROR ("PC not at instruction start");
595
596 instruction_bits[PC] |= BCODE_VERIFIED;
597
598 eh_ranges = find_handler (oldpc);
599
600 op_code = byte_ops[PC++];
601 switch (op_code)
602 {
603 int is_static, is_putting;
604 case OPCODE_nop:
605 break;
606 case OPCODE_iconst_m1:
607 case OPCODE_iconst_0: case OPCODE_iconst_1: case OPCODE_iconst_2:
608 case OPCODE_iconst_3: case OPCODE_iconst_4: case OPCODE_iconst_5:
609 i = op_code - OPCODE_iconst_0;
610 goto push_int;
611 push_int:
612 if (byte_ops[PC] == OPCODE_newarray
613 || byte_ops[PC] == OPCODE_anewarray)
614 int_value = i;
615 PUSH_TYPE (int_type_node); break;
616 case OPCODE_lconst_0: case OPCODE_lconst_1:
617 PUSH_TYPE (long_type_node); break;
618 case OPCODE_fconst_0: case OPCODE_fconst_1: case OPCODE_fconst_2:
619 PUSH_TYPE (float_type_node); break;
620 case OPCODE_dconst_0: case OPCODE_dconst_1:
621 PUSH_TYPE (double_type_node); break;
622 case OPCODE_bipush:
623 i = IMMEDIATE_s1;
624 goto push_int;
625 case OPCODE_sipush:
626 i = IMMEDIATE_s2;
627 goto push_int;
628 case OPCODE_iload: type = int_type_node; goto general_load;
629 case OPCODE_lload: type = long_type_node; goto general_load;
630 case OPCODE_fload: type = float_type_node; goto general_load;
631 case OPCODE_dload: type = double_type_node; goto general_load;
632 case OPCODE_aload: type = ptr_type_node; goto general_load;
633 general_load:
634 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
635 wide = 0;
636 goto load;
637 case OPCODE_iload_0: type = int_type_node; index = 0; goto load;
638 case OPCODE_iload_1: type = int_type_node; index = 1; goto load;
639 case OPCODE_iload_2: type = int_type_node; index = 2; goto load;
640 case OPCODE_iload_3: type = int_type_node; index = 3; goto load;
641 case OPCODE_lload_0: type = long_type_node; index = 0; goto load;
642 case OPCODE_lload_1: type = long_type_node; index = 1; goto load;
643 case OPCODE_lload_2: type = long_type_node; index = 2; goto load;
644 case OPCODE_lload_3: type = long_type_node; index = 3; goto load;
645 case OPCODE_fload_0: type = float_type_node; index = 0; goto load;
646 case OPCODE_fload_1: type = float_type_node; index = 1; goto load;
647 case OPCODE_fload_2: type = float_type_node; index = 2; goto load;
648 case OPCODE_fload_3: type = float_type_node; index = 3; goto load;
649 case OPCODE_dload_0: type = double_type_node; index = 0; goto load;
650 case OPCODE_dload_1: type = double_type_node; index = 1; goto load;
651 case OPCODE_dload_2: type = double_type_node; index = 2; goto load;
652 case OPCODE_dload_3: type = double_type_node; index = 3; goto load;
653 case OPCODE_aload_0: type = ptr_type_node; index = 0; goto load;
654 case OPCODE_aload_1: type = ptr_type_node; index = 1; goto load;
655 case OPCODE_aload_2: type = ptr_type_node; index = 2; goto load;
656 case OPCODE_aload_3: type = ptr_type_node; index = 3; goto load;
657 load:
658 if (index < 0
659 || (index + TYPE_IS_WIDE (type)
660 >= DECL_MAX_LOCALS (current_function_decl)))
661 VERIFICATION_ERROR_WITH_INDEX
662 ("invalid local variable index %d in load");
663 tmp = type_map[index];
664 if (tmp == TYPE_UNKNOWN)
665 VERIFICATION_ERROR_WITH_INDEX
666 ("loading local variable %d which has unknown type");
667 else if (tmp == TYPE_SECOND
668 || (TYPE_IS_WIDE (type)
669 && type_map[index+1] != void_type_node)
670 || (type == ptr_type_node
671 ? TREE_CODE (tmp) != POINTER_TYPE
672 : type == int_type_node
673 ? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
674 : type != tmp))
675 VERIFICATION_ERROR_WITH_INDEX
676 ("loading local variable %d which has invalid type");
677 PUSH_TYPE (tmp);
678 goto note_used;
679 case OPCODE_istore: type = int_type_node; goto general_store;
680 case OPCODE_lstore: type = long_type_node; goto general_store;
681 case OPCODE_fstore: type = float_type_node; goto general_store;
682 case OPCODE_dstore: type = double_type_node; goto general_store;
683 case OPCODE_astore: type = object_ptr_type_node; goto general_store;
684 general_store:
685 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
686 wide = 0;
687 goto store;
688 case OPCODE_istore_0: type = int_type_node; index = 0; goto store;
689 case OPCODE_istore_1: type = int_type_node; index = 1; goto store;
690 case OPCODE_istore_2: type = int_type_node; index = 2; goto store;
691 case OPCODE_istore_3: type = int_type_node; index = 3; goto store;
692 case OPCODE_lstore_0: type = long_type_node; index=0; goto store;
693 case OPCODE_lstore_1: type = long_type_node; index=1; goto store;
694 case OPCODE_lstore_2: type = long_type_node; index=2; goto store;
695 case OPCODE_lstore_3: type = long_type_node; index=3; goto store;
696 case OPCODE_fstore_0: type=float_type_node; index=0; goto store;
697 case OPCODE_fstore_1: type=float_type_node; index=1; goto store;
698 case OPCODE_fstore_2: type=float_type_node; index=2; goto store;
699 case OPCODE_fstore_3: type=float_type_node; index=3; goto store;
700 case OPCODE_dstore_0: type=double_type_node; index=0; goto store;
701 case OPCODE_dstore_1: type=double_type_node; index=1; goto store;
702 case OPCODE_dstore_2: type=double_type_node; index=2; goto store;
703 case OPCODE_dstore_3: type=double_type_node; index=3; goto store;
704 case OPCODE_astore_0: type = ptr_type_node; index = 0; goto store;
705 case OPCODE_astore_1: type = ptr_type_node; index = 1; goto store;
706 case OPCODE_astore_2: type = ptr_type_node; index = 2; goto store;
707 case OPCODE_astore_3: type = ptr_type_node; index = 3; goto store;
708 store:
709 if (index < 0
710 || (index + TYPE_IS_WIDE (type)
711 >= DECL_MAX_LOCALS (current_function_decl)))
712 {
713 VERIFICATION_ERROR_WITH_INDEX
714 ("invalid local variable index %d in store");
715 return 0;
716 }
717 POP_TYPE_CONV (type, type, NULL);
718 type_map[index] = type;
719
720 /* If local variable changed, we need to reconsider eh handlers. */
721 prev_eh_ranges = NULL_EH_RANGE;
722
723 /* Allocate decl and rtx for this variable now, so if we're not
724 optmizing, we get a temporary that survives the whole method. */
725 find_local_variable (index, type, oldpc);
726
727 if (TYPE_IS_WIDE (type))
728 type_map[index+1] = TYPE_SECOND;
729 /* ... fall through to note_used ... */
730 note_used:
731 /* For store or load, note that local variable INDEX is used.
732 This is needed to verify try-finally sub-routines. */
733 if (current_subr)
734 {
735 tree vec = LABEL_RETURN_TYPE_STATE (current_subr);
736 tree subr_vec = LABEL_TYPE_STATE (current_subr);
737 int len = 1 + TYPE_IS_WIDE (type);
738 while (--len >= 0)
739 {
740 if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)
741 TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);
742 }
743 }
744 break;
745 case OPCODE_iadd:
746 case OPCODE_iand:
747 case OPCODE_idiv:
748 case OPCODE_imul:
749 case OPCODE_ior:
750 case OPCODE_irem:
751 case OPCODE_ishl:
752 case OPCODE_ishr:
753 case OPCODE_isub:
754 case OPCODE_iushr:
755 case OPCODE_ixor:
756 type = int_type_node; goto binop;
757 case OPCODE_ineg:
758 case OPCODE_i2c:
759 case OPCODE_i2b:
760 case OPCODE_i2s:
761 type = int_type_node; goto unop;
762 case OPCODE_ladd:
763 case OPCODE_land:
764 case OPCODE_ldiv:
765 case OPCODE_lsub:
766 case OPCODE_lmul:
767 case OPCODE_lrem:
768 case OPCODE_lor:
769 case OPCODE_lxor:
770 type = long_type_node; goto binop;
771 case OPCODE_lneg:
772 type = long_type_node; goto unop;
773 case OPCODE_fadd: case OPCODE_fsub:
774 case OPCODE_fmul: case OPCODE_fdiv: case OPCODE_frem:
775 type = float_type_node; goto binop;
776 case OPCODE_fneg:
777 type = float_type_node; goto unop;
778 case OPCODE_dadd: case OPCODE_dsub:
779 case OPCODE_dmul: case OPCODE_ddiv: case OPCODE_drem:
780 type = double_type_node; goto binop;
781 case OPCODE_dneg:
782 type = double_type_node; goto unop;
783 unop:
784 pop_type (type);
785 PUSH_TYPE (type);
786 break;
787 binop:
788 pop_type (type);
789 pop_type (type);
790 PUSH_TYPE (type);
791 break;
792 case OPCODE_lshl:
793 case OPCODE_lshr:
794 case OPCODE_lushr:
795 pop_type (int_type_node);
796 pop_type (long_type_node);
797 PUSH_TYPE (long_type_node);
798 break;
799 case OPCODE_iinc:
800 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
801 PC += wide + 1;
802 wide = 0;
803 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))
804 VERIFICATION_ERROR ("invalid local variable index in iinc");
805 tmp = type_map[index];
806 if (tmp == NULL_TREE
807 || ! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
808 VERIFICATION_ERROR ("invalid local variable type in iinc");
809 break;
810 case OPCODE_i2l:
811 pop_type (int_type_node); PUSH_TYPE (long_type_node); break;
812 case OPCODE_i2f:
813 pop_type (int_type_node); PUSH_TYPE (float_type_node); break;
814 case OPCODE_i2d:
815 pop_type (int_type_node); PUSH_TYPE (double_type_node); break;
816 case OPCODE_l2i:
817 pop_type (long_type_node); PUSH_TYPE (int_type_node); break;
818 case OPCODE_l2f:
819 pop_type (long_type_node); PUSH_TYPE (float_type_node); break;
820 case OPCODE_l2d:
821 pop_type (long_type_node); PUSH_TYPE (double_type_node); break;
822 case OPCODE_f2i:
823 pop_type (float_type_node); PUSH_TYPE (int_type_node); break;
824 case OPCODE_f2l:
825 pop_type (float_type_node); PUSH_TYPE (long_type_node); break;
826 case OPCODE_f2d:
827 pop_type (float_type_node); PUSH_TYPE (double_type_node); break;
828 case OPCODE_d2i:
829 pop_type (double_type_node); PUSH_TYPE (int_type_node); break;
830 case OPCODE_d2l:
831 pop_type (double_type_node); PUSH_TYPE (long_type_node); break;
832 case OPCODE_d2f:
833 pop_type (double_type_node); PUSH_TYPE (float_type_node); break;
834 case OPCODE_lcmp:
835 type = long_type_node; goto compare;
836 case OPCODE_fcmpl:
837 case OPCODE_fcmpg:
838 type = float_type_node; goto compare;
839 case OPCODE_dcmpl:
840 case OPCODE_dcmpg:
841 type = double_type_node; goto compare;
842 compare:
843 pop_type (type); pop_type (type);
844 PUSH_TYPE (int_type_node); break;
845 case OPCODE_ifeq:
846 case OPCODE_ifne:
847 case OPCODE_iflt:
848 case OPCODE_ifge:
849 case OPCODE_ifgt:
850 case OPCODE_ifle:
851 pop_type (int_type_node); goto cond;
852 case OPCODE_ifnull:
853 case OPCODE_ifnonnull:
854 pop_type (ptr_type_node ); goto cond;
855 case OPCODE_if_icmpeq:
856 case OPCODE_if_icmpne:
857 case OPCODE_if_icmplt:
858 case OPCODE_if_icmpge:
859 case OPCODE_if_icmpgt:
860 case OPCODE_if_icmple:
861 pop_type (int_type_node); pop_type (int_type_node); goto cond;
862 case OPCODE_if_acmpeq:
863 case OPCODE_if_acmpne:
864 pop_type (object_ptr_type_node); pop_type (object_ptr_type_node);
865 goto cond;
866 cond:
867 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
868 break;
869 case OPCODE_goto:
870 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
871 INVALIDATE_PC;
872 break;
873 case OPCODE_wide:
874 switch (byte_ops[PC])
875 {
876 case OPCODE_iload: case OPCODE_lload:
877 case OPCODE_fload: case OPCODE_dload: case OPCODE_aload:
878 case OPCODE_istore: case OPCODE_lstore:
879 case OPCODE_fstore: case OPCODE_dstore: case OPCODE_astore:
880 case OPCODE_iinc:
881 case OPCODE_ret:
882 wide = 1;
883 break;
884 default:
885 VERIFICATION_ERROR ("invalid use of wide instruction");
886 }
887 break;
888 case OPCODE_return: type = void_type_node; goto ret;
889 case OPCODE_ireturn:
890 if ((TREE_CODE (return_type) == BOOLEAN_TYPE
891 || TREE_CODE (return_type) == CHAR_TYPE
892 || TREE_CODE (return_type) == INTEGER_TYPE)
893 && TYPE_PRECISION (return_type) <= 32)
894 type = return_type;
895 else
896 type = NULL_TREE;
897 goto ret;
898 case OPCODE_lreturn: type = long_type_node; goto ret;
899 case OPCODE_freturn: type = float_type_node; goto ret;
900 case OPCODE_dreturn: type = double_type_node; goto ret;
901 case OPCODE_areturn:
902 if (TREE_CODE (return_type) == POINTER_TYPE)
903 type = return_type;
904 else
905 type = NULL_TREE;
906 goto ret;
907 ret:
908 if (type != return_type)
909 VERIFICATION_ERROR ("incorrect ?return opcode");
910 if (type != void_type_node)
911 POP_TYPE(type, "return value has wrong type");
912 INVALIDATE_PC;
913 break;
914 case OPCODE_getstatic: is_putting = 0; is_static = 1; goto field;
915 case OPCODE_putstatic: is_putting = 1; is_static = 1; goto field;
916 case OPCODE_getfield: is_putting = 0; is_static = 0; goto field;
917 case OPCODE_putfield: is_putting = 1; is_static = 0; goto field;
918 field:
919 {
920 tree field_signature, field_type;
921 index = IMMEDIATE_u2;
922 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
923 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d");
924 if (JPOOL_TAG (current_jcf, index) != CONSTANT_Fieldref)
925 VERIFICATION_ERROR
926 ("field instruction does not reference a Fieldref");
927 field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
928 field_type = get_type_from_signature (field_signature);
929 if (is_putting)
930 POP_TYPE (field_type, "incorrect type for field");
931 if (! is_static)
932 {
933 int clindex = COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
934 index);
935 tree self_type = get_class_constant (current_jcf, clindex);
936 /* Defer actual checking until next pass. */
937 POP_TYPE(self_type, "incorrect type for field reference");
938 }
939 if (! is_putting)
940 PUSH_TYPE (field_type);
941 break;
942 }
943 case OPCODE_new:
944 PUSH_TYPE (get_class_constant (jcf, IMMEDIATE_u2));
945 break;
946 case OPCODE_dup: wide = 1; index = 0; goto dup;
947 case OPCODE_dup_x1: wide = 1; index = 1; goto dup;
948 case OPCODE_dup_x2: wide = 1; index = 2; goto dup;
949 case OPCODE_dup2: wide = 2; index = 0; goto dup;
950 case OPCODE_dup2_x1: wide = 2; index = 1; goto dup;
951 case OPCODE_dup2_x2: wide = 2; index = 2; goto dup;
952 dup:
953 if (wide + index > stack_pointer)
954 VERIFICATION_ERROR ("stack underflow - dup* operation");
955 type_stack_dup (wide, index);
956 wide = 0;
957 break;
958 case OPCODE_pop: index = 1; goto pop;
959 case OPCODE_pop2: index = 2; goto pop;
960 pop:
961 if (stack_pointer < index)
962 VERIFICATION_ERROR ("stack underflow");
963 stack_pointer -= index;
964 break;
965 case OPCODE_swap:
966 if (stack_pointer < 2)
967 VERIFICATION_ERROR ("stack underflow (in swap)");
968 else
969 {
970 tree type1 = stack_type_map[stack_pointer - 1];
971 tree type2 = stack_type_map[stack_pointer - 2];
972 if (type1 == void_type_node || type2 == void_type_node)
973 VERIFICATION_ERROR ("verifier (swap): double or long value");
974 stack_type_map[stack_pointer - 2] = type1;
975 stack_type_map[stack_pointer - 1] = type2;
976 }
977 break;
978 case OPCODE_ldc: index = IMMEDIATE_u1; goto ldc;
979 case OPCODE_ldc2_w:
980 case OPCODE_ldc_w:
981 index = IMMEDIATE_u2; goto ldc;
982 ldc:
983 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
984 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d in ldc");
985 int_value = -1;
986 switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)
987 {
988 case CONSTANT_Integer: type = int_type_node; goto check_ldc;
989 case CONSTANT_Float: type = float_type_node; goto check_ldc;
990 case CONSTANT_String: type = string_type_node; goto check_ldc;
991 case CONSTANT_Long: type = long_type_node; goto check_ldc;
992 case CONSTANT_Double: type = double_type_node; goto check_ldc;
993 check_ldc:
994 if (TYPE_IS_WIDE (type) == (op_code == OPCODE_ldc2_w))
995 break;
996 /* ... else fall through ... */
997 default:
998 VERIFICATION_ERROR ("bad constant pool tag in ldc");
999 }
1000 if (type == int_type_node)
1001 {
1002 i = TREE_INT_CST_LOW (get_constant (current_jcf, index));
1003 goto push_int;
1004 }
1005 PUSH_TYPE (type);
1006 break;
1007
1008 case OPCODE_invokevirtual:
1009 case OPCODE_invokespecial:
1010 case OPCODE_invokestatic:
1011 case OPCODE_invokeinterface:
1012 {
1013 tree sig, method_name, method_type, self_type;
1014 int self_is_interface, tag;
1015 index = IMMEDIATE_u2;
1016 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
1017 VERIFICATION_ERROR_WITH_INDEX
1018 ("bad constant pool index %d for invoke");
1019 tag = JPOOL_TAG (current_jcf, index);
1020 if (op_code == OPCODE_invokeinterface)
1021 {
1022 if (tag != CONSTANT_InterfaceMethodref)
1023 VERIFICATION_ERROR
1024 ("invokeinterface does not reference an InterfaceMethodref");
1025 }
1026 else
1027 {
1028 if (tag != CONSTANT_Methodref)
1029 VERIFICATION_ERROR ("invoke does not reference a Methodref");
1030 }
1031 sig = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
1032 self_type = get_class_constant
1033 (current_jcf, COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
1034 index));
1035 if (! CLASS_LOADED_P (self_type))
1036 load_class (self_type, 1);
1037 self_is_interface = CLASS_INTERFACE (TYPE_NAME (self_type));
1038 method_name = COMPONENT_REF_NAME (&current_jcf->cpool, index);
1039 method_type = parse_signature_string (IDENTIFIER_POINTER (sig),
1040 IDENTIFIER_LENGTH (sig));
1041 if (TREE_CODE (method_type) != FUNCTION_TYPE)
1042 VERIFICATION_ERROR ("bad method signature");
1043 pmessage = pop_argument_types (TYPE_ARG_TYPES (method_type));
1044 if (pmessage != NULL)
1045 {
1046 message = "invalid argument type";
1047 goto pop_type_error;
1048 }
1049
1050 /* Can't invoke <clinit> */
1051 if (ID_CLINIT_P (method_name))
1052 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
1053 /* Apart invokespecial, can't invoke <init> */
1054 if (op_code != OPCODE_invokespecial && ID_INIT_P (method_name))
1055 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
1056
1057 if (op_code != OPCODE_invokestatic)
1058 POP_TYPE (self_type,
1059 "stack type not subclass of invoked method's class");
1060
1061 switch (op_code)
1062 {
1063 case OPCODE_invokeinterface:
1064 {
1065 int nargs = IMMEDIATE_u1;
1066 int notZero = IMMEDIATE_u1;
1067
1068 if (!nargs || notZero)
1069 VERIFICATION_ERROR
1070 ("invalid argument number in invokeinterface");
1071 /* If we verify/resolve the constant pool, as we should,
1072 this test (and the one just following) are redundant. */
1073 if (! self_is_interface)
1074 VERIFICATION_ERROR ("invokeinterface calls method not in interface");
1075 break;
1076 default:
1077 if (self_is_interface)
1078 VERIFICATION_ERROR ("method in interface called");
1079 }
1080 }
1081
1082 if (TREE_TYPE (method_type) != void_type_node)
1083 PUSH_TYPE (TREE_TYPE (method_type));
1084 break;
1085 }
1086
1087 case OPCODE_arraylength:
1088 /* Type checking actually made during code generation */
1089 pop_type( ptr_type_node );
1090 PUSH_TYPE( int_type_node );
1091 break;
1092
1093 /* Q&D verification *or* more checking done during code generation
1094 for byte/boolean/char/short, the value popped is a int coerced
1095 into the right type before being stored. */
1096 case OPCODE_iastore: type = int_type_node; goto astore;
1097 case OPCODE_lastore: type = long_type_node; goto astore;
1098 case OPCODE_fastore: type = float_type_node; goto astore;
1099 case OPCODE_dastore: type = double_type_node; goto astore;
1100 case OPCODE_aastore: type = ptr_type_node; goto astore;
1101 case OPCODE_bastore: type = int_type_node; goto astore;
1102 case OPCODE_castore: type = int_type_node; goto astore;
1103 case OPCODE_sastore: type = int_type_node; goto astore;
1104 astore:
1105 /* FIXME - need better verification here */
1106 pop_type (type); /* new value */
1107 pop_type (int_type_node); /* index */
1108 pop_type (ptr_type_node); /* array */
1109 break;
1110
1111 /* Q&D verification *or* more checking done during code generation
1112 for byte/boolean/char/short, the value pushed is a int. */
1113 case OPCODE_iaload: type = int_type_node; goto aload;
1114 case OPCODE_laload: type = long_type_node; goto aload;
1115 case OPCODE_faload: type = float_type_node; goto aload;
1116 case OPCODE_daload: type = double_type_node; goto aload;
1117 case OPCODE_aaload: type = ptr_type_node; goto aload;
1118 case OPCODE_baload: type = promote_type (byte_type_node); goto aload;
1119 case OPCODE_caload: type = promote_type (char_type_node); goto aload;
1120 case OPCODE_saload: type = promote_type (short_type_node); goto aload;
1121 aload:
1122 pop_type (int_type_node);
1123 tmp = pop_type (ptr_type_node);
1124 if (is_array_type_p (tmp))
1125 type = TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp));
1126 else if (tmp != TYPE_NULL)
1127 VERIFICATION_ERROR ("array load from non-array type");
1128 PUSH_TYPE (type);
1129 break;
1130
1131 case OPCODE_anewarray:
1132 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1133 type = promote_type (type);
1134 goto newarray;
1135
1136 case OPCODE_newarray:
1137 index = IMMEDIATE_u1;
1138 type = decode_newarray_type (index);
1139 if (type == NULL_TREE)
1140 VERIFICATION_ERROR ("invalid type code in newarray opcode");
1141 goto newarray;
1142
1143 newarray:
1144 if (int_value >= 0 && prevpc >= 0)
1145 {
1146 /* If previous instruction pushed int constant,
1147 we want to use it. */
1148 switch (byte_ops[prevpc])
1149 {
1150 case OPCODE_iconst_0: case OPCODE_iconst_1:
1151 case OPCODE_iconst_2: case OPCODE_iconst_3:
1152 case OPCODE_iconst_4: case OPCODE_iconst_5:
1153 case OPCODE_bipush: case OPCODE_sipush:
1154 case OPCODE_ldc: case OPCODE_ldc_w:
1155 break;
1156 default:
1157 int_value = -1;
1158 }
1159 }
1160 else
1161 int_value = -1;
1162 type = build_java_array_type (type, int_value);
1163 pop_type (int_type_node);
1164 PUSH_TYPE (type);
1165 break;
1166
1167 case OPCODE_multianewarray:
1168 {
1169 int ndim, i;
1170 index = IMMEDIATE_u2;
1171 ndim = IMMEDIATE_u1;
1172
1173 if( ndim < 1 )
1174 VERIFICATION_ERROR ("number of dimension lower that 1 in multianewarray" );
1175
1176 for( i = 0; i < ndim; i++ )
1177 pop_type (int_type_node);
1178 PUSH_TYPE (get_class_constant (current_jcf, index));
1179 break;
1180 }
1181
1182 case OPCODE_aconst_null:
1183 PUSH_TYPE (ptr_type_node);
1184 break;
1185
1186 case OPCODE_athrow:
1187 /* FIXME: athrow also empties the stack. */
1188 POP_TYPE (throwable_type_node, "missing throwable at athrow" );
1189 INVALIDATE_PC;
1190 break;
1191
1192 case OPCODE_checkcast:
1193 POP_TYPE (object_ptr_type_node,
1194 "checkcast operand is not a pointer");
1195 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1196 PUSH_TYPE (type);
1197 break;
1198 case OPCODE_instanceof:
1199 POP_TYPE (object_ptr_type_node,
1200 "instanceof operand is not a pointer");
1201 get_class_constant (current_jcf, IMMEDIATE_u2);
1202 PUSH_TYPE (int_type_node);
1203 break;
1204
1205 case OPCODE_tableswitch:
1206 {
1207 jint low, high;
1208
1209 POP_TYPE (int_type_node, "missing int for tableswitch");
1210 while (PC%4)
1211 {
1212 if (byte_ops[PC++])
1213 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
1214 }
1215 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1216 low = IMMEDIATE_s4;
1217 high = IMMEDIATE_s4;
1218
1219 if (low > high)
1220 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
1221
1222 while (low++ <= high)
1223 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1224 INVALIDATE_PC;
1225 break;
1226 }
1227
1228 case OPCODE_lookupswitch:
1229 {
1230 jint npairs, last = 0, not_registered = 1;
1231
1232 POP_TYPE (int_type_node, "missing int for lookupswitch");
1233 while (PC%4)
1234 {
1235 if (byte_ops[PC++])
1236 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
1237 }
1238
1239 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1240 npairs = IMMEDIATE_s4;
1241
1242 if (npairs < 0)
1243 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1244
1245 while (npairs--)
1246 {
1247 int match = IMMEDIATE_s4;
1248 if (not_registered)
1249 not_registered = 0;
1250 else if (last >= match)
1251 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1252
1253 last = match;
1254 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1255 }
1256 INVALIDATE_PC;
1257 break;
1258 }
1259
1260 case OPCODE_monitorenter:
1261 /* fall thru */
1262 case OPCODE_monitorexit:
1263 pop_type (ptr_type_node);
1264 break;
1265
1266 case OPCODE_goto_w:
1267 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1268 INVALIDATE_PC;
1269 break;
1270
1271 case OPCODE_jsr:
1272 {
1273 tree target = lookup_label (oldpc + IMMEDIATE_s2);
1274 tree return_label = lookup_label (PC);
1275 PUSH_TYPE (return_address_type_node);
1276 /* The return label chain will be null if this is the first
1277 time we've seen this jsr target. */
1278 if (LABEL_RETURN_LABEL (target) == NULL_TREE)
1279 {
1280 tree return_type_map;
1281 int nlocals = DECL_MAX_LOCALS (current_function_decl);
1282 index = nlocals + DECL_MAX_STACK (current_function_decl);
1283 return_type_map = make_tree_vec (index);
1284 while (index > nlocals)
1285 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
1286 while (index > 0)
1287 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
1288 LABEL_RETURN_LABEL (target)
1289 = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
1290 LABEL_PC (LABEL_RETURN_LABEL (target)) = -1;
1291 LABEL_RETURN_TYPE_STATE (target) = return_type_map;
1292 LABEL_IS_SUBR_START (target) = 1;
1293 LABEL_IN_SUBR (target) = 1;
1294 LABEL_SUBR_START (target) = target;
1295 LABEL_SUBR_CONTEXT (target) = current_subr;
1296 }
1297 else if (! LABEL_IS_SUBR_START (target)
1298 || LABEL_SUBR_CONTEXT (target) != current_subr)
1299 VERIFICATION_ERROR ("label part of different subroutines");
1300
1301 i = merge_type_state (target);
1302 if (i != 0)
1303 {
1304 if (i < 0)
1305 VERIFICATION_ERROR ("types could not be merged at jsr");
1306 push_pending_label (target);
1307 }
1308 current_subr = target;
1309
1310 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1311 if (! value_member (return_label, LABEL_RETURN_LABELS (target)))
1312 {
1313 LABEL_RETURN_LABELS (target)
1314 = tree_cons (NULL_TREE, return_label,
1315 LABEL_RETURN_LABELS (target));
1316 }
1317
1318 if (LABEL_VERIFIED (target))
1319 {
1320 tree return_map = LABEL_RETURN_TYPE_STATE (target);
1321 int len = TREE_VEC_LENGTH (return_map);
1322 stack_pointer = len - DECL_MAX_LOCALS (current_function_decl);
1323 while (--len >= 0)
1324 {
1325 if (TREE_VEC_ELT (return_map, len) != TYPE_UNUSED)
1326 type_map[len] = TREE_VEC_ELT (return_map, len);
1327 }
1328 current_subr = LABEL_SUBR_CONTEXT (target);
1329 PUSH_PENDING (return_label);
1330 }
1331
1332 INVALIDATE_PC;
1333 }
1334 break;
1335 case OPCODE_ret:
1336 if (current_subr == NULL)
1337 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1338 else
1339 {
1340 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
1341 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
1342 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
1343 wide = 0;
1344 INVALIDATE_PC;
1345 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl)
1346 || type_map[index] != TYPE_RETURN_ADDR)
1347 VERIFICATION_ERROR ("invalid ret index");
1348
1349 /* The next chunk of code is similar to an inlined version of
1350 * merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1351 * The main differences are that LABEL_RETURN_LABEL is
1352 * pre-allocated by the jsr (but we don't know the size then);
1353 * and that we have to handle TYPE_UNUSED. */
1354
1355 if (! RETURN_MAP_ADJUSTED (ret_map))
1356 { /* First return from this subroutine - fix stack pointer. */
1357 TREE_VEC_LENGTH (ret_map) = size;
1358 for (index = size; --index >= 0; )
1359 {
1360 if (TREE_VEC_ELT (ret_map, index) != TYPE_UNUSED)
1361 TREE_VEC_ELT (ret_map, index) = type_map[index];
1362 }
1363 RETURN_MAP_ADJUSTED (ret_map) = 1;
1364 }
1365 else
1366 {
1367 if (TREE_VEC_LENGTH (ret_map) != size)
1368 VERIFICATION_ERROR ("inconsistent stack size on ret");
1369 for (index = 0; index < size; index++)
1370 {
1371 tree type = TREE_VEC_ELT (ret_map, index);
1372 if (type != TYPE_UNUSED)
1373 {
1374 type = merge_types (type, type_map [index]);
1375 TREE_VEC_ELT (ret_map, index) = type;
1376 if (type == TYPE_UNKNOWN)
1377 {
1378 if (index >= size - stack_pointer)
1379 VERIFICATION_ERROR
1380 ("inconsistent types on ret from jsr");
1381 }
1382 else if (TYPE_IS_WIDE (type))
1383 index++;
1384 }
1385 }
1386 }
1387
1388
1389 }
1390 break;
1391 case OPCODE_jsr_w:
1392 case OPCODE_ret_w:
1393 default:
1394 error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
1395 return 0;
1396 }
1397
1398 prevpc = oldpc;
1399
1400 /* The following test is true if we have entered or exited an exception
1401 handler range *or* we have done a store to a local variable.
1402 In either case we need to consider any exception handlers that
1403 might "follow" this instruction. */
1404
1405 if (eh_ranges != prev_eh_ranges)
1406 {
1407 int save_stack_pointer = stack_pointer;
1408 int index = DECL_MAX_LOCALS (current_function_decl);
1409 tree save_type = type_map[index];
1410 tree save_current_subr = current_subr;
1411 struct eh_range *ranges = find_handler (oldpc);
1412 stack_pointer = 1;
1413 for (; ranges != NULL_EH_RANGE; ranges = ranges->outer)
1414 {
1415 tree chain = ranges->handlers;
1416
1417 /* We need to determine if the handler is part of current_subr.
1418 The are two cases: (1) The exception catch range
1419 is entirely within current_subr. In that case the handler
1420 is also part of current_subr.
1421 (2) Some of the catch range is not in current_subr.
1422 In that case, the handler is *not* part of current_subr.
1423
1424 Figuring out which is the case is not necessarily obvious,
1425 in the presence of clever code generators (and obfuscators).
1426 We make a simplifying assumption that in case (2) we
1427 have that the current_subr is entirely within the catch range.
1428 In that case we can assume if that if a caller (the jsr) of
1429 a subroutine is within the catch range, then the handler is
1430 *not* part of the subroutine, and vice versa. */
1431
1432 current_subr = save_current_subr;
1433 for ( ; current_subr != NULL_TREE;
1434 current_subr = LABEL_SUBR_CONTEXT (current_subr))
1435 {
1436 tree return_labels = LABEL_RETURN_LABELS (current_subr);
1437 /* There could be multiple return_labels, but
1438 we only need to check one. */
1439 int return_pc = LABEL_PC (TREE_VALUE (return_labels));
1440 if (return_pc <= ranges->start_pc
1441 || return_pc > ranges->end_pc)
1442 break;
1443 }
1444
1445 for ( ; chain != NULL_TREE; chain = TREE_CHAIN (chain))
1446 {
1447 tree handler = TREE_VALUE (chain);
1448 tree type = TREE_PURPOSE (chain);
1449 if (type == NULL_TREE) /* a finally handler */
1450 type = throwable_type_node;
1451 type_map[index] = promote_type (type);
1452
1453 PUSH_PENDING (handler);
1454 }
1455 }
1456 stack_pointer = save_stack_pointer;
1457 current_subr = save_current_subr;
1458 type_map[index] = save_type;
1459 prev_eh_ranges = eh_ranges;
1460 }
1461 }
1462 return 1;
1463 pop_type_error:
1464 error ("verification error at PC=%d", oldpc);
1465 if (message != NULL)
1466 error ("%s", message);
1467 error ("%s", pmessage);
1468 free (pmessage);
1469 return 0;
1470 stack_overflow:
1471 message = "stack overflow";
1472 goto verify_error;
1473 bad_pc:
1474 message = "program counter out of range";
1475 goto verify_error;
1476 error_with_index:
1477 error ("verification error at PC=%d", oldpc);
1478 error (message, index);
1479 return 0;
1480 verify_error:
1481 error ("verification error at PC=%d", oldpc);
1482 error ("%s", message);
1483 return 0;
1484 }
This page took 0.10549 seconds and 5 git commands to generate.