]>
gcc.gnu.org Git - gcc.git/blob - gcc/java/verify.c
1 /* Handle verification of bytecoded methods for the GNU compiler for
3 Copyright (C) 1997, 1998, 1999 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
;
154 if (CLASS_INTERFACE (TYPE_NAME (tt1
)))
156 if (CLASS_INTERFACE (TYPE_NAME (tt2
)))
158 /* This is a kludge, but matches what Sun's verifier does.
159 It can be tricked, but is safe as long as type errors
160 (i.e. interface method calls) are caught at run-time. */
161 return object_ptr_type_node
;
165 if (can_widen_reference_to (tt2
, tt1
))
171 else if (CLASS_INTERFACE (TYPE_NAME (tt2
)))
173 if (can_widen_reference_to (tt1
, tt2
))
182 depth1
= class_depth (type1
);
183 depth2
= class_depth (type2
);
184 for ( ; depth1
> depth2
; depth1
--)
185 type1
= TYPE_BINFO_BASETYPE (type1
, 0);
186 for ( ; depth2
> depth1
; depth2
--)
187 type2
= TYPE_BINFO_BASETYPE (type2
, 0);
188 while (type1
!= type2
)
190 type1
= TYPE_BINFO_BASETYPE (type1
, 0);
191 type2
= TYPE_BINFO_BASETYPE (type2
, 0);
193 return promote_type (type1
);
195 if (INTEGRAL_TYPE_P (type1
) && INTEGRAL_TYPE_P (type2
)
196 && TYPE_PRECISION (type1
) <= 32 && TYPE_PRECISION (type2
) <= 32)
197 return int_type_node
;
201 /* Merge the current type state with that at LABEL.
202 Return -1 the the states are incompatible (i.e. on error),
203 0 if there was no change, and 1 if there was a change. */
206 merge_type_state (label
)
209 int nlocals
= DECL_MAX_LOCALS(current_function_decl
);
210 int cur_length
= stack_pointer
+ nlocals
;
211 tree vec
= LABEL_TYPE_STATE (label
);
213 if (vec
== NULL_TREE
)
215 vec
= make_tree_vec (cur_length
);
216 LABEL_TYPE_STATE (label
) = vec
;
217 while (--cur_length
>= 0)
218 TREE_VEC_ELT (vec
, cur_length
) = type_map
[cur_length
];
225 if (LABEL_IS_SUBR_START (label
) && LABEL_VERIFIED (label
)
226 && current_subr
!= label
)
227 return_map
= LABEL_RETURN_TYPE_STATE (label
);
229 return_map
= NULL_TREE
;
230 if (TREE_VEC_LENGTH (vec
) != cur_length
)
234 for (i
= 0; i
< cur_length
; i
++)
236 tree old_type
= TREE_VEC_ELT (vec
, i
);
237 tree new_type
= merge_types (old_type
, type_map
[i
]);
238 if (TREE_VEC_ELT (vec
, i
) != new_type
)
240 /* If there has been a change, note that since we must re-verify.
241 However, if the label is the start of a subroutine,
242 we don't care about local variables that are neither
243 set nor used in the sub-routine. */
244 if (return_map
== NULL_TREE
|| i
>= nlocals
245 || TREE_VEC_ELT (return_map
, i
) != TYPE_UNUSED
246 || (TYPE_IS_WIDE (new_type
)
247 && TREE_VEC_ELT (return_map
, i
+1) != TYPE_UNUSED
))
250 TREE_VEC_ELT (vec
, i
) = new_type
;
251 if (new_type
== TYPE_UNKNOWN
)
256 else if (TYPE_IS_WIDE (new_type
))
263 /* Handle dup-like operations. */
266 type_stack_dup (size
, offset
)
271 if (size
+ offset
> stack_pointer
)
272 error ("stack underflow - dup* operation");
273 for (index
= 0; index
< size
+ offset
; index
++)
275 type
[index
] = stack_type_map
[stack_pointer
- 1];
276 if (type
[index
] == void_type_node
)
279 type
[index
] = stack_type_map
[stack_pointer
- 2];
280 if (! TYPE_IS_WIDE (type
[index
]))
281 fatal ("internal error - dup operation");
282 if (index
== size
|| index
== size
+ offset
)
283 fatal ("dup operation splits 64-bit number");
285 pop_type (type
[index
]);
287 for (index
= size
; --index
>= 0; )
289 if (type
[index
] != void_type_node
)
290 push_type (type
[index
]);
293 for (index
= size
+ offset
; --index
>= 0; )
295 if (type
[index
] != void_type_node
)
296 push_type (type
[index
]);
300 /* This causes the next iteration to ignore the next instruction
301 and look for some other unhandled instruction. */
302 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
303 #define INVALID_PC (-1)
305 #define VERIFICATION_ERROR(MESSAGE) \
306 do { message = MESSAGE; goto verify_error; } while (0)
308 #define PUSH_PENDING(LABEL) \
309 do { if ((message = check_pending_block (LABEL)) != NULL) \
310 goto verify_error; } while (0)
313 #define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; 1;})
315 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? \
316 (fatal("Bad byte codes.\n"), 0) : 1)
319 #define BCODE byte_ops
321 /* Verify the bytecodes of the current method.
322 Return 1 on sucess, 0 on failure. */
324 verify_jvm_instructions (jcf
, byte_ops
, length
)
326 unsigned char* byte_ops
;
333 int oldpc
; /* PC of start of instruction. */
334 int prevpc
; /* If >= 0, PC of previous instruction. */
337 register unsigned char *p
;
338 struct eh_range
*prev_eh_ranges
= NULL_EH_RANGE
;
339 struct eh_range
*eh_ranges
;
343 pending_blocks
= NULL_TREE
;
345 /* Handle the exception table. */
346 method_init_exceptions ();
347 JCF_SEEK (jcf
, DECL_CODE_OFFSET (current_function_decl
) + length
);
348 i
= JCF_readu2 (jcf
);
350 /* We read the exception backwards. */
351 p
= jcf
->read_ptr
+ 8 * i
;
354 int start_pc
= GET_u2 (p
-8);
355 int end_pc
= GET_u2 (p
-6);
356 int handler_pc
= GET_u2 (p
-4);
357 int catch_type
= GET_u2 (p
-2);
360 if (start_pc
< 0 || start_pc
>= length
361 || end_pc
< 0 || end_pc
> length
|| start_pc
>= end_pc
362 || handler_pc
< 0 || handler_pc
>= length
363 || (handler_pc
>= start_pc
&& handler_pc
< end_pc
)
364 || ! (instruction_bits
[start_pc
] & BCODE_INSTRUCTION_START
)
365 || ! (instruction_bits
[end_pc
] & BCODE_INSTRUCTION_START
)
366 || ! (instruction_bits
[handler_pc
] & BCODE_INSTRUCTION_START
))
368 error ("bad pc in exception_table");
372 if (! add_handler (start_pc
, end_pc
,
373 lookup_label (handler_pc
),
374 catch_type
== 0 ? NULL_TREE
375 : get_class_constant (jcf
, catch_type
)))
377 error ("overlapping exception ranges are not supported");
381 instruction_bits
[handler_pc
] |= BCODE_EXCEPTION_TARGET
;
388 if (((PC
!= INVALID_PC
389 && instruction_bits
[PC
] & BCODE_TARGET
) != 0)
392 PUSH_PENDING (lookup_label (PC
));
395 if (PC
== INVALID_PC
)
397 label
= pending_blocks
;
398 if (label
== NULL_TREE
)
399 break; /* We're done! */
400 pending_blocks
= LABEL_PENDING_CHAIN (label
);
401 LABEL_CHANGED (label
) = 0;
403 if (LABEL_IN_SUBR (label
))
404 current_subr
= LABEL_SUBR_START (label
);
406 current_subr
= NULL_TREE
;
408 /* Restore type_map and stack_pointer from
409 LABEL_TYPE_STATE (label), and continue
410 compiling from there. */
411 load_type_state (label
);
412 PC
= LABEL_PC (label
);
414 else if (PC
>= length
)
415 VERIFICATION_ERROR ("falling through end of method");
419 if (!(instruction_bits
[PC
] & BCODE_INSTRUCTION_START
) && ! wide
)
420 VERIFICATION_ERROR ("PC not at instruction start");
422 instruction_bits
[PC
] |= BCODE_VERIFIED
;
424 eh_ranges
= find_handler (oldpc
);
426 op_code
= byte_ops
[PC
++];
429 int is_static
, is_putting
;
432 case OPCODE_iconst_m1
:
433 case OPCODE_iconst_0
: case OPCODE_iconst_1
: case OPCODE_iconst_2
:
434 case OPCODE_iconst_3
: case OPCODE_iconst_4
: case OPCODE_iconst_5
:
435 i
= op_code
- OPCODE_iconst_0
;
438 if (byte_ops
[PC
] == OPCODE_newarray
439 || byte_ops
[PC
] == OPCODE_newarray
)
441 push_type (int_type_node
); break;
442 case OPCODE_lconst_0
: case OPCODE_lconst_1
:
443 push_type (long_type_node
); break;
444 case OPCODE_fconst_0
: case OPCODE_fconst_1
: case OPCODE_fconst_2
:
445 push_type (float_type_node
); break;
446 case OPCODE_dconst_0
: case OPCODE_dconst_1
:
447 push_type (double_type_node
); break;
454 case OPCODE_iload
: type
= int_type_node
; goto general_load
;
455 case OPCODE_lload
: type
= long_type_node
; goto general_load
;
456 case OPCODE_fload
: type
= float_type_node
; goto general_load
;
457 case OPCODE_dload
: type
= double_type_node
; goto general_load
;
458 case OPCODE_aload
: type
= ptr_type_node
; goto general_load
;
460 index
= wide
? IMMEDIATE_u2
: IMMEDIATE_u1
;
463 case OPCODE_iload_0
: type
= int_type_node
; index
= 0; goto load
;
464 case OPCODE_iload_1
: type
= int_type_node
; index
= 1; goto load
;
465 case OPCODE_iload_2
: type
= int_type_node
; index
= 2; goto load
;
466 case OPCODE_iload_3
: type
= int_type_node
; index
= 3; goto load
;
467 case OPCODE_lload_0
: type
= long_type_node
; index
= 0; goto load
;
468 case OPCODE_lload_1
: type
= long_type_node
; index
= 1; goto load
;
469 case OPCODE_lload_2
: type
= long_type_node
; index
= 2; goto load
;
470 case OPCODE_lload_3
: type
= long_type_node
; index
= 3; goto load
;
471 case OPCODE_fload_0
: type
= float_type_node
; index
= 0; goto load
;
472 case OPCODE_fload_1
: type
= float_type_node
; index
= 1; goto load
;
473 case OPCODE_fload_2
: type
= float_type_node
; index
= 2; goto load
;
474 case OPCODE_fload_3
: type
= float_type_node
; index
= 3; goto load
;
475 case OPCODE_dload_0
: type
= double_type_node
; index
= 0; goto load
;
476 case OPCODE_dload_1
: type
= double_type_node
; index
= 1; goto load
;
477 case OPCODE_dload_2
: type
= double_type_node
; index
= 2; goto load
;
478 case OPCODE_dload_3
: type
= double_type_node
; index
= 3; goto load
;
479 case OPCODE_aload_0
: type
= ptr_type_node
; index
= 0; goto load
;
480 case OPCODE_aload_1
: type
= ptr_type_node
; index
= 1; goto load
;
481 case OPCODE_aload_2
: type
= ptr_type_node
; index
= 2; goto load
;
482 case OPCODE_aload_3
: type
= ptr_type_node
; index
= 3; goto load
;
485 || (index
+ TYPE_IS_WIDE (type
)
486 >= DECL_MAX_LOCALS (current_function_decl
)))
487 VERIFICATION_ERROR ("invalid local variable index in load");
488 tmp
= type_map
[index
];
489 if (tmp
== TYPE_UNKNOWN
|| tmp
== TYPE_SECOND
490 || (TYPE_IS_WIDE (type
)
491 && type_map
[index
+1] != void_type_node
)
492 || (type
== ptr_type_node
493 ? TREE_CODE (tmp
) != POINTER_TYPE
494 : type
== int_type_node
495 ? (! INTEGRAL_TYPE_P (tmp
) || TYPE_PRECISION (tmp
) > 32)
497 VERIFICATION_ERROR("invalid local variable type in load");
500 case OPCODE_istore
: type
= int_type_node
; goto general_store
;
501 case OPCODE_lstore
: type
= long_type_node
; goto general_store
;
502 case OPCODE_fstore
: type
= float_type_node
; goto general_store
;
503 case OPCODE_dstore
: type
= double_type_node
; goto general_store
;
504 case OPCODE_astore
: type
= ptr_type_node
; goto general_store
;
506 index
= wide
? IMMEDIATE_u2
: IMMEDIATE_u1
;
509 case OPCODE_istore_0
: type
= int_type_node
; index
= 0; goto store
;
510 case OPCODE_istore_1
: type
= int_type_node
; index
= 1; goto store
;
511 case OPCODE_istore_2
: type
= int_type_node
; index
= 2; goto store
;
512 case OPCODE_istore_3
: type
= int_type_node
; index
= 3; goto store
;
513 case OPCODE_lstore_0
: type
= long_type_node
; index
=0; goto store
;
514 case OPCODE_lstore_1
: type
= long_type_node
; index
=1; goto store
;
515 case OPCODE_lstore_2
: type
= long_type_node
; index
=2; goto store
;
516 case OPCODE_lstore_3
: type
= long_type_node
; index
=3; goto store
;
517 case OPCODE_fstore_0
: type
=float_type_node
; index
=0; goto store
;
518 case OPCODE_fstore_1
: type
=float_type_node
; index
=1; goto store
;
519 case OPCODE_fstore_2
: type
=float_type_node
; index
=2; goto store
;
520 case OPCODE_fstore_3
: type
=float_type_node
; index
=3; goto store
;
521 case OPCODE_dstore_0
: type
=double_type_node
; index
=0; goto store
;
522 case OPCODE_dstore_1
: type
=double_type_node
; index
=1; goto store
;
523 case OPCODE_dstore_2
: type
=double_type_node
; index
=2; goto store
;
524 case OPCODE_dstore_3
: type
=double_type_node
; index
=3; goto store
;
525 case OPCODE_astore_0
: type
= ptr_type_node
; index
= 0; goto store
;
526 case OPCODE_astore_1
: type
= ptr_type_node
; index
= 1; goto store
;
527 case OPCODE_astore_2
: type
= ptr_type_node
; index
= 2; goto store
;
528 case OPCODE_astore_3
: type
= ptr_type_node
; index
= 3; goto store
;
531 || (index
+ TYPE_IS_WIDE (type
)
532 >= DECL_MAX_LOCALS (current_function_decl
)))
534 VERIFICATION_ERROR ("invalid local variable index in store");
537 type
= pop_type (type
);
538 type_map
[index
] = type
;
540 /* If local variable changed, we need to reconsider eh handlers. */
541 prev_eh_ranges
= NULL_EH_RANGE
;
543 /* Allocate decl and rtx for this variable now, so if we're not
544 optmizing, we get a temporary that survives the whole method. */
545 find_local_variable (index
, type
, oldpc
);
547 if (TYPE_IS_WIDE (type
))
548 type_map
[index
+1] = TYPE_SECOND
;
549 /* ... fall through to note_used ... */
551 /* For store or load, note that local variable INDEX is used.
552 This is needed to verify try-finally sub-routines. */
555 tree vec
= LABEL_RETURN_TYPE_STATE (current_subr
);
556 tree subr_vec
= LABEL_TYPE_STATE (current_subr
);
557 int len
= 1 + TYPE_IS_WIDE (type
);
560 if (TREE_VEC_ELT (vec
, index
) == TYPE_UNUSED
)
561 TREE_VEC_ELT (vec
, index
) = TREE_VEC_ELT (subr_vec
, index
);
576 type
= int_type_node
; goto binop
;
581 type
= int_type_node
; goto unop
;
590 type
= long_type_node
; goto binop
;
592 type
= long_type_node
; goto unop
;
593 case OPCODE_fadd
: case OPCODE_fsub
:
594 case OPCODE_fmul
: case OPCODE_fdiv
: case OPCODE_frem
:
595 type
= float_type_node
; goto binop
;
597 type
= float_type_node
; goto unop
;
598 case OPCODE_dadd
: case OPCODE_dsub
:
599 case OPCODE_dmul
: case OPCODE_ddiv
: case OPCODE_drem
:
600 type
= double_type_node
; goto binop
;
602 type
= double_type_node
; goto unop
;
615 pop_type (int_type_node
);
616 pop_type (long_type_node
);
617 push_type (long_type_node
);
620 index
= wide
? IMMEDIATE_u2
: IMMEDIATE_u1
;
623 if (index
< 0 || index
>= DECL_MAX_LOCALS (current_function_decl
))
624 VERIFICATION_ERROR ("invalid local variable index in iinc");
625 tmp
= type_map
[index
];
626 if (! INTEGRAL_TYPE_P (tmp
) || TYPE_PRECISION (tmp
) > 32)
627 VERIFICATION_ERROR ("invalid local variable type in iinc");
630 pop_type (int_type_node
); push_type (long_type_node
); break;
632 pop_type (int_type_node
); push_type (float_type_node
); break;
634 pop_type (int_type_node
); push_type (double_type_node
); break;
636 pop_type (long_type_node
); push_type (int_type_node
); break;
638 pop_type (long_type_node
); push_type (float_type_node
); break;
640 pop_type (long_type_node
); push_type (double_type_node
); break;
642 pop_type (float_type_node
); push_type (int_type_node
); break;
644 pop_type (float_type_node
); push_type (long_type_node
); break;
646 pop_type (float_type_node
); push_type (double_type_node
); break;
648 pop_type (double_type_node
); push_type (int_type_node
); break;
650 pop_type (double_type_node
); push_type (long_type_node
); break;
652 pop_type (double_type_node
); push_type (float_type_node
); break;
654 type
= long_type_node
; goto compare
;
657 type
= float_type_node
; goto compare
;
660 type
= double_type_node
; goto compare
;
662 pop_type (type
); pop_type (type
);
663 push_type (int_type_node
); break;
670 pop_type (int_type_node
); goto cond
;
672 case OPCODE_ifnonnull
:
673 pop_type (ptr_type_node
); goto cond
;
674 case OPCODE_if_icmpeq
:
675 case OPCODE_if_icmpne
:
676 case OPCODE_if_icmplt
:
677 case OPCODE_if_icmpge
:
678 case OPCODE_if_icmpgt
:
679 case OPCODE_if_icmple
:
680 pop_type (int_type_node
); pop_type (int_type_node
); goto cond
;
681 case OPCODE_if_acmpeq
:
682 case OPCODE_if_acmpne
:
683 pop_type (object_ptr_type_node
); pop_type (object_ptr_type_node
);
686 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s2
));
689 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s2
));
693 switch (byte_ops
[PC
])
695 case OPCODE_iload
: case OPCODE_lload
:
696 case OPCODE_fload
: case OPCODE_dload
: case OPCODE_aload
:
697 case OPCODE_istore
: case OPCODE_lstore
:
698 case OPCODE_fstore
: case OPCODE_dstore
: case OPCODE_astore
:
704 VERIFICATION_ERROR ("invalid use of wide instruction");
707 case OPCODE_ireturn
: type
= int_type_node
; goto ret
;
708 case OPCODE_lreturn
: type
= long_type_node
; goto ret
;
709 case OPCODE_freturn
: type
= float_type_node
; goto ret
;
710 case OPCODE_dreturn
: type
= double_type_node
; goto ret
;
711 case OPCODE_areturn
: type
= ptr_type_node
; goto ret
;
714 /* ... fall through ... */
718 case OPCODE_getstatic
: is_putting
= 0; is_static
= 1; goto field
;
719 case OPCODE_putstatic
: is_putting
= 1; is_static
= 1; goto field
;
720 case OPCODE_getfield
: is_putting
= 0; is_static
= 0; goto field
;
721 case OPCODE_putfield
: is_putting
= 1; is_static
= 0; goto field
;
724 int index
= IMMEDIATE_u2
;
725 tree self_type
= get_class_constant
726 (jcf
, COMPONENT_REF_CLASS_INDEX (¤t_jcf
->cpool
, index
));
727 tree field_signature
= COMPONENT_REF_SIGNATURE (¤t_jcf
->cpool
, index
);
728 tree field_type
= get_type_from_signature (field_signature
);
730 pop_type (field_type
);
733 /* Defer actual checking until next pass. */
734 pop_type (ptr_type_node
);
737 push_type (field_type
);
741 push_type (get_class_constant (jcf
, IMMEDIATE_u2
));
743 case OPCODE_dup
: type_stack_dup (1, 0); break;
744 case OPCODE_dup_x1
: type_stack_dup (1, 1); break;
745 case OPCODE_dup_x2
: type_stack_dup (1, 2); break;
746 case OPCODE_dup2
: type_stack_dup (2, 0); break;
747 case OPCODE_dup2_x1
: type_stack_dup (2, 1); break;
748 case OPCODE_dup2_x2
: type_stack_dup (2, 2); break;
749 case OPCODE_pop
: index
= 1; goto pop
;
750 case OPCODE_pop2
: index
= 2; goto pop
;
752 if (stack_pointer
< index
)
753 VERIFICATION_ERROR ("stack underflow");
754 stack_pointer
-= index
;
757 if (stack_pointer
< 2)
758 VERIFICATION_ERROR ("stack underflow (in swap)");
761 tree type1
= stack_type_map
[stack_pointer
- 1];
762 tree type2
= stack_type_map
[stack_pointer
- 2];
763 if (type1
== void_type_node
|| type2
== void_type_node
)
764 VERIFICATION_ERROR ("verifier (swap): double or long value");
765 stack_type_map
[stack_pointer
- 2] = type1
;
766 stack_type_map
[stack_pointer
- 1] = type2
;
769 case OPCODE_ldc
: index
= IMMEDIATE_u1
; goto ldc
;
772 index
= IMMEDIATE_u2
; goto ldc
;
774 if (index
<= 0 || index
>= JPOOL_SIZE(current_jcf
))
775 VERIFICATION_ERROR ("bad constant pool index in ldc");
777 switch (JPOOL_TAG (current_jcf
, index
) & ~CONSTANT_ResolvedFlag
)
779 case CONSTANT_Integer
: type
= int_type_node
; goto check_ldc
;
780 case CONSTANT_Float
: type
= float_type_node
; goto check_ldc
;
781 case CONSTANT_String
: type
= string_type_node
; goto check_ldc
;
782 case CONSTANT_Long
: type
= long_type_node
; goto check_ldc
;
783 case CONSTANT_Double
: type
= double_type_node
; goto check_ldc
;
785 if (TYPE_IS_WIDE (type
) == (op_code
== OPCODE_ldc2_w
))
787 /* ... else fall through ... */
789 VERIFICATION_ERROR ("bad constant pool tag in ldc");
791 if (type
== int_type_node
)
793 i
= TREE_INT_CST_LOW (get_constant (current_jcf
, index
));
799 case OPCODE_invokevirtual
:
800 case OPCODE_invokespecial
:
801 case OPCODE_invokestatic
:
802 case OPCODE_invokeinterface
:
804 int index
= IMMEDIATE_u2
;
805 tree sig
= COMPONENT_REF_SIGNATURE (¤t_jcf
->cpool
, index
);
806 tree self_type
= get_class_constant
807 (current_jcf
, COMPONENT_REF_CLASS_INDEX (¤t_jcf
->cpool
,
809 tree method_name
= COMPONENT_REF_NAME (¤t_jcf
->cpool
, index
);
811 method_type
= parse_signature_string (IDENTIFIER_POINTER (sig
),
812 IDENTIFIER_LENGTH (sig
));
813 if (TREE_CODE (method_type
) != FUNCTION_TYPE
)
814 VERIFICATION_ERROR ("bad method signature");
815 pop_argument_types (TYPE_ARG_TYPES (method_type
));
817 /* Can't invoke <clinit> */
818 if (method_name
== clinit_identifier_node
)
819 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
820 /* Apart invokespecial, can't invoke <init> */
821 if (op_code
!= OPCODE_invokespecial
822 && method_name
== init_identifier_node
)
823 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
825 if (op_code
!= OPCODE_invokestatic
)
826 pop_type (self_type
);
830 case OPCODE_invokeinterface
:
832 int nargs
= IMMEDIATE_u1
;
833 int notZero
= IMMEDIATE_u1
;
835 if (!nargs
|| notZero
)
837 ("invalid argument number in invokeinterface");
842 if (TREE_TYPE (method_type
) != void_type_node
)
843 push_type (TREE_TYPE (method_type
));
847 case OPCODE_arraylength
:
848 /* Type checking actually made during code generation */
849 pop_type( ptr_type_node
);
850 push_type( int_type_node
);
853 /* Q&D verification *or* more checking done during code generation
854 for byte/boolean/char/short, the value popped is a int coerced
855 into the right type before being stored. */
856 case OPCODE_iastore
: type
= int_type_node
; goto astore
;
857 case OPCODE_lastore
: type
= long_type_node
; goto astore
;
858 case OPCODE_fastore
: type
= float_type_node
; goto astore
;
859 case OPCODE_dastore
: type
= double_type_node
; goto astore
;
860 case OPCODE_aastore
: type
= ptr_type_node
; goto astore
;
861 case OPCODE_bastore
: type
= int_type_node
; goto astore
;
862 case OPCODE_castore
: type
= int_type_node
; goto astore
;
863 case OPCODE_sastore
: type
= int_type_node
; goto astore
;
865 /* FIXME - need better verification here */
866 pop_type (type
); /* new value */
867 pop_type (int_type_node
); /* index */
868 pop_type (ptr_type_node
); /* array */
871 /* Q&D verification *or* more checking done during code generation
872 for byte/boolean/char/short, the value pushed is a int. */
873 case OPCODE_iaload
: type
= int_type_node
; goto aload
;
874 case OPCODE_laload
: type
= long_type_node
; goto aload
;
875 case OPCODE_faload
: type
= float_type_node
; goto aload
;
876 case OPCODE_daload
: type
= double_type_node
; goto aload
;
877 case OPCODE_aaload
: type
= ptr_type_node
; goto aload
;
878 case OPCODE_baload
: type
= promote_type (byte_type_node
); goto aload
;
879 case OPCODE_caload
: type
= promote_type (char_type_node
); goto aload
;
880 case OPCODE_saload
: type
= promote_type (short_type_node
); goto aload
;
882 pop_type (int_type_node
);
883 tmp
= pop_type (ptr_type_node
);
884 if (is_array_type_p (tmp
))
885 type
= TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp
));
886 else if (tmp
!= TYPE_NULL
)
887 VERIFICATION_ERROR ("array load from non-array type");
891 case OPCODE_anewarray
:
892 type
= get_class_constant (current_jcf
, IMMEDIATE_u2
);
893 type
= promote_type (type
);
896 case OPCODE_newarray
:
897 index
= IMMEDIATE_u1
;
898 type
= decode_newarray_type (index
);
899 if (type
== NULL_TREE
)
900 VERIFICATION_ERROR ("invalid type code in newarray opcode");
904 if (int_value
>= 0 && prevpc
>= 0)
906 /* If previous instruction pushed int constant,
907 we want to use it. */
908 switch (byte_ops
[prevpc
])
910 case OPCODE_iconst_0
: case OPCODE_iconst_1
:
911 case OPCODE_iconst_2
: case OPCODE_iconst_3
:
912 case OPCODE_iconst_4
: case OPCODE_iconst_5
:
913 case OPCODE_bipush
: case OPCODE_sipush
:
914 case OPCODE_ldc
: case OPCODE_ldc_w
:
922 type
= build_java_array_type (type
, int_value
);
923 pop_type (int_type_node
);
927 case OPCODE_multianewarray
:
930 index
= IMMEDIATE_u2
;
934 VERIFICATION_ERROR ("number of dimension lower that 1 in multianewarray" );
936 for( i
= 0; i
< ndim
; i
++ )
937 pop_type (int_type_node
);
938 push_type (get_class_constant (current_jcf
, index
));
942 case OPCODE_aconst_null
:
943 push_type (ptr_type_node
);
947 pop_type (throwable_type_node
);
951 case OPCODE_checkcast
:
952 pop_type (ptr_type_node
);
953 type
= get_class_constant (current_jcf
, IMMEDIATE_u2
);
956 case OPCODE_instanceof
:
957 pop_type (ptr_type_node
);
958 get_class_constant (current_jcf
, IMMEDIATE_u2
);
959 push_type (int_type_node
);
962 case OPCODE_tableswitch
:
966 pop_type (int_type_node
);
970 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
972 PUSH_PENDING (lookup_label (oldpc
+IMMEDIATE_s4
));
977 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
979 while (low
++ <= high
)
980 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s4
));
985 case OPCODE_lookupswitch
:
987 jint npairs
, last
, not_registered
= 1;
989 pop_type (int_type_node
);
993 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
996 PUSH_PENDING (lookup_label (oldpc
+IMMEDIATE_s4
));
997 npairs
= IMMEDIATE_s4
;
1000 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1004 int match
= IMMEDIATE_s4
;
1007 else if (last
>= match
)
1008 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1011 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s4
));
1017 case OPCODE_monitorenter
:
1019 case OPCODE_monitorexit
:
1020 pop_type (ptr_type_node
);
1024 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s4
));
1030 tree target
= lookup_label (oldpc
+ IMMEDIATE_s2
);
1031 tree return_label
= lookup_label (PC
);
1032 push_type (return_address_type_node
);
1033 if (! LABEL_VERIFIED (target
))
1035 /* first time seen */
1036 tree return_type_map
;
1037 int nlocals
= DECL_MAX_LOCALS (current_function_decl
);
1038 index
= nlocals
+ DECL_MAX_STACK (current_function_decl
);
1039 return_type_map
= make_tree_vec (index
);
1040 while (index
> nlocals
)
1041 TREE_VEC_ELT (return_type_map
, --index
) = TYPE_UNKNOWN
;
1043 TREE_VEC_ELT (return_type_map
, --index
) = TYPE_UNUSED
;
1044 LABEL_RETURN_LABEL (target
)
1045 = build_decl (LABEL_DECL
, NULL_TREE
, TREE_TYPE (target
));
1046 LABEL_PC (LABEL_RETURN_LABEL (target
)) = -1;
1047 LABEL_RETURN_TYPE_STATE (target
) = return_type_map
;
1048 LABEL_IS_SUBR_START (target
) = 1;
1049 LABEL_IN_SUBR (target
) = 1;
1050 LABEL_SUBR_START (target
) = target
;
1051 LABEL_SUBR_CONTEXT (target
) = current_subr
;
1053 else if (! LABEL_IS_SUBR_START (target
)
1054 || LABEL_SUBR_CONTEXT (target
) != current_subr
)
1055 VERIFICATION_ERROR ("label part of different subroutines");
1057 i
= merge_type_state (target
);
1061 VERIFICATION_ERROR ("types could not be merged at jsr");
1062 push_pending_label (target
);
1064 current_subr
= target
;
1066 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1067 if (! value_member (return_label
, LABEL_RETURN_LABELS (target
)))
1069 LABEL_RETURN_LABELS (target
)
1070 = tree_cons (NULL_TREE
, return_label
,
1071 LABEL_RETURN_LABELS (target
));
1074 if (LABEL_VERIFIED (target
))
1076 tree return_map
= LABEL_RETURN_TYPE_STATE (target
);
1077 int len
= TREE_VEC_LENGTH (return_map
);
1078 stack_pointer
= len
- DECL_MAX_LOCALS (current_function_decl
);
1081 if (TREE_VEC_ELT (return_map
, len
) != TYPE_UNUSED
)
1082 type_map
[len
] = TREE_VEC_ELT (return_map
, len
);
1084 current_subr
= LABEL_SUBR_CONTEXT (target
);
1085 PUSH_PENDING (return_label
);
1092 if (current_subr
== NULL
)
1093 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1096 tree ret_map
= LABEL_RETURN_TYPE_STATE (current_subr
);
1097 tree caller
= LABEL_SUBR_CONTEXT (current_subr
);
1098 int size
= DECL_MAX_LOCALS(current_function_decl
)+stack_pointer
;
1099 index
= wide
? IMMEDIATE_u2
: IMMEDIATE_u1
;
1102 if (index
< 0 || index
>= DECL_MAX_LOCALS (current_function_decl
)
1103 || type_map
[index
] != TYPE_RETURN_ADDR
)
1104 VERIFICATION_ERROR ("invalid ret index");
1106 /* The next chunk of code is similar to an inlined version of
1107 * merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1108 * The main differences are that LABEL_RETURN_LABEL is
1109 * pre-allocated by the jsr (but we don't know the size then);
1110 * and that we have to handle TYPE_UNUSED. */
1112 if (! RETURN_MAP_ADJUSTED (ret_map
))
1113 { /* First return from this subroutine - fix stack pointer. */
1114 TREE_VEC_LENGTH (ret_map
) = size
;
1115 for (index
= size
; --index
>= 0; )
1117 if (TREE_VEC_ELT (ret_map
, index
) != TYPE_UNUSED
)
1118 TREE_VEC_ELT (ret_map
, index
) = type_map
[index
];
1120 RETURN_MAP_ADJUSTED (ret_map
) = 1;
1124 if (TREE_VEC_LENGTH (ret_map
) != size
)
1125 VERIFICATION_ERROR ("inconsistent stack size on ret");
1126 for (index
= 0; index
< size
; index
++)
1128 tree type
= TREE_VEC_ELT (ret_map
, index
);
1129 if (type
!= TYPE_UNUSED
)
1131 type
= merge_types (type
, type_map
[index
]);
1132 TREE_VEC_ELT (ret_map
, index
) = type
;
1133 if (type
== TYPE_UNKNOWN
)
1135 if (index
>= size
- stack_pointer
)
1137 ("inconsistent types on ret from jsr");
1139 else if (TYPE_IS_WIDE (type
))
1145 /* Check if there are any more pending blocks in this subroutine.
1146 Because we push pending blocks in a last-in-first-out order,
1147 and because we don't push anything from our caller until we
1148 are done with this subroutine or anything nested in it,
1149 then we are done if the top of the pending_blocks stack is
1150 not in a subroutine, or it is in our caller. */
1151 if (pending_blocks
== NULL_TREE
1152 || ! LABEL_IN_SUBR (pending_blocks
)
1153 || LABEL_SUBR_START (pending_blocks
) == caller
)
1155 /* Since we are done with this subroutine (i.e. this is the
1156 last ret from it), set up the (so far known) return
1157 address as pending - with the merged type state. */
1158 tmp
= LABEL_RETURN_LABELS (current_subr
);
1159 current_subr
= caller
;
1160 for ( ; tmp
!= NULL_TREE
; tmp
= TREE_CHAIN (tmp
))
1162 tree return_label
= TREE_VALUE (tmp
);
1163 tree return_state
= LABEL_TYPE_STATE (return_label
);
1164 if (return_state
== NULL_TREE
)
1166 /* This means means we had not verified the
1167 subroutine earlier, so this is the first jsr to
1168 call it. In this case, the type_map of the return
1169 address is just the current type_map - and that
1170 is handled by the following PUSH_PENDING. */
1174 /* In this case we have to do a merge. But first
1175 restore the type_map for unused slots to those
1176 that were in effect at the jsr. */
1177 for (index
= size
; --index
>= 0; )
1179 type_map
[index
] = TREE_VEC_ELT (ret_map
, index
);
1180 if (type_map
[index
] == TYPE_UNUSED
)
1182 = TREE_VEC_ELT (return_state
, index
);
1185 PUSH_PENDING (return_label
);
1193 error ("unknown opcode %d@pc=%d during verification", op_code
, PC
-1);
1199 /* The following test is true if we have entered or exited an exception
1200 handler range *or* we have done a store to a local variable.
1201 In either case we need to consider any exception handlers that
1202 might "follow" this instruction. */
1204 if (eh_ranges
!= prev_eh_ranges
)
1206 int save_stack_pointer
= stack_pointer
;
1207 int index
= DECL_MAX_LOCALS (current_function_decl
);
1208 tree save_type
= type_map
[index
];
1209 tree save_current_subr
= current_subr
;
1210 struct eh_range
*ranges
= find_handler (oldpc
);
1212 for (; ranges
!= NULL_EH_RANGE
; ranges
= ranges
->outer
)
1214 tree chain
= ranges
->handlers
;
1216 /* We need to determine if the handler is part of current_subr.
1217 The are two cases: (1) The exception catch range
1218 is entirely within current_subr. In that case the handler
1219 is also part of current_subr.
1220 (2) Some of the catch range is not in current_subr.
1221 In that case, the handler is *not* part of current_subr.
1223 Figuring out which is the case is not necessarily obvious,
1224 in the presence of clever code generators (and obfuscators).
1225 We make a simplifying assumption that in case (2) we
1226 have that the current_subr is entirely within the catch range.
1227 In that case we can assume if that if a caller (the jsr) of
1228 a subroutine is within the catch range, then the handler is
1229 *not* part of the subroutine, and vice versa. */
1231 current_subr
= save_current_subr
;
1232 for ( ; current_subr
!= NULL_TREE
;
1233 current_subr
= LABEL_SUBR_CONTEXT (current_subr
))
1235 tree return_labels
= LABEL_RETURN_LABELS (current_subr
);
1236 /* There could be multiple return_labels, but
1237 we only need to check one. */
1238 int return_pc
= LABEL_PC (TREE_VALUE (return_labels
));
1239 if (return_pc
<= ranges
->start_pc
1240 || return_pc
> ranges
->end_pc
)
1244 for ( ; chain
!= NULL_TREE
; chain
= TREE_CHAIN (chain
))
1246 tree handler
= TREE_VALUE (chain
);
1247 tree type
= TREE_PURPOSE (chain
);
1248 if (type
== NULL_TREE
) /* a finally handler */
1249 type
= throwable_type_node
;
1250 type_map
[index
] = promote_type (type
);
1252 PUSH_PENDING (handler
);
1255 stack_pointer
= save_stack_pointer
;
1256 current_subr
= save_current_subr
;
1257 type_map
[index
] = save_type
;
1258 prev_eh_ranges
= eh_ranges
;
1263 message
= "program counter out of range";
1266 error ("verification error at PC=%d: %s", oldpc
, message
);
This page took 0.103979 seconds and 6 git commands to generate.