]>
Commit | Line | Data |
---|---|---|
5624e564 | 1 | /* Copyright (C) 2001-2015 Free Software Foundation, Inc. |
36739040 TT |
2 | |
3 | This file is part of libgcj. | |
4 | ||
5 | This software is copyrighted work licensed under the terms of the | |
6 | Libgcj License. Please consult the file "LIBGCJ_LICENSE" for | |
7 | details. */ | |
8 | ||
9 | /* Written by Tom Tromey <tromey@redhat.com> */ | |
10 | ||
11 | /* Uncomment this to enable debugging output. */ | |
12 | /* #define VERIFY_DEBUG */ | |
13 | ||
14 | #include "config.h" | |
79bdca32 SB |
15 | #include "system.h" |
16 | #include "coretypes.h" | |
36739040 TT |
17 | |
18 | #include "verify.h" | |
19 | ||
20 | /* Hack to work around namespace pollution from java-tree.h. */ | |
21 | #undef current_class | |
22 | ||
36739040 TT |
23 | /* This is used to mark states which are not scheduled for |
24 | verification. */ | |
25 | #define INVALID_STATE ((state *) -1) | |
26 | ||
74118f15 KG |
27 | static void ATTRIBUTE_PRINTF_1 |
28 | debug_print (const char *fmt ATTRIBUTE_UNUSED, ...) | |
36739040 | 29 | { |
74118f15 | 30 | #ifdef VERIFY_DEBUG |
36739040 TT |
31 | va_list ap; |
32 | va_start (ap, fmt); | |
33 | vfprintf (stderr, fmt, ap); | |
34 | va_end (ap); | |
36739040 | 35 | #endif /* VERIFY_DEBUG */ |
74118f15 | 36 | } |
36739040 | 37 | |
36739040 TT |
38 | /* This started as a fairly ordinary verifier, and for the most part |
39 | it remains so. It works in the obvious way, by modeling the effect | |
40 | of each opcode as it is encountered. For most opcodes, this is a | |
41 | straightforward operation. | |
42 | ||
43 | This verifier does not do type merging. It used to, but this | |
44 | results in difficulty verifying some relatively simple code | |
45 | involving interfaces, and it pushed some verification work into the | |
46 | interpreter. | |
47 | ||
48 | Instead of merging reference types, when we reach a point where two | |
49 | flows of control merge, we simply keep the union of reference types | |
50 | from each branch. Then, when we need to verify a fact about a | |
51 | reference on the stack (e.g., that it is compatible with the | |
52 | argument type of a method), we check to ensure that all possible | |
53 | types satisfy the requirement. | |
54 | ||
55 | Another area this verifier differs from the norm is in its handling | |
56 | of subroutines. The JVM specification has some confusing things to | |
57 | say about subroutines. For instance, it makes claims about not | |
58 | allowing subroutines to merge and it rejects recursive subroutines. | |
59 | For the most part these are red herrings; we used to try to follow | |
60 | these things but they lead to problems. For example, the notion of | |
61 | "being in a subroutine" is not well-defined: is an exception | |
62 | handler in a subroutine? If you never execute the `ret' but | |
63 | instead `goto 1' do you remain in the subroutine? | |
64 | ||
65 | For clarity on what is really required for type safety, read | |
66 | "Simple Verification Technique for Complex Java Bytecode | |
67 | Subroutines" by Alessandro Coglio. Among other things this paper | |
68 | shows that recursive subroutines are not harmful to type safety. | |
69 | We implement something similar to what he proposes. Note that this | |
70 | means that this verifier will accept code that is rejected by some | |
71 | other verifiers. | |
72 | ||
73 | For those not wanting to read the paper, the basic observation is | |
74 | that we can maintain split states in subroutines. We maintain one | |
75 | state for each calling `jsr'. In other words, we re-verify a | |
76 | subroutine once for each caller, using the exact types held by the | |
77 | callers (as opposed to the old approach of merging types and | |
78 | keeping a bitmap registering what did or did not change). This | |
79 | approach lets us continue to verify correctly even when a | |
80 | subroutine is exited via `goto' or `athrow' and not `ret'. | |
81 | ||
82 | In some other areas the JVM specification is (mildly) incorrect, | |
83 | so we diverge. For instance, you cannot | |
84 | violate type safety by allocating an object with `new' and then | |
85 | failing to initialize it, no matter how one branches or where one | |
86 | stores the uninitialized reference. See "Improving the official | |
87 | specification of Java bytecode verification" by Alessandro Coglio. | |
88 | ||
89 | Note that there's no real point in enforcing that padding bytes or | |
90 | the mystery byte of invokeinterface must be 0, but we do that | |
91 | regardless. | |
92 | ||
93 | The verifier is currently neither completely lazy nor eager when it | |
94 | comes to loading classes. It tries to represent types by name when | |
95 | possible, and then loads them when it needs to verify a fact about | |
96 | the type. Checking types by name is valid because we only use | |
97 | names which come from the current class' constant pool. Since all | |
98 | such names are looked up using the same class loader, there is no | |
99 | danger that we might be fooled into comparing different types with | |
100 | the same name. | |
101 | ||
102 | In the future we plan to allow for a completely lazy mode of | |
103 | operation, where the verifier will construct a list of type | |
104 | assertions to be checked later. | |
105 | ||
106 | Some test cases for the verifier live in the "verify" module of the | |
107 | Mauve test suite. However, some of these are presently | |
108 | (2004-01-20) believed to be incorrect. (More precisely the notion | |
109 | of "correct" is not well-defined, and this verifier differs from | |
110 | others while remaining type-safe.) Some other tests live in the | |
111 | libgcj test suite. | |
112 | ||
113 | This verifier is also written to be pluggable. This means that it | |
114 | is intended for use in a variety of environments, not just libgcj. | |
115 | As a result the verifier expects a number of type and method | |
116 | declarations to be declared in "verify.h". The intent is that you | |
117 | recompile the verifier for your particular environment. This | |
118 | approach was chosen so that operations could be inlined in verify.h | |
119 | as much as possible. | |
120 | ||
121 | See the verify.h that accompanies this copy of the verifier to see | |
122 | what types, preprocessor defines, and functions must be declared. | |
123 | The interface is ad hoc, but was defined so that it could be | |
124 | implemented to connect to a pure C program. | |
125 | */ | |
126 | ||
127 | #define FLAG_INSN_START 1 | |
128 | #define FLAG_BRANCH_TARGET 2 | |
129 | #define FLAG_INSN_SEEN 4 | |
130 | ||
131 | struct state; | |
132 | struct type; | |
133 | struct ref_intersection; | |
134 | ||
135 | typedef struct state state; | |
136 | typedef struct type type; | |
137 | typedef struct ref_intersection ref_intersection; | |
138 | ||
139 | /*typedef struct state_list state_list;*/ | |
140 | ||
141 | typedef struct state_list | |
142 | { | |
143 | state *val; | |
144 | struct state_list *next; | |
145 | } state_list; | |
146 | ||
147 | typedef struct vfy_string_list | |
148 | { | |
149 | vfy_string val; | |
150 | struct vfy_string_list *next; | |
151 | } vfy_string_list; | |
152 | ||
153 | typedef struct verifier_context | |
154 | { | |
155 | /* The current PC. */ | |
156 | int PC; | |
157 | /* The PC corresponding to the start of the current instruction. */ | |
158 | int start_PC; | |
159 | ||
160 | /* The current state of the stack, locals, etc. */ | |
161 | state *current_state; | |
162 | ||
163 | /* At each branch target we keep a linked list of all the states we | |
164 | can process at that point. We'll only have multiple states at a | |
165 | given PC if they both have different return-address types in the | |
166 | same stack or local slot. This array is indexed by PC and holds | |
167 | the list of all such states. */ | |
168 | state_list **states; | |
169 | ||
170 | /* We keep a linked list of all the states which we must reverify. | |
171 | This is the head of the list. */ | |
172 | state *next_verify_state; | |
173 | ||
174 | /* We keep some flags for each instruction. The values are the | |
175 | FLAG_* constants defined above. This is an array indexed by PC. */ | |
176 | char *flags; | |
177 | ||
178 | /* The bytecode itself. */ | |
179 | const unsigned char *bytecode; | |
180 | /* The exceptions. */ | |
181 | vfy_exception *exception; | |
182 | ||
183 | /* Defining class. */ | |
184 | vfy_jclass current_class; | |
185 | /* This method. */ | |
186 | vfy_method *current_method; | |
187 | ||
188 | /* A linked list of utf8 objects we allocate. */ | |
189 | vfy_string_list *utf8_list; | |
190 | ||
191 | /* A linked list of all ref_intersection objects we allocate. */ | |
192 | ref_intersection *isect_list; | |
193 | } verifier_context; | |
194 | ||
195 | /* The current verifier's state data. This is maintained by | |
196 | {push/pop}_verifier_context to provide a shorthand form to access | |
197 | the verification state. */ | |
198 | static GTY(()) verifier_context *vfr; | |
199 | ||
200 | /* Local function declarations. */ | |
201 | bool type_initialized (type *t); | |
202 | int ref_count_dimensions (ref_intersection *ref); | |
203 | ||
36739040 TT |
204 | static void |
205 | verify_fail_pc (const char *s, int pc) | |
206 | { | |
207 | vfy_fail (s, pc, vfr->current_class, vfr->current_method); | |
208 | } | |
209 | ||
210 | static void | |
211 | verify_fail (const char *s) | |
212 | { | |
a2da2c9a | 213 | verify_fail_pc (s, vfr->PC); |
36739040 TT |
214 | } |
215 | ||
216 | /* This enum holds a list of tags for all the different types we | |
217 | need to handle. Reference types are treated specially by the | |
218 | type class. */ | |
219 | typedef enum type_val | |
220 | { | |
221 | void_type, | |
222 | ||
223 | /* The values for primitive types are chosen to correspond to values | |
224 | specified to newarray. */ | |
225 | boolean_type = 4, | |
226 | char_type = 5, | |
227 | float_type = 6, | |
228 | double_type = 7, | |
229 | byte_type = 8, | |
230 | short_type = 9, | |
231 | int_type = 10, | |
232 | long_type = 11, | |
233 | ||
234 | /* Used when overwriting second word of a double or long in the | |
235 | local variables. Also used after merging local variable states | |
236 | to indicate an unusable value. */ | |
237 | unsuitable_type, | |
238 | return_address_type, | |
239 | /* This is the second word of a two-word value, i.e., a double or | |
240 | a long. */ | |
241 | continuation_type, | |
242 | ||
243 | /* Everything after `reference_type' must be a reference type. */ | |
244 | reference_type, | |
245 | null_type, | |
246 | uninitialized_reference_type | |
247 | } type_val; | |
248 | ||
249 | /* This represents a merged class type. Some verifiers (including | |
250 | earlier versions of this one) will compute the intersection of | |
251 | two class types when merging states. However, this loses | |
252 | critical information about interfaces implemented by the various | |
253 | classes. So instead we keep track of all the actual classes that | |
254 | have been merged. */ | |
255 | struct ref_intersection | |
256 | { | |
257 | /* Whether or not this type has been resolved. */ | |
258 | bool is_resolved; | |
259 | ||
260 | /* Actual type data. */ | |
261 | union | |
262 | { | |
263 | /* For a resolved reference type, this is a pointer to the class. */ | |
264 | vfy_jclass klass; | |
265 | /* For other reference types, this it the name of the class. */ | |
266 | vfy_string name; | |
267 | } data; | |
268 | ||
269 | /* Link to the next reference in the intersection. */ | |
270 | ref_intersection *ref_next; | |
271 | ||
272 | /* This is used to keep track of all the allocated | |
273 | ref_intersection objects, so we can free them. | |
274 | FIXME: we should allocate these in chunks. */ | |
275 | ref_intersection *alloc_next; | |
276 | }; | |
277 | ||
278 | static ref_intersection * | |
279 | make_ref (void) | |
280 | { | |
281 | ref_intersection *new_ref = | |
282 | (ref_intersection *) vfy_alloc (sizeof (ref_intersection)); | |
283 | ||
284 | new_ref->alloc_next = vfr->isect_list; | |
285 | vfr->isect_list = new_ref; | |
286 | return new_ref; | |
287 | } | |
288 | ||
289 | static ref_intersection * | |
290 | clone_ref (ref_intersection *dup) | |
291 | { | |
292 | ref_intersection *new_ref = make_ref (); | |
293 | ||
294 | new_ref->is_resolved = dup->is_resolved; | |
295 | new_ref->data = dup->data; | |
296 | return new_ref; | |
297 | } | |
298 | ||
299 | static void | |
300 | resolve_ref (ref_intersection *ref) | |
301 | { | |
302 | if (ref->is_resolved) | |
303 | return; | |
304 | ref->data.klass = vfy_find_class (vfr->current_class, ref->data.name); | |
305 | ref->is_resolved = true; | |
306 | } | |
307 | ||
308 | static bool | |
309 | refs_equal (ref_intersection *ref1, ref_intersection *ref2) | |
310 | { | |
311 | if (! ref1->is_resolved && ! ref2->is_resolved | |
312 | && vfy_strings_equal (ref1->data.name, ref2->data.name)) | |
313 | return true; | |
314 | if (! ref1->is_resolved) | |
315 | resolve_ref (ref1); | |
316 | if (! ref2->is_resolved) | |
317 | resolve_ref (ref2); | |
318 | return ref1->data.klass == ref2->data.klass; | |
319 | } | |
320 | ||
321 | /* Merge REF1 type into REF2, returning the result. This will | |
322 | return REF2 if all the classes in THIS already appear in | |
323 | REF2. */ | |
324 | static ref_intersection * | |
325 | merge_refs (ref_intersection *ref1, ref_intersection *ref2) | |
326 | { | |
327 | ref_intersection *tail = ref2; | |
328 | for (; ref1 != NULL; ref1 = ref1->ref_next) | |
329 | { | |
330 | bool add = true; | |
331 | ref_intersection *iter; | |
332 | for (iter = ref2; iter != NULL; iter = iter->ref_next) | |
333 | { | |
334 | if (refs_equal (ref1, iter)) | |
335 | { | |
336 | add = false; | |
337 | break; | |
338 | } | |
339 | } | |
340 | ||
341 | if (add) | |
342 | { | |
343 | ref_intersection *new_tail = clone_ref (ref1); | |
344 | new_tail->ref_next = tail; | |
345 | tail = new_tail; | |
346 | } | |
347 | } | |
348 | return tail; | |
349 | } | |
350 | ||
351 | /* See if an object of type SOURCE can be assigned to an object of | |
352 | type TARGET. This might resolve classes in one chain or the other. */ | |
353 | static bool | |
354 | ref_compatible (ref_intersection *target, ref_intersection *source) | |
355 | { | |
356 | for (; target != NULL; target = target->ref_next) | |
357 | { | |
358 | ref_intersection *source_iter = source; | |
359 | ||
360 | for (; source_iter != NULL; source_iter = source_iter->ref_next) | |
361 | { | |
362 | /* Avoid resolving if possible. */ | |
363 | if (! target->is_resolved | |
364 | && ! source_iter->is_resolved | |
365 | && vfy_strings_equal (target->data.name, | |
366 | source_iter->data.name)) | |
367 | continue; | |
368 | ||
369 | if (! target->is_resolved) | |
370 | resolve_ref (target); | |
371 | if (! source_iter->is_resolved) | |
372 | resolve_ref (source_iter); | |
373 | ||
374 | if (! vfy_is_assignable_from (target->data.klass, | |
375 | source_iter->data.klass)) | |
376 | return false; | |
377 | } | |
378 | } | |
379 | ||
380 | return true; | |
381 | } | |
382 | ||
383 | static bool | |
384 | ref_isarray (ref_intersection *ref) | |
385 | { | |
386 | /* assert (ref_next == NULL); */ | |
387 | if (ref->is_resolved) | |
388 | return vfy_is_array (ref->data.klass); | |
389 | else | |
390 | return vfy_string_bytes (ref->data.name)[0] == '['; | |
391 | } | |
392 | ||
393 | static bool | |
394 | ref_isinterface (ref_intersection *ref) | |
395 | { | |
396 | /* assert (ref_next == NULL); */ | |
397 | if (! ref->is_resolved) | |
398 | resolve_ref (ref); | |
399 | return vfy_is_interface (ref->data.klass); | |
400 | } | |
401 | ||
402 | static bool | |
403 | ref_isabstract (ref_intersection *ref) | |
404 | { | |
405 | /* assert (ref_next == NULL); */ | |
406 | if (! ref->is_resolved) | |
407 | resolve_ref (ref); | |
408 | return vfy_is_abstract (ref->data.klass); | |
409 | } | |
410 | ||
411 | static vfy_jclass | |
412 | ref_getclass (ref_intersection *ref) | |
413 | { | |
414 | if (! ref->is_resolved) | |
415 | resolve_ref (ref); | |
416 | return ref->data.klass; | |
417 | } | |
418 | ||
419 | int | |
420 | ref_count_dimensions (ref_intersection *ref) | |
421 | { | |
422 | int ndims = 0; | |
423 | if (ref->is_resolved) | |
424 | { | |
425 | vfy_jclass k = ref->data.klass; | |
426 | while (vfy_is_array (k)) | |
427 | { | |
428 | k = vfy_get_component_type (k); | |
429 | ++ndims; | |
430 | } | |
431 | } | |
432 | else | |
433 | { | |
434 | const char *p = vfy_string_bytes (ref->data.name); | |
435 | while (*p++ == '[') | |
436 | ++ndims; | |
437 | } | |
438 | return ndims; | |
439 | } | |
440 | ||
441 | /* Return the type_val corresponding to a primitive signature | |
442 | character. For instance `I' returns `int.class'. */ | |
443 | static type_val | |
444 | get_type_val_for_signature (char sig) | |
445 | { | |
446 | type_val rt; | |
447 | switch (sig) | |
448 | { | |
449 | case 'Z': | |
450 | rt = boolean_type; | |
451 | break; | |
452 | case 'B': | |
453 | rt = byte_type; | |
454 | break; | |
455 | case 'C': | |
456 | rt = char_type; | |
457 | break; | |
458 | case 'S': | |
459 | rt = short_type; | |
460 | break; | |
461 | case 'I': | |
462 | rt = int_type; | |
463 | break; | |
464 | case 'J': | |
465 | rt = long_type; | |
466 | break; | |
467 | case 'F': | |
468 | rt = float_type; | |
469 | break; | |
470 | case 'D': | |
471 | rt = double_type; | |
472 | break; | |
473 | case 'V': | |
474 | rt = void_type; | |
475 | break; | |
476 | default: | |
477 | verify_fail ("invalid signature"); | |
478 | return null_type; | |
479 | } | |
480 | return rt; | |
481 | } | |
482 | ||
483 | /* Return the type_val corresponding to a primitive class. */ | |
484 | static type_val | |
485 | get_type_val_for_primtype (vfy_jclass k) | |
486 | { | |
487 | return get_type_val_for_signature (vfy_get_primitive_char (k)); | |
488 | } | |
489 | ||
490 | /* The `type' class is used to represent a single type in the verifier. */ | |
491 | struct type | |
492 | { | |
493 | /* The type key. */ | |
494 | type_val key; | |
495 | ||
496 | /* For reference types, the representation of the type. */ | |
497 | ref_intersection *klass; | |
498 | ||
499 | /* This is used in two situations. | |
500 | ||
501 | First, when constructing a new object, it is the PC of the | |
502 | `new' instruction which created the object. We use the special | |
84b6a4d2 TT |
503 | value UNINIT to mean that this is uninitialized. The special |
504 | value SELF is used for the case where the current method is | |
505 | itself the <init> method. the special value EITHER is used | |
506 | when we may optionally allow either an uninitialized or | |
507 | initialized reference to match. | |
508 | ||
36739040 TT |
509 | Second, when the key is return_address_type, this holds the PC |
510 | of the instruction following the `jsr'. */ | |
511 | int pc; | |
512 | ||
84b6a4d2 TT |
513 | #define UNINIT -2 |
514 | #define SELF -1 | |
515 | #define EITHER -3 | |
36739040 TT |
516 | }; |
517 | ||
36739040 TT |
518 | /* Make a new instance given the type tag. We assume a generic |
519 | `reference_type' means Object. */ | |
520 | static void | |
521 | init_type_from_tag (type *t, type_val k) | |
522 | { | |
523 | t->key = k; | |
524 | /* For reference_type, if KLASS==NULL then that means we are | |
525 | looking for a generic object of any kind, including an | |
526 | uninitialized reference. */ | |
527 | t->klass = NULL; | |
528 | t->pc = UNINIT; | |
529 | } | |
530 | ||
531 | /* Make a type for the given type_val tag K. */ | |
532 | static type | |
533 | make_type (type_val k) | |
534 | { | |
535 | type t; | |
536 | init_type_from_tag (&t, k); | |
537 | return t; | |
538 | } | |
539 | ||
540 | /* Make a new instance given a class. */ | |
541 | static void | |
542 | init_type_from_class (type *t, vfy_jclass k) | |
543 | { | |
544 | t->key = reference_type; | |
545 | t->klass = make_ref (); | |
546 | t->klass->is_resolved = true; | |
547 | t->klass->data.klass = k; | |
548 | t->klass->ref_next = NULL; | |
549 | t->pc = UNINIT; | |
550 | } | |
551 | ||
552 | static type | |
553 | make_type_from_class (vfy_jclass k) | |
554 | { | |
555 | type t; | |
556 | init_type_from_class (&t, k); | |
557 | return t; | |
558 | } | |
559 | ||
560 | static void | |
561 | init_type_from_string (type *t, vfy_string n) | |
562 | { | |
563 | t->key = reference_type; | |
564 | t->klass = make_ref (); | |
565 | t->klass->is_resolved = false; | |
566 | t->klass->data.name = n; | |
567 | t->klass->ref_next = NULL; | |
568 | t->pc = UNINIT; | |
569 | } | |
570 | ||
571 | static type | |
572 | make_type_from_string (vfy_string n) | |
573 | { | |
574 | type t; | |
575 | init_type_from_string (&t, n); | |
576 | return t; | |
577 | } | |
578 | ||
36739040 TT |
579 | /* Promote a numeric type. */ |
580 | static void | |
581 | vfy_promote_type (type *t) | |
582 | { | |
583 | if (t->key == boolean_type || t->key == char_type | |
584 | || t->key == byte_type || t->key == short_type) | |
585 | t->key = int_type; | |
586 | } | |
587 | #define promote_type vfy_promote_type | |
588 | ||
589 | /* Mark this type as the uninitialized result of `new'. */ | |
590 | static void | |
591 | type_set_uninitialized (type *t, int npc) | |
592 | { | |
593 | if (t->key == reference_type) | |
594 | t->key = uninitialized_reference_type; | |
595 | else | |
596 | verify_fail ("internal error in type::uninitialized"); | |
597 | t->pc = npc; | |
598 | } | |
599 | ||
600 | /* Mark this type as now initialized. */ | |
601 | static void | |
602 | type_set_initialized (type *t, int npc) | |
603 | { | |
604 | if (npc != UNINIT && t->pc == npc && t->key == uninitialized_reference_type) | |
605 | { | |
606 | t->key = reference_type; | |
607 | t->pc = UNINIT; | |
608 | } | |
609 | } | |
610 | ||
611 | /* Mark this type as a particular return address. */ | |
612 | static void type_set_return_address (type *t, int npc) | |
613 | { | |
614 | t->pc = npc; | |
615 | } | |
616 | ||
617 | /* Return true if this type and type OTHER are considered | |
618 | mergeable for the purposes of state merging. This is related | |
619 | to subroutine handling. For this purpose two types are | |
620 | considered unmergeable if they are both return-addresses but | |
621 | have different PCs. */ | |
622 | static bool | |
623 | type_state_mergeable_p (type *t1, type *t2) | |
624 | { | |
625 | return (t1->key != return_address_type | |
626 | || t2->key != return_address_type | |
627 | || t1->pc == t2->pc); | |
628 | } | |
629 | ||
630 | /* Return true if an object of type K can be assigned to a variable | |
631 | of type T. Handle various special cases too. Might modify | |
632 | T or K. Note however that this does not perform numeric | |
633 | promotion. */ | |
634 | static bool | |
635 | types_compatible (type *t, type *k) | |
636 | { | |
637 | /* Any type is compatible with the unsuitable type. */ | |
638 | if (k->key == unsuitable_type) | |
639 | return true; | |
640 | ||
641 | if (t->key < reference_type || k->key < reference_type) | |
642 | return t->key == k->key; | |
643 | ||
644 | /* The `null' type is convertible to any initialized reference | |
645 | type. */ | |
646 | if (t->key == null_type) | |
647 | return k->key != uninitialized_reference_type; | |
648 | if (k->key == null_type) | |
649 | return t->key != uninitialized_reference_type; | |
650 | ||
651 | /* A special case for a generic reference. */ | |
652 | if (t->klass == NULL) | |
653 | return true; | |
654 | if (k->klass == NULL) | |
655 | verify_fail ("programmer error in type::compatible"); | |
656 | ||
84b6a4d2 TT |
657 | /* Handle the special 'EITHER' case, which is only used in a |
658 | special case of 'putfield'. Note that we only need to handle | |
659 | this on the LHS of a check. */ | |
660 | if (! type_initialized (t) && t->pc == EITHER) | |
36739040 | 661 | { |
84b6a4d2 TT |
662 | /* If the RHS is uninitialized, it must be an uninitialized |
663 | 'this'. */ | |
664 | if (! type_initialized (k) && k->pc != SELF) | |
36739040 TT |
665 | return false; |
666 | } | |
84b6a4d2 TT |
667 | else if (type_initialized (t) != type_initialized (k)) |
668 | { | |
669 | /* An initialized type and an uninitialized type are not | |
670 | otherwise compatible. */ | |
671 | return false; | |
672 | } | |
673 | else | |
674 | { | |
675 | /* Two uninitialized objects are compatible if either: | |
676 | * The PCs are identical, or | |
677 | * One PC is UNINIT. */ | |
678 | if (type_initialized (t)) | |
679 | { | |
680 | if (t->pc != k->pc && t->pc != UNINIT && k->pc != UNINIT) | |
681 | return false; | |
682 | } | |
683 | } | |
36739040 TT |
684 | |
685 | return ref_compatible (t->klass, k->klass); | |
686 | } | |
687 | ||
1870a43b TT |
688 | /* Return true if two types are equal. Only valid for reference |
689 | types. */ | |
690 | static bool | |
691 | types_equal (type *t1, type *t2) | |
692 | { | |
e022a6cb TT |
693 | if ((t1->key != reference_type && t1->key != uninitialized_reference_type) |
694 | || (t2->key != reference_type | |
695 | && t2->key != uninitialized_reference_type)) | |
1870a43b TT |
696 | return false; |
697 | /* Only single-ref types are allowed. */ | |
698 | if (t1->klass->ref_next || t2->klass->ref_next) | |
699 | return false; | |
700 | return refs_equal (t1->klass, t2->klass); | |
701 | } | |
702 | ||
36739040 TT |
703 | static bool |
704 | type_isvoid (type *t) | |
705 | { | |
706 | return t->key == void_type; | |
707 | } | |
708 | ||
709 | static bool | |
710 | type_iswide (type *t) | |
711 | { | |
712 | return t->key == long_type || t->key == double_type; | |
713 | } | |
714 | ||
715 | /* Return number of stack or local variable slots taken by this type. */ | |
716 | static int | |
717 | type_depth (type *t) | |
718 | { | |
719 | return type_iswide (t) ? 2 : 1; | |
720 | } | |
721 | ||
722 | static bool | |
723 | type_isarray (type *t) | |
724 | { | |
725 | /* We treat null_type as not an array. This is ok based on the | |
726 | current uses of this method. */ | |
727 | if (t->key == reference_type) | |
728 | return ref_isarray (t->klass); | |
729 | return false; | |
730 | } | |
731 | ||
732 | static bool | |
733 | type_isnull (type *t) | |
734 | { | |
735 | return t->key == null_type; | |
736 | } | |
737 | ||
738 | static bool | |
739 | type_isinterface (type *t) | |
740 | { | |
741 | if (t->key != reference_type) | |
742 | return false; | |
743 | return ref_isinterface (t->klass); | |
744 | } | |
745 | ||
746 | static bool | |
747 | type_isabstract (type *t) | |
748 | { | |
749 | if (t->key != reference_type) | |
750 | return false; | |
751 | return ref_isabstract (t->klass); | |
752 | } | |
753 | ||
754 | /* Return the element type of an array. */ | |
755 | static type | |
756 | type_array_element (type *t) | |
757 | { | |
758 | type et; | |
759 | vfy_jclass k; | |
760 | ||
761 | if (t->key != reference_type) | |
762 | verify_fail ("programmer error in type::element_type()"); | |
763 | ||
764 | k = vfy_get_component_type (ref_getclass (t->klass)); | |
765 | if (vfy_is_primitive (k)) | |
766 | init_type_from_tag (&et, get_type_val_for_primtype (k)); | |
767 | else | |
768 | init_type_from_class (&et, k); | |
769 | return et; | |
770 | } | |
771 | ||
772 | /* Return the array type corresponding to an initialized | |
773 | reference. We could expand this to work for other kinds of | |
774 | types, but currently we don't need to. */ | |
775 | static type | |
776 | type_to_array (type *t) | |
777 | { | |
778 | type at; | |
779 | vfy_jclass k; | |
780 | ||
781 | if (t->key != reference_type) | |
782 | verify_fail ("internal error in type::to_array()"); | |
783 | ||
784 | k = ref_getclass (t->klass); | |
785 | init_type_from_class (&at, vfy_get_array_class (k)); | |
786 | return at; | |
787 | } | |
788 | ||
789 | static bool | |
790 | type_isreference (type *t) | |
791 | { | |
792 | return t->key >= reference_type; | |
793 | } | |
794 | ||
795 | static int | |
796 | type_get_pc (type *t) | |
797 | { | |
798 | return t->pc; | |
799 | } | |
800 | ||
801 | bool | |
802 | type_initialized (type *t) | |
803 | { | |
804 | return t->key == reference_type || t->key == null_type; | |
805 | } | |
806 | ||
36739040 TT |
807 | static void |
808 | type_verify_dimensions (type *t, int ndims) | |
809 | { | |
810 | /* The way this is written, we don't need to check isarray(). */ | |
811 | if (t->key != reference_type) | |
812 | verify_fail ("internal error in verify_dimensions:" | |
813 | " not a reference type"); | |
814 | ||
815 | if (ref_count_dimensions (t->klass) < ndims) | |
816 | verify_fail ("array type has fewer dimensions" | |
817 | " than required"); | |
818 | } | |
819 | ||
820 | /* Merge OLD_TYPE into this. On error throw exception. Return | |
821 | true if the merge caused a type change. */ | |
822 | static bool | |
823 | merge_types (type *t, type *old_type, bool local_semantics) | |
824 | { | |
825 | bool changed = false; | |
826 | bool refo = type_isreference (old_type); | |
827 | bool refn = type_isreference (t); | |
828 | if (refo && refn) | |
829 | { | |
830 | if (old_type->key == null_type) | |
831 | ; | |
832 | else if (t->key == null_type) | |
833 | { | |
834 | *t = *old_type; | |
835 | changed = true; | |
836 | } | |
837 | else if (type_initialized (t) != type_initialized (old_type)) | |
838 | verify_fail ("merging initialized and uninitialized types"); | |
839 | else | |
840 | { | |
841 | ref_intersection *merged; | |
842 | if (! type_initialized (t)) | |
843 | { | |
844 | if (t->pc == UNINIT) | |
845 | t->pc = old_type->pc; | |
846 | else if (old_type->pc == UNINIT) | |
847 | ; | |
848 | else if (t->pc != old_type->pc) | |
849 | verify_fail ("merging different uninitialized types"); | |
850 | } | |
851 | ||
852 | merged = merge_refs (old_type->klass, t->klass); | |
853 | if (merged != t->klass) | |
854 | { | |
855 | t->klass = merged; | |
856 | changed = true; | |
857 | } | |
858 | } | |
859 | } | |
860 | else if (refo || refn || t->key != old_type->key) | |
861 | { | |
862 | if (local_semantics) | |
863 | { | |
864 | /* If we already have an `unsuitable' type, then we | |
865 | don't need to change again. */ | |
866 | if (t->key != unsuitable_type) | |
867 | { | |
868 | t->key = unsuitable_type; | |
869 | changed = true; | |
870 | } | |
871 | } | |
872 | else | |
873 | verify_fail ("unmergeable type"); | |
874 | } | |
875 | return changed; | |
876 | } | |
877 | ||
878 | #ifdef VERIFY_DEBUG | |
879 | static void | |
880 | type_print (type *t) | |
881 | { | |
882 | char c = '?'; | |
883 | switch (t->key) | |
884 | { | |
885 | case boolean_type: c = 'Z'; break; | |
886 | case byte_type: c = 'B'; break; | |
887 | case char_type: c = 'C'; break; | |
888 | case short_type: c = 'S'; break; | |
889 | case int_type: c = 'I'; break; | |
890 | case long_type: c = 'J'; break; | |
891 | case float_type: c = 'F'; break; | |
892 | case double_type: c = 'D'; break; | |
893 | case void_type: c = 'V'; break; | |
894 | case unsuitable_type: c = '-'; break; | |
895 | case return_address_type: c = 'r'; break; | |
896 | case continuation_type: c = '+'; break; | |
897 | case reference_type: c = 'L'; break; | |
898 | case null_type: c = '@'; break; | |
899 | case uninitialized_reference_type: c = 'U'; break; | |
900 | } | |
901 | debug_print ("%c", c); | |
902 | } | |
903 | #endif /* VERIFY_DEBUG */ | |
904 | ||
905 | /* This class holds all the state information we need for a given | |
906 | location. */ | |
907 | struct state | |
908 | { | |
909 | /* The current top of the stack, in terms of slots. */ | |
910 | int stacktop; | |
911 | /* The current depth of the stack. This will be larger than | |
912 | STACKTOP when wide types are on the stack. */ | |
913 | int stackdepth; | |
914 | /* The stack. */ | |
915 | type *stack; | |
916 | /* The local variables. */ | |
917 | type *locals; | |
918 | /* We keep track of the type of `this' specially. This is used to | |
919 | ensure that an instance initializer invokes another initializer | |
920 | on `this' before returning. We must keep track of this | |
921 | specially because otherwise we might be confused by code which | |
922 | assigns to locals[0] (overwriting `this') and then returns | |
923 | without really initializing. */ | |
924 | type this_type; | |
925 | ||
926 | /* The PC for this state. This is only valid on states which are | |
927 | permanently attached to a given PC. For an object like | |
928 | `current_state', which is used transiently, this has no | |
929 | meaning. */ | |
930 | int pc; | |
931 | /* We keep a linked list of all states requiring reverification. | |
932 | If this is the special value INVALID_STATE then this state is | |
933 | not on the list. NULL marks the end of the linked list. */ | |
934 | state *next; | |
935 | }; | |
936 | ||
937 | /* NO_NEXT is the PC value meaning that a new state must be | |
938 | acquired from the verification list. */ | |
939 | #define NO_NEXT -1 | |
940 | ||
36739040 TT |
941 | static void |
942 | init_state_with_stack (state *s, int max_stack, int max_locals) | |
943 | { | |
944 | int i; | |
945 | s->stacktop = 0; | |
946 | s->stackdepth = 0; | |
947 | s->stack = (type *) vfy_alloc (max_stack * sizeof (type)); | |
948 | for (i = 0; i < max_stack; ++i) | |
949 | init_type_from_tag (&s->stack[i], unsuitable_type); | |
950 | s->locals = (type *) vfy_alloc (max_locals * sizeof (type)); | |
951 | for (i = 0; i < max_locals; ++i) | |
952 | init_type_from_tag (&s->locals[i], unsuitable_type); | |
953 | init_type_from_tag (&s->this_type, unsuitable_type); | |
954 | s->pc = NO_NEXT; | |
955 | s->next = INVALID_STATE; | |
956 | } | |
957 | ||
958 | static void | |
959 | copy_state (state *s, state *copy, int max_stack, int max_locals) | |
960 | { | |
961 | int i; | |
962 | s->stacktop = copy->stacktop; | |
963 | s->stackdepth = copy->stackdepth; | |
964 | for (i = 0; i < max_stack; ++i) | |
965 | s->stack[i] = copy->stack[i]; | |
966 | for (i = 0; i < max_locals; ++i) | |
967 | s->locals[i] = copy->locals[i]; | |
968 | ||
969 | s->this_type = copy->this_type; | |
970 | /* Don't modify `next' or `pc'. */ | |
971 | } | |
972 | ||
973 | static void | |
974 | copy_state_with_stack (state *s, state *orig, int max_stack, int max_locals) | |
975 | { | |
976 | init_state_with_stack (s, max_stack, max_locals); | |
977 | copy_state (s, orig, max_stack, max_locals); | |
978 | } | |
979 | ||
980 | /* Allocate a new state, copying ORIG. */ | |
981 | static state * | |
982 | make_state_copy (state *orig, int max_stack, int max_locals) | |
983 | { | |
e1e4cdc4 | 984 | state *s = (state *) vfy_alloc (sizeof (state)); |
36739040 TT |
985 | copy_state_with_stack (s, orig, max_stack, max_locals); |
986 | return s; | |
987 | } | |
988 | ||
989 | static state * | |
990 | make_state (int max_stack, int max_locals) | |
991 | { | |
e1e4cdc4 | 992 | state *s = (state *) vfy_alloc (sizeof (state)); |
36739040 TT |
993 | init_state_with_stack (s, max_stack, max_locals); |
994 | return s; | |
995 | } | |
996 | ||
36739040 TT |
997 | static void |
998 | free_state (state *s) | |
999 | { | |
1000 | if (s->stack != NULL) | |
1001 | vfy_free (s->stack); | |
1002 | if (s->locals != NULL) | |
1003 | vfy_free (s->locals); | |
1004 | } | |
36739040 TT |
1005 | |
1006 | /* Modify this state to reflect entry to an exception handler. */ | |
1007 | static void | |
1008 | state_set_exception (state *s, type *t, int max_stack) | |
1009 | { | |
1010 | int i; | |
1011 | s->stackdepth = 1; | |
1012 | s->stacktop = 1; | |
1013 | s->stack[0] = *t; | |
1014 | for (i = s->stacktop; i < max_stack; ++i) | |
1015 | init_type_from_tag (&s->stack[i], unsuitable_type); | |
1016 | } | |
1017 | ||
36739040 TT |
1018 | /* Merge STATE_OLD into this state. Destructively modifies this |
1019 | state. Returns true if the new state was in fact changed. | |
1020 | Will throw an exception if the states are not mergeable. */ | |
1021 | static bool | |
1022 | merge_states (state *s, state *state_old, int max_locals) | |
1023 | { | |
1024 | int i; | |
1025 | bool changed = false; | |
1026 | ||
1027 | /* Special handling for `this'. If one or the other is | |
1028 | uninitialized, then the merge is uninitialized. */ | |
1029 | if (type_initialized (&s->this_type)) | |
1030 | s->this_type = state_old->this_type; | |
1031 | ||
1032 | /* Merge stacks. */ | |
1033 | if (state_old->stacktop != s->stacktop) /* FIXME stackdepth instead? */ | |
1034 | verify_fail ("stack sizes differ"); | |
1035 | for (i = 0; i < state_old->stacktop; ++i) | |
1036 | { | |
1037 | if (merge_types (&s->stack[i], &state_old->stack[i], false)) | |
1038 | changed = true; | |
1039 | } | |
1040 | ||
1041 | /* Merge local variables. */ | |
1042 | for (i = 0; i < max_locals; ++i) | |
1043 | { | |
1044 | if (merge_types (&s->locals[i], &state_old->locals[i], true)) | |
1045 | changed = true; | |
1046 | } | |
1047 | ||
1048 | return changed; | |
1049 | } | |
1050 | ||
1051 | /* Ensure that `this' has been initialized. */ | |
1052 | static void | |
1053 | state_check_this_initialized (state *s) | |
1054 | { | |
1055 | if (type_isreference (&s->this_type) && ! type_initialized (&s->this_type)) | |
1056 | verify_fail ("`this' is uninitialized"); | |
1057 | } | |
1058 | ||
1059 | /* Set type of `this'. */ | |
1060 | static void | |
1061 | state_set_this_type (state *s, type *k) | |
1062 | { | |
1063 | s->this_type = *k; | |
1064 | } | |
1065 | ||
1066 | /* Mark each `new'd object we know of that was allocated at PC as | |
1067 | initialized. */ | |
1068 | static void | |
1069 | state_set_initialized (state *s, int pc, int max_locals) | |
1070 | { | |
1071 | int i; | |
1072 | for (i = 0; i < s->stacktop; ++i) | |
1073 | type_set_initialized (&s->stack[i], pc); | |
1074 | for (i = 0; i < max_locals; ++i) | |
1075 | type_set_initialized (&s->locals[i], pc); | |
1076 | type_set_initialized (&s->this_type, pc); | |
1077 | } | |
1078 | ||
1079 | /* This tests to see whether two states can be considered "merge | |
1080 | compatible". If both states have a return-address in the same | |
1081 | slot, and the return addresses are different, then they are not | |
1082 | compatible and we must not try to merge them. */ | |
1083 | static bool | |
1084 | state_mergeable_p (state *s, state *other, int max_locals) | |
1085 | ||
1086 | { | |
1087 | int i; | |
1088 | ||
1089 | /* This is tricky: if the stack sizes differ, then not only are | |
1090 | these not mergeable, but in fact we should give an error, as | |
1091 | we've found two execution paths that reach a branch target | |
1092 | with different stack depths. FIXME stackdepth instead? */ | |
1093 | if (s->stacktop != other->stacktop) | |
1094 | verify_fail ("stack sizes differ"); | |
1095 | ||
1096 | for (i = 0; i < s->stacktop; ++i) | |
1097 | if (! type_state_mergeable_p (&s->stack[i], &other->stack[i])) | |
1098 | return false; | |
1099 | for (i = 0; i < max_locals; ++i) | |
1100 | if (! type_state_mergeable_p (&s->locals[i], &other->locals[i])) | |
1101 | return false; | |
1102 | return true; | |
1103 | } | |
1104 | ||
1105 | static void | |
1106 | state_reverify (state *s) | |
1107 | { | |
1108 | if (s->next == INVALID_STATE) | |
1109 | { | |
1110 | s->next = vfr->next_verify_state; | |
1111 | vfr->next_verify_state = s; | |
1112 | } | |
1113 | } | |
1114 | ||
1115 | #ifdef VERIFY_DEBUG | |
1116 | static void | |
1117 | debug_print_state (state *s, const char *leader, int pc, int max_stack, | |
1118 | int max_locals) | |
1119 | { | |
1120 | int i; | |
1121 | debug_print ("%s [%4d]: [stack] ", leader, pc); | |
1122 | for (i = 0; i < s->stacktop; ++i) | |
1123 | type_print (&s->stack[i]); | |
1124 | for (; i < max_stack; ++i) | |
1125 | debug_print ("."); | |
1126 | debug_print (" [local] "); | |
1127 | for (i = 0; i < max_locals; ++i) | |
1128 | type_print (&s->locals[i]); | |
1129 | debug_print (" | %p\n", s); | |
1130 | } | |
1131 | #else | |
1132 | static void | |
1133 | debug_print_state (state *s ATTRIBUTE_UNUSED, | |
1134 | const char *leader ATTRIBUTE_UNUSED, | |
1135 | int pc ATTRIBUTE_UNUSED, int max_stack ATTRIBUTE_UNUSED, | |
1136 | int max_locals ATTRIBUTE_UNUSED) | |
1137 | { | |
1138 | } | |
1139 | #endif /* VERIFY_DEBUG */ | |
1140 | ||
1141 | static type | |
1142 | pop_raw (void) | |
1143 | { | |
1144 | type r; | |
1145 | state *s = vfr->current_state; | |
1146 | if (s->stacktop <= 0) | |
1147 | verify_fail ("stack empty"); | |
1148 | r = s->stack[--s->stacktop]; | |
1149 | s->stackdepth -= type_depth (&r); | |
1150 | if (s->stackdepth < 0) | |
1151 | verify_fail_pc ("stack empty", vfr->start_PC); | |
1152 | return r; | |
1153 | } | |
1154 | ||
1155 | static type | |
1156 | pop32 (void) | |
1157 | { | |
1158 | type r = pop_raw (); | |
1159 | if (type_iswide (&r)) | |
1160 | verify_fail ("narrow pop of wide type"); | |
1161 | return r; | |
1162 | } | |
1163 | ||
1164 | static type | |
1165 | vfy_pop_type_t (type match) | |
1166 | { | |
1167 | type t; | |
1168 | vfy_promote_type (&match); | |
1169 | t = pop_raw (); | |
1170 | if (! types_compatible (&match, &t)) | |
1171 | verify_fail ("incompatible type on stack"); | |
1172 | return t; | |
1173 | } | |
1174 | ||
1175 | static type | |
1176 | vfy_pop_type (type_val match) | |
1177 | { | |
1178 | type t = make_type (match); | |
1179 | return vfy_pop_type_t (t); | |
1180 | } | |
1181 | ||
1182 | #define pop_type vfy_pop_type | |
1183 | #define pop_type_t vfy_pop_type_t | |
1184 | ||
1185 | /* Pop a reference which is guaranteed to be initialized. MATCH | |
1186 | doesn't have to be a reference type; in this case this acts like | |
1187 | pop_type. */ | |
1188 | static type | |
1189 | pop_init_ref_t (type match) | |
1190 | { | |
1191 | type t = pop_raw (); | |
1192 | if (type_isreference (&t) && ! type_initialized (&t)) | |
1193 | verify_fail ("initialized reference required"); | |
1194 | else if (! types_compatible (&match, &t)) | |
1195 | verify_fail ("incompatible type on stack"); | |
1196 | return t; | |
1197 | } | |
1198 | ||
1199 | static type | |
1200 | pop_init_ref (type_val match) | |
1201 | { | |
1202 | type t = make_type (match); | |
1203 | return pop_init_ref_t (t); | |
1204 | } | |
1205 | ||
1206 | /* Pop a reference type or a return address. */ | |
1207 | static type | |
1208 | pop_ref_or_return (void) | |
1209 | { | |
1210 | type t = pop_raw (); | |
1211 | if (! type_isreference (&t) && t.key != return_address_type) | |
1212 | verify_fail ("expected reference or return address on stack"); | |
1213 | return t; | |
1214 | } | |
1215 | ||
1216 | static void | |
1217 | vfy_push_type_t (type t) | |
1218 | { | |
1219 | int depth; | |
1220 | state *s = vfr->current_state; | |
1221 | /* If T is a numeric type like short, promote it to int. */ | |
1222 | promote_type (&t); | |
1223 | ||
1224 | depth = type_depth (&t); | |
1225 | ||
1226 | if (s->stackdepth + depth > vfr->current_method->max_stack) | |
1227 | verify_fail ("stack overflow"); | |
1228 | s->stack[s->stacktop++] = t; | |
1229 | s->stackdepth += depth; | |
1230 | } | |
1231 | ||
1232 | static void | |
1233 | vfy_push_type (type_val tval) | |
1234 | { | |
1235 | type t = make_type (tval); | |
528d9c63 | 1236 | vfy_push_type_t (t); |
36739040 TT |
1237 | } |
1238 | ||
1239 | #define push_type vfy_push_type | |
1240 | #define push_type_t vfy_push_type_t | |
1241 | ||
1242 | static void | |
1243 | set_variable (int index, type t) | |
1244 | { | |
1245 | int depth; | |
1246 | state *s = vfr->current_state; | |
1247 | /* If T is a numeric type like short, promote it to int. */ | |
1248 | promote_type (&t); | |
1249 | ||
1250 | depth = type_depth (&t); | |
1251 | if (index > vfr->current_method->max_locals - depth) | |
1252 | verify_fail ("invalid local variable"); | |
1253 | s->locals[index] = t; | |
1254 | ||
1255 | if (depth == 2) | |
1256 | init_type_from_tag (&s->locals[index + 1], continuation_type); | |
1257 | if (index > 0 && type_iswide (&s->locals[index - 1])) | |
1258 | init_type_from_tag (&s->locals[index - 1], unsuitable_type); | |
1259 | } | |
1260 | ||
1261 | static type | |
1262 | get_variable_t (int index, type *t) | |
1263 | { | |
1264 | state *s = vfr->current_state; | |
1265 | int depth = type_depth (t); | |
1266 | if (index > vfr->current_method->max_locals - depth) | |
1267 | verify_fail ("invalid local variable"); | |
1268 | if (! types_compatible (t, &s->locals[index])) | |
1269 | verify_fail ("incompatible type in local variable"); | |
1270 | if (depth == 2) | |
1271 | { | |
1272 | type cont = make_type (continuation_type); | |
1273 | if (! types_compatible (&s->locals[index + 1], &cont)) | |
1274 | verify_fail ("invalid local variable"); | |
1275 | } | |
1276 | return s->locals[index]; | |
1277 | } | |
1278 | ||
1279 | static type | |
1280 | get_variable (int index, type_val v) | |
1281 | { | |
1282 | type t = make_type (v); | |
1283 | return get_variable_t (index, &t); | |
1284 | } | |
1285 | ||
1286 | /* Make sure ARRAY is an array type and that its elements are | |
1287 | compatible with type ELEMENT. Returns the actual element type. */ | |
1288 | static type | |
1289 | require_array_type_t (type array, type element) | |
1290 | { | |
1291 | type t; | |
1292 | /* An odd case. Here we just pretend that everything went ok. If | |
1293 | the requested element type is some kind of reference, return | |
1294 | the null type instead. */ | |
1295 | if (type_isnull (&array)) | |
1296 | return type_isreference (&element) ? make_type (null_type) : element; | |
1297 | ||
1298 | if (! type_isarray (&array)) | |
1299 | verify_fail ("array required"); | |
1300 | ||
1301 | t = type_array_element (&array); | |
1302 | if (! types_compatible (&element, &t)) | |
1303 | { | |
1304 | /* Special case for byte arrays, which must also be boolean | |
1305 | arrays. */ | |
1306 | bool ok = true; | |
1307 | if (element.key == byte_type) | |
1308 | { | |
1309 | type e2 = make_type (boolean_type); | |
1310 | ok = types_compatible (&e2, &t); | |
1311 | } | |
1312 | if (! ok) | |
1313 | verify_fail ("incompatible array element type"); | |
1314 | } | |
1315 | ||
1316 | /* Return T and not ELEMENT, because T might be specialized. */ | |
1317 | return t; | |
1318 | } | |
1319 | ||
1320 | static type | |
1321 | require_array_type (type array, type_val element) | |
1322 | { | |
1323 | type t = make_type (element); | |
1324 | return require_array_type_t (array, t); | |
1325 | } | |
1326 | ||
1327 | static jint | |
1328 | get_byte (void) | |
1329 | { | |
1330 | if (vfr->PC >= vfr->current_method->code_length) | |
1331 | verify_fail ("premature end of bytecode"); | |
1332 | return (jint) vfr->bytecode[vfr->PC++] & 0xff; | |
1333 | } | |
1334 | ||
1335 | static jint | |
1336 | get_ushort (void) | |
1337 | { | |
1338 | jint b1 = get_byte (); | |
1339 | jint b2 = get_byte (); | |
1340 | return (jint) ((b1 << 8) | b2) & 0xffff; | |
1341 | } | |
1342 | ||
1343 | static jint | |
1344 | get_short (void) | |
1345 | { | |
6db1446e | 1346 | signed char b1 = (signed char) get_byte (); |
36739040 TT |
1347 | jint b2 = get_byte (); |
1348 | jshort s = (b1 << 8) | b2; | |
1349 | return (jint) s; | |
1350 | } | |
1351 | ||
1352 | static jint | |
1353 | get_int (void) | |
1354 | { | |
1355 | jint b1 = get_byte (); | |
1356 | jint b2 = get_byte (); | |
1357 | jint b3 = get_byte (); | |
1358 | jint b4 = get_byte (); | |
6db1446e TT |
1359 | jword result = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; |
1360 | /* In the compiler, 'jint' might have more than 32 bits, so we must | |
1361 | sign extend. */ | |
1362 | return WORD_TO_INT (result); | |
36739040 TT |
1363 | } |
1364 | ||
1365 | static int | |
1366 | compute_jump (int offset) | |
1367 | { | |
1368 | int npc = vfr->start_PC + offset; | |
1369 | if (npc < 0 || npc >= vfr->current_method->code_length) | |
1370 | verify_fail_pc ("branch out of range", vfr->start_PC); | |
1371 | return npc; | |
1372 | } | |
1373 | ||
1374 | /* Add a new state to the state list at NPC. */ | |
1375 | static state * | |
1376 | add_new_state (int npc, state *old_state) | |
1377 | { | |
1378 | state_list *nlink; | |
1379 | vfy_method *current_method = vfr->current_method; | |
1380 | state *new_state = make_state_copy (old_state, current_method->max_stack, | |
1381 | current_method->max_locals); | |
1382 | debug_print ("== New state in add_new_state\n"); | |
1383 | debug_print_state (new_state, "New", npc, current_method->max_stack, | |
1384 | current_method->max_locals); | |
1385 | ||
e1e4cdc4 | 1386 | nlink = (state_list *) vfy_alloc (sizeof (state_list)); |
36739040 TT |
1387 | nlink->val = new_state; |
1388 | nlink->next = vfr->states[npc]; | |
1389 | vfr->states[npc] = nlink; | |
1390 | new_state->pc = npc; | |
1391 | return new_state; | |
1392 | } | |
1393 | ||
1394 | /* Merge the indicated state into the state at the branch target and | |
1395 | schedule a new PC if there is a change. NPC is the PC of the | |
1396 | branch target, and FROM_STATE is the state at the source of the | |
1397 | branch. This method returns true if the destination state | |
1398 | changed and requires reverification, false otherwise. */ | |
1399 | static void | |
1400 | merge_into (int npc, state *from_state) | |
1401 | { | |
1402 | /* Iterate over all target states and merge our state into each, | |
1403 | if applicable. FIXME one improvement we could make here is | |
1404 | "state destruction". Merging a new state into an existing one | |
1405 | might cause a return_address_type to be merged to | |
1406 | unsuitable_type. In this case the resulting state may now be | |
1407 | mergeable with other states currently held in parallel at this | |
1408 | location. So in this situation we could pairwise compare and | |
1409 | reduce the number of parallel states. */ | |
1410 | state_list *iter; | |
1411 | bool applicable = false; | |
1412 | for (iter = vfr->states[npc]; iter != NULL; iter = iter->next) | |
1413 | { | |
1414 | state *new_state = iter->val; | |
1415 | vfy_method *current_method = vfr->current_method; | |
1416 | ||
1417 | if (state_mergeable_p (new_state, from_state, | |
1418 | current_method->max_locals)) | |
1419 | { | |
1420 | bool changed; | |
1421 | applicable = true; | |
1422 | ||
1423 | debug_print ("== Merge states in merge_into\n"); | |
1424 | debug_print_state (from_state, "Frm", vfr->start_PC, current_method->max_stack, | |
1425 | current_method->max_locals); | |
1426 | debug_print_state (new_state, " To", npc, current_method->max_stack, | |
1427 | current_method->max_locals); | |
1428 | changed = merge_states (new_state, from_state, | |
1429 | current_method->max_locals); | |
1430 | debug_print_state (new_state, "New", npc, current_method->max_stack, | |
1431 | current_method->max_locals); | |
1432 | ||
1433 | if (changed) | |
1434 | state_reverify (new_state); | |
1435 | } | |
1436 | } | |
1437 | ||
1438 | if (! applicable) | |
1439 | { | |
1440 | /* Either we don't yet have a state at NPC, or we have a | |
1441 | return-address type that is in conflict with all existing | |
1442 | state. So, we need to create a new entry. */ | |
1443 | state *new_state = add_new_state (npc, from_state); | |
1444 | /* A new state added in this way must always be reverified. */ | |
1445 | state_reverify (new_state); | |
1446 | } | |
1447 | } | |
1448 | ||
1449 | static void | |
1450 | push_jump (int offset) | |
1451 | { | |
1452 | int npc = compute_jump (offset); | |
1453 | /* According to the JVM Spec, we need to check for uninitialized | |
1454 | objects here. However, this does not actually affect type | |
1455 | safety, and the Eclipse java compiler generates code that | |
1456 | violates this constraint. */ | |
1457 | merge_into (npc, vfr->current_state); | |
1458 | } | |
1459 | ||
1460 | static void | |
1461 | push_exception_jump (type t, int pc) | |
1462 | { | |
1463 | state s; | |
1464 | /* According to the JVM Spec, we need to check for uninitialized | |
1465 | objects here. However, this does not actually affect type | |
1466 | safety, and the Eclipse java compiler generates code that | |
1467 | violates this constraint. */ | |
1468 | copy_state_with_stack (&s, vfr->current_state, | |
1469 | vfr->current_method->max_stack, | |
1470 | vfr->current_method->max_locals); | |
1471 | if (vfr->current_method->max_stack < 1) | |
1472 | verify_fail ("stack overflow at exception handler"); | |
1473 | state_set_exception (&s, &t, vfr->current_method->max_stack); | |
1474 | merge_into (pc, &s); | |
1475 | /* FIXME: leak.. need free_state or GC */ | |
1476 | } | |
1477 | ||
1478 | static state * | |
1479 | pop_jump (void) | |
1480 | { | |
1481 | state *new_state = vfr->next_verify_state; | |
1482 | if (new_state == INVALID_STATE) | |
1483 | verify_fail ("programmer error in pop_jump"); | |
1484 | if (new_state != NULL) | |
1485 | { | |
1486 | vfr->next_verify_state = new_state->next; | |
1487 | new_state->next = INVALID_STATE; | |
1488 | } | |
1489 | return new_state; | |
1490 | } | |
1491 | ||
1492 | static void | |
1493 | invalidate_pc (void) | |
1494 | { | |
1495 | vfr->PC = NO_NEXT; | |
1496 | } | |
1497 | ||
1498 | static void | |
1499 | note_branch_target (int pc) | |
1500 | { | |
1501 | /* Don't check `pc <= PC', because we've advanced PC after | |
1502 | fetching the target and we haven't yet checked the next | |
1503 | instruction. */ | |
1504 | if (pc < vfr->PC && ! (vfr->flags[pc] & FLAG_INSN_START)) | |
1505 | verify_fail_pc ("branch not to instruction start", vfr->start_PC); | |
1506 | vfr->flags[pc] |= FLAG_BRANCH_TARGET; | |
1507 | } | |
1508 | ||
1509 | static void | |
1510 | skip_padding (void) | |
1511 | { | |
1512 | while ((vfr->PC % 4) > 0) | |
1513 | if (get_byte () != 0) | |
1514 | verify_fail ("found nonzero padding byte"); | |
1515 | } | |
1516 | ||
1517 | /* Do the work for a `ret' instruction. INDEX is the index into the | |
1518 | local variables. */ | |
1519 | static void | |
1520 | handle_ret_insn (int index) | |
1521 | { | |
1522 | type ret = make_type (return_address_type); | |
1523 | type ret_addr = get_variable_t (index, &ret); | |
1524 | /* It would be nice if we could do this. However, the JVM Spec | |
1525 | doesn't say that this is what happens. It is implied that | |
1526 | reusing a return address is invalid, but there's no actual | |
1527 | prohibition against it. */ | |
1528 | /* set_variable (index, unsuitable_type); */ | |
1529 | ||
1530 | int npc = type_get_pc (&ret_addr); | |
1531 | /* We might be returning to a `jsr' that is at the end of the | |
1532 | bytecode. This is ok if we never return from the called | |
1533 | subroutine, but if we see this here it is an error. */ | |
1534 | if (npc >= vfr->current_method->code_length) | |
1535 | verify_fail ("fell off end"); | |
1536 | ||
1537 | /* According to the JVM Spec, we need to check for uninitialized | |
1538 | objects here. However, this does not actually affect type | |
1539 | safety, and the Eclipse java compiler generates code that | |
1540 | violates this constraint. */ | |
1541 | merge_into (npc, vfr->current_state); | |
1542 | invalidate_pc (); | |
1543 | } | |
1544 | ||
1545 | static void handle_jsr_insn (int offset) | |
1546 | { | |
1547 | type ret_addr; | |
1548 | int npc = compute_jump (offset); | |
1549 | ||
1550 | /* According to the JVM Spec, we need to check for uninitialized | |
1551 | objects here. However, this does not actually affect type | |
1552 | safety, and the Eclipse java compiler generates code that | |
1553 | violates this constraint. */ | |
1554 | ||
1555 | /* Modify our state as appropriate for entry into a subroutine. */ | |
1556 | ret_addr = make_type (return_address_type); | |
1557 | type_set_return_address (&ret_addr, vfr->PC); | |
1558 | vfy_push_type_t (ret_addr); | |
1559 | merge_into (npc, vfr->current_state); | |
1560 | invalidate_pc (); | |
1561 | } | |
1562 | ||
1563 | static vfy_jclass | |
1564 | construct_primitive_array_type (type_val prim) | |
1565 | { | |
1566 | vfy_jclass k = NULL; | |
1567 | switch (prim) | |
1568 | { | |
1569 | case boolean_type: | |
1570 | case char_type: | |
1571 | case float_type: | |
1572 | case double_type: | |
1573 | case byte_type: | |
1574 | case short_type: | |
1575 | case int_type: | |
1576 | case long_type: | |
1577 | k = vfy_get_primitive_type ((int) prim); | |
1578 | break; | |
1579 | ||
1580 | /* These aren't used here but we call them out to avoid | |
1581 | warnings. */ | |
1582 | case void_type: | |
1583 | case unsuitable_type: | |
1584 | case return_address_type: | |
1585 | case continuation_type: | |
1586 | case reference_type: | |
1587 | case null_type: | |
1588 | case uninitialized_reference_type: | |
1589 | default: | |
1590 | verify_fail ("unknown type in construct_primitive_array_type"); | |
1591 | } | |
1592 | k = vfy_get_array_class (k); | |
1593 | return k; | |
1594 | } | |
1595 | ||
1596 | /* This pass computes the location of branch targets and also | |
1597 | instruction starts. */ | |
1598 | static void | |
1599 | branch_prepass (void) | |
1600 | { | |
1601 | int i, pc; | |
1602 | vfr->flags = (char *) vfy_alloc (vfr->current_method->code_length); | |
1603 | ||
1604 | for (i = 0; i < vfr->current_method->code_length; ++i) | |
1605 | vfr->flags[i] = 0; | |
1606 | ||
1607 | vfr->PC = 0; | |
1608 | while (vfr->PC < vfr->current_method->code_length) | |
1609 | { | |
1610 | java_opcode opcode; | |
1611 | /* Set `start_PC' early so that error checking can have the | |
1612 | correct value. */ | |
1613 | vfr->start_PC = vfr->PC; | |
1614 | vfr->flags[vfr->PC] |= FLAG_INSN_START; | |
1615 | ||
1616 | opcode = (java_opcode) vfr->bytecode[vfr->PC++]; | |
1617 | switch (opcode) | |
1618 | { | |
1619 | case op_nop: | |
1620 | case op_aconst_null: | |
1621 | case op_iconst_m1: | |
1622 | case op_iconst_0: | |
1623 | case op_iconst_1: | |
1624 | case op_iconst_2: | |
1625 | case op_iconst_3: | |
1626 | case op_iconst_4: | |
1627 | case op_iconst_5: | |
1628 | case op_lconst_0: | |
1629 | case op_lconst_1: | |
1630 | case op_fconst_0: | |
1631 | case op_fconst_1: | |
1632 | case op_fconst_2: | |
1633 | case op_dconst_0: | |
1634 | case op_dconst_1: | |
1635 | case op_iload_0: | |
1636 | case op_iload_1: | |
1637 | case op_iload_2: | |
1638 | case op_iload_3: | |
1639 | case op_lload_0: | |
1640 | case op_lload_1: | |
1641 | case op_lload_2: | |
1642 | case op_lload_3: | |
1643 | case op_fload_0: | |
1644 | case op_fload_1: | |
1645 | case op_fload_2: | |
1646 | case op_fload_3: | |
1647 | case op_dload_0: | |
1648 | case op_dload_1: | |
1649 | case op_dload_2: | |
1650 | case op_dload_3: | |
1651 | case op_aload_0: | |
1652 | case op_aload_1: | |
1653 | case op_aload_2: | |
1654 | case op_aload_3: | |
1655 | case op_iaload: | |
1656 | case op_laload: | |
1657 | case op_faload: | |
1658 | case op_daload: | |
1659 | case op_aaload: | |
1660 | case op_baload: | |
1661 | case op_caload: | |
1662 | case op_saload: | |
1663 | case op_istore_0: | |
1664 | case op_istore_1: | |
1665 | case op_istore_2: | |
1666 | case op_istore_3: | |
1667 | case op_lstore_0: | |
1668 | case op_lstore_1: | |
1669 | case op_lstore_2: | |
1670 | case op_lstore_3: | |
1671 | case op_fstore_0: | |
1672 | case op_fstore_1: | |
1673 | case op_fstore_2: | |
1674 | case op_fstore_3: | |
1675 | case op_dstore_0: | |
1676 | case op_dstore_1: | |
1677 | case op_dstore_2: | |
1678 | case op_dstore_3: | |
1679 | case op_astore_0: | |
1680 | case op_astore_1: | |
1681 | case op_astore_2: | |
1682 | case op_astore_3: | |
1683 | case op_iastore: | |
1684 | case op_lastore: | |
1685 | case op_fastore: | |
1686 | case op_dastore: | |
1687 | case op_aastore: | |
1688 | case op_bastore: | |
1689 | case op_castore: | |
1690 | case op_sastore: | |
1691 | case op_pop: | |
1692 | case op_pop2: | |
1693 | case op_dup: | |
1694 | case op_dup_x1: | |
1695 | case op_dup_x2: | |
1696 | case op_dup2: | |
1697 | case op_dup2_x1: | |
1698 | case op_dup2_x2: | |
1699 | case op_swap: | |
1700 | case op_iadd: | |
1701 | case op_isub: | |
1702 | case op_imul: | |
1703 | case op_idiv: | |
1704 | case op_irem: | |
1705 | case op_ishl: | |
1706 | case op_ishr: | |
1707 | case op_iushr: | |
1708 | case op_iand: | |
1709 | case op_ior: | |
1710 | case op_ixor: | |
1711 | case op_ladd: | |
1712 | case op_lsub: | |
1713 | case op_lmul: | |
1714 | case op_ldiv: | |
1715 | case op_lrem: | |
1716 | case op_lshl: | |
1717 | case op_lshr: | |
1718 | case op_lushr: | |
1719 | case op_land: | |
1720 | case op_lor: | |
1721 | case op_lxor: | |
1722 | case op_fadd: | |
1723 | case op_fsub: | |
1724 | case op_fmul: | |
1725 | case op_fdiv: | |
1726 | case op_frem: | |
1727 | case op_dadd: | |
1728 | case op_dsub: | |
1729 | case op_dmul: | |
1730 | case op_ddiv: | |
1731 | case op_drem: | |
1732 | case op_ineg: | |
1733 | case op_i2b: | |
1734 | case op_i2c: | |
1735 | case op_i2s: | |
1736 | case op_lneg: | |
1737 | case op_fneg: | |
1738 | case op_dneg: | |
1739 | case op_i2l: | |
1740 | case op_i2f: | |
1741 | case op_i2d: | |
1742 | case op_l2i: | |
1743 | case op_l2f: | |
1744 | case op_l2d: | |
1745 | case op_f2i: | |
1746 | case op_f2l: | |
1747 | case op_f2d: | |
1748 | case op_d2i: | |
1749 | case op_d2l: | |
1750 | case op_d2f: | |
1751 | case op_lcmp: | |
1752 | case op_fcmpl: | |
1753 | case op_fcmpg: | |
1754 | case op_dcmpl: | |
1755 | case op_dcmpg: | |
1756 | case op_monitorenter: | |
1757 | case op_monitorexit: | |
1758 | case op_ireturn: | |
1759 | case op_lreturn: | |
1760 | case op_freturn: | |
1761 | case op_dreturn: | |
1762 | case op_areturn: | |
1763 | case op_return: | |
1764 | case op_athrow: | |
1765 | case op_arraylength: | |
1766 | break; | |
1767 | ||
1768 | case op_bipush: | |
1769 | case op_ldc: | |
1770 | case op_iload: | |
1771 | case op_lload: | |
1772 | case op_fload: | |
1773 | case op_dload: | |
1774 | case op_aload: | |
1775 | case op_istore: | |
1776 | case op_lstore: | |
1777 | case op_fstore: | |
1778 | case op_dstore: | |
1779 | case op_astore: | |
1780 | case op_ret: | |
1781 | case op_newarray: | |
1782 | get_byte (); | |
1783 | break; | |
1784 | ||
1785 | case op_iinc: | |
1786 | case op_sipush: | |
1787 | case op_ldc_w: | |
1788 | case op_ldc2_w: | |
1789 | case op_getstatic: | |
1790 | case op_getfield: | |
1791 | case op_putfield: | |
1792 | case op_putstatic: | |
1793 | case op_new: | |
1794 | case op_anewarray: | |
1795 | case op_instanceof: | |
1796 | case op_checkcast: | |
1797 | case op_invokespecial: | |
1798 | case op_invokestatic: | |
1799 | case op_invokevirtual: | |
1800 | get_short (); | |
1801 | break; | |
1802 | ||
1803 | case op_multianewarray: | |
1804 | get_short (); | |
1805 | get_byte (); | |
1806 | break; | |
1807 | ||
1808 | case op_jsr: | |
1809 | case op_ifeq: | |
1810 | case op_ifne: | |
1811 | case op_iflt: | |
1812 | case op_ifge: | |
1813 | case op_ifgt: | |
1814 | case op_ifle: | |
1815 | case op_if_icmpeq: | |
1816 | case op_if_icmpne: | |
1817 | case op_if_icmplt: | |
1818 | case op_if_icmpge: | |
1819 | case op_if_icmpgt: | |
1820 | case op_if_icmple: | |
1821 | case op_if_acmpeq: | |
1822 | case op_if_acmpne: | |
1823 | case op_ifnull: | |
1824 | case op_ifnonnull: | |
1825 | case op_goto: | |
1826 | note_branch_target (compute_jump (get_short ())); | |
1827 | break; | |
1828 | ||
1829 | case op_tableswitch: | |
1830 | { | |
1831 | jint low, hi; | |
1832 | skip_padding (); | |
1833 | note_branch_target (compute_jump (get_int ())); | |
1834 | low = get_int (); | |
1835 | hi = get_int (); | |
1836 | if (low > hi) | |
1837 | verify_fail_pc ("invalid tableswitch", vfr->start_PC); | |
1838 | for (i = low; i <= hi; ++i) | |
1839 | note_branch_target (compute_jump (get_int ())); | |
1840 | } | |
1841 | break; | |
1842 | ||
1843 | case op_lookupswitch: | |
1844 | { | |
1845 | int npairs; | |
1846 | skip_padding (); | |
1847 | note_branch_target (compute_jump (get_int ())); | |
1848 | npairs = get_int (); | |
1849 | if (npairs < 0) | |
1850 | verify_fail_pc ("too few pairs in lookupswitch", vfr->start_PC); | |
1851 | while (npairs-- > 0) | |
1852 | { | |
1853 | get_int (); | |
1854 | note_branch_target (compute_jump (get_int ())); | |
1855 | } | |
1856 | } | |
1857 | break; | |
1858 | ||
1859 | case op_invokeinterface: | |
1860 | get_short (); | |
1861 | get_byte (); | |
1862 | get_byte (); | |
1863 | break; | |
1864 | ||
1865 | case op_wide: | |
1866 | { | |
1867 | opcode = (java_opcode) get_byte (); | |
1868 | get_short (); | |
1869 | if (opcode == op_iinc) | |
1870 | get_short (); | |
1871 | } | |
1872 | break; | |
1873 | ||
1874 | case op_jsr_w: | |
1875 | case op_goto_w: | |
1876 | note_branch_target (compute_jump (get_int ())); | |
1877 | break; | |
1878 | ||
1879 | #if 0 | |
1880 | /* These are unused here, but we call them out explicitly | |
1881 | so that -Wswitch-enum doesn't complain. */ | |
1882 | case op_putfield_1: | |
1883 | case op_putfield_2: | |
1884 | case op_putfield_4: | |
1885 | case op_putfield_8: | |
1886 | case op_putfield_a: | |
1887 | case op_putstatic_1: | |
1888 | case op_putstatic_2: | |
1889 | case op_putstatic_4: | |
1890 | case op_putstatic_8: | |
1891 | case op_putstatic_a: | |
1892 | case op_getfield_1: | |
1893 | case op_getfield_2s: | |
1894 | case op_getfield_2u: | |
1895 | case op_getfield_4: | |
1896 | case op_getfield_8: | |
1897 | case op_getfield_a: | |
1898 | case op_getstatic_1: | |
1899 | case op_getstatic_2s: | |
1900 | case op_getstatic_2u: | |
1901 | case op_getstatic_4: | |
1902 | case op_getstatic_8: | |
1903 | case op_getstatic_a: | |
1904 | #endif /* VFY_FAST_OPCODES */ | |
1905 | default: | |
1906 | verify_fail_pc ("unrecognized instruction in branch_prepass", | |
1907 | vfr->start_PC); | |
1908 | } | |
1909 | ||
1910 | /* See if any previous branch tried to branch to the middle of | |
1911 | this instruction. */ | |
1912 | for (pc = vfr->start_PC + 1; pc < vfr->PC; ++pc) | |
1913 | { | |
1914 | if ((vfr->flags[pc] & FLAG_BRANCH_TARGET)) | |
1915 | verify_fail_pc ("branch to middle of instruction", pc); | |
1916 | } | |
1917 | } | |
1918 | ||
1919 | /* Verify exception handlers. */ | |
1920 | for (i = 0; i < vfr->current_method->exc_count; ++i) | |
1921 | { | |
1922 | int handler, start, end, htype; | |
1923 | vfy_get_exception (vfr->exception, i, &handler, &start, &end, &htype); | |
1924 | if (! (vfr->flags[handler] & FLAG_INSN_START)) | |
1925 | verify_fail_pc ("exception handler not at instruction start", | |
1926 | handler); | |
1927 | if (! (vfr->flags[start] & FLAG_INSN_START)) | |
1928 | verify_fail_pc ("exception start not at instruction start", start); | |
1929 | if (end != vfr->current_method->code_length | |
1930 | && ! (vfr->flags[end] & FLAG_INSN_START)) | |
1931 | verify_fail_pc ("exception end not at instruction start", end); | |
1932 | ||
1933 | vfr->flags[handler] |= FLAG_BRANCH_TARGET; | |
1934 | } | |
1935 | } | |
1936 | ||
1937 | static void | |
1938 | check_pool_index (int index) | |
1939 | { | |
1940 | if (index < 0 || index >= vfy_get_constants_size (vfr->current_class)) | |
1941 | verify_fail_pc ("constant pool index out of range", vfr->start_PC); | |
1942 | } | |
1943 | ||
1944 | static type | |
1945 | check_class_constant (int index) | |
1946 | { | |
81f40b79 | 1947 | type t = { (type_val) 0, 0, 0 }; |
36739040 TT |
1948 | vfy_constants *pool; |
1949 | ||
1950 | check_pool_index (index); | |
1951 | pool = vfy_get_constants (vfr->current_class); | |
1952 | if (vfy_tag (pool, index) == JV_CONSTANT_ResolvedClass) | |
1953 | init_type_from_class (&t, vfy_get_pool_class (pool, index)); | |
1954 | else if (vfy_tag (pool, index) == JV_CONSTANT_Class) | |
1955 | init_type_from_string (&t, vfy_get_pool_string (pool, index)); | |
1956 | else | |
1957 | verify_fail_pc ("expected class constant", vfr->start_PC); | |
1958 | return t; | |
1959 | } | |
1960 | ||
1961 | static type | |
1962 | check_constant (int index) | |
1963 | { | |
81f40b79 | 1964 | type t = { (type_val) 0, 0, 0 }; |
36739040 TT |
1965 | vfy_constants *pool; |
1966 | ||
1967 | check_pool_index (index); | |
1968 | pool = vfy_get_constants (vfr->current_class); | |
1969 | if (vfy_tag (pool, index) == JV_CONSTANT_ResolvedString | |
1970 | || vfy_tag (pool, index) == JV_CONSTANT_String) | |
1971 | init_type_from_class (&t, vfy_string_type ()); | |
1972 | else if (vfy_tag (pool, index) == JV_CONSTANT_Integer) | |
1973 | init_type_from_tag (&t, int_type); | |
1974 | else if (vfy_tag (pool, index) == JV_CONSTANT_Float) | |
1975 | init_type_from_tag (&t, float_type); | |
153d08d5 TT |
1976 | else if (vfy_tag (pool, index) == JV_CONSTANT_Class |
1977 | || vfy_tag (pool, index) == JV_CONSTANT_ResolvedClass) | |
1978 | /* FIXME: should only allow this for 1.5 bytecode. */ | |
1979 | init_type_from_class (&t, vfy_class_type ()); | |
36739040 TT |
1980 | else |
1981 | verify_fail_pc ("String, int, or float constant expected", vfr->start_PC); | |
1982 | return t; | |
1983 | } | |
1984 | ||
1985 | static type | |
1986 | check_wide_constant (int index) | |
1987 | { | |
81f40b79 | 1988 | type t = { (type_val) 0, 0, 0 }; |
36739040 TT |
1989 | vfy_constants *pool; |
1990 | ||
1991 | check_pool_index (index); | |
1992 | pool = vfy_get_constants (vfr->current_class); | |
1993 | if (vfy_tag (pool, index) == JV_CONSTANT_Long) | |
1994 | init_type_from_tag (&t, long_type); | |
1995 | else if (vfy_tag (pool, index) == JV_CONSTANT_Double) | |
1996 | init_type_from_tag (&t, double_type); | |
1997 | else | |
1998 | verify_fail_pc ("long or double constant expected", vfr->start_PC); | |
1999 | return t; | |
2000 | } | |
2001 | ||
2002 | /* Helper for both field and method. These are laid out the same in | |
2003 | the constant pool. */ | |
2004 | static type | |
2005 | handle_field_or_method (int index, int expected, | |
2006 | vfy_string *name, vfy_string *fmtype) | |
2007 | { | |
2008 | vfy_uint_16 class_index, name_and_type_index; | |
2009 | vfy_uint_16 name_index, desc_index; | |
2010 | vfy_constants *pool; | |
2011 | ||
2012 | check_pool_index (index); | |
2013 | pool = vfy_get_constants (vfr->current_class); | |
2014 | if (vfy_tag (pool, index) != expected) | |
2015 | verify_fail_pc ("didn't see expected constant", vfr->start_PC); | |
2016 | /* Once we know we have a Fieldref or Methodref we assume that it | |
2017 | is correctly laid out in the constant pool. I think the code | |
2018 | in defineclass.cc guarantees this. */ | |
2019 | vfy_load_indexes (pool, index, &class_index, &name_and_type_index); | |
2020 | vfy_load_indexes (pool, name_and_type_index, &name_index, &desc_index); | |
2021 | ||
2022 | *name = vfy_get_pool_string (pool, name_index); | |
2023 | *fmtype = vfy_get_pool_string (pool, desc_index); | |
2024 | ||
2025 | return check_class_constant (class_index); | |
2026 | } | |
2027 | ||
1870a43b TT |
2028 | /* Return field's type, compute class' type if requested. If |
2029 | PUTFIELD is true, use the special 'putfield' semantics. */ | |
36739040 | 2030 | static type |
1870a43b | 2031 | check_field_constant (int index, type *class_type, bool putfield) |
36739040 TT |
2032 | { |
2033 | vfy_string name, field_type; | |
2034 | const char *typec; | |
36739040 TT |
2035 | type t; |
2036 | ||
2037 | type ct = handle_field_or_method (index, | |
2038 | JV_CONSTANT_Fieldref, | |
2039 | &name, &field_type); | |
2040 | if (class_type) | |
2041 | *class_type = ct; | |
2042 | typec = vfy_string_bytes (field_type); | |
36739040 TT |
2043 | if (typec[0] == '[' || typec[0] == 'L') |
2044 | init_type_from_string (&t, field_type); | |
2045 | else | |
2046 | init_type_from_tag (&t, get_type_val_for_signature (typec[0])); | |
1870a43b TT |
2047 | |
2048 | /* We have an obscure special case here: we can use `putfield' on a | |
2049 | field declared in this class, even if `this' has not yet been | |
2050 | initialized. */ | |
2051 | if (putfield | |
2052 | && ! type_initialized (&vfr->current_state->this_type) | |
2053 | && vfr->current_state->this_type.pc == SELF | |
2054 | && types_equal (&vfr->current_state->this_type, &ct) | |
2055 | && vfy_class_has_field (vfr->current_class, name, field_type)) | |
84b6a4d2 TT |
2056 | /* Note that we don't actually know whether we're going to match |
2057 | against 'this' or some other object of the same type. So, | |
2058 | here we set things up so that it doesn't matter. This relies | |
2059 | on knowing what our caller is up to. */ | |
2060 | type_set_uninitialized (class_type, EITHER); | |
1870a43b | 2061 | |
36739040 TT |
2062 | return t; |
2063 | } | |
2064 | ||
2065 | static type | |
2066 | check_method_constant (int index, bool is_interface, | |
2067 | vfy_string *method_name, | |
2068 | vfy_string *method_signature) | |
2069 | { | |
2070 | return handle_field_or_method (index, | |
2071 | (is_interface | |
2072 | ? JV_CONSTANT_InterfaceMethodref | |
2073 | : JV_CONSTANT_Methodref), | |
2074 | method_name, method_signature); | |
2075 | } | |
2076 | ||
741ac903 KG |
2077 | static const char * |
2078 | get_one_type (const char *p, type *t) | |
36739040 TT |
2079 | { |
2080 | const char *start = p; | |
2081 | vfy_jclass k; | |
2082 | type_val rt; | |
2083 | char v; | |
2084 | ||
2085 | int arraycount = 0; | |
2086 | while (*p == '[') | |
2087 | { | |
2088 | ++arraycount; | |
2089 | ++p; | |
2090 | } | |
2091 | ||
2092 | v = *p++; | |
2093 | ||
2094 | if (v == 'L') | |
2095 | { | |
2096 | vfy_string name; | |
2097 | while (*p != ';') | |
2098 | ++p; | |
2099 | ++p; | |
2100 | name = vfy_get_string (start, p - start); | |
2101 | *t = make_type_from_string (name); | |
2102 | return p; | |
2103 | } | |
2104 | ||
2105 | /* Casting to jchar here is ok since we are looking at an ASCII | |
2106 | character. */ | |
2107 | rt = get_type_val_for_signature (v); | |
2108 | ||
2109 | if (arraycount == 0) | |
2110 | { | |
2111 | /* Callers of this function eventually push their arguments on | |
2112 | the stack. So, promote them here. */ | |
2113 | type new_t = make_type (rt); | |
2114 | vfy_promote_type (&new_t); | |
2115 | *t = new_t; | |
2116 | return p; | |
2117 | } | |
2118 | ||
2119 | k = construct_primitive_array_type (rt); | |
2120 | while (--arraycount > 0) | |
2121 | k = vfy_get_array_class (k); | |
2122 | *t = make_type_from_class (k); | |
2123 | return p; | |
2124 | } | |
2125 | ||
2126 | static void | |
2127 | compute_argument_types (vfy_string signature, type *types) | |
2128 | { | |
2129 | int i; | |
741ac903 | 2130 | const char *p = vfy_string_bytes (signature); |
36739040 TT |
2131 | |
2132 | /* Skip `('. */ | |
2133 | ++p; | |
2134 | ||
2135 | i = 0; | |
2136 | while (*p != ')') | |
2137 | p = get_one_type (p, &types[i++]); | |
2138 | } | |
2139 | ||
2140 | static type | |
2141 | compute_return_type (vfy_string signature) | |
2142 | { | |
741ac903 | 2143 | const char *p = vfy_string_bytes (signature); |
36739040 TT |
2144 | type t; |
2145 | while (*p != ')') | |
2146 | ++p; | |
2147 | ++p; | |
2148 | get_one_type (p, &t); | |
2149 | return t; | |
2150 | } | |
2151 | ||
2152 | static void | |
2153 | check_return_type (type onstack) | |
2154 | { | |
2155 | type rt = compute_return_type (vfy_get_signature (vfr->current_method)); | |
2156 | if (! types_compatible (&rt, &onstack)) | |
2157 | verify_fail ("incompatible return type"); | |
2158 | } | |
2159 | ||
2160 | /* Initialize the stack for the new method. Returns true if this | |
2161 | method is an instance initializer. */ | |
2162 | static bool | |
2163 | initialize_stack (void) | |
2164 | { | |
2165 | int arg_count, i; | |
2166 | int var = 0; | |
2167 | bool is_init = vfy_strings_equal (vfy_get_method_name (vfr->current_method), | |
2168 | vfy_init_name()); | |
2169 | bool is_clinit = vfy_strings_equal (vfy_get_method_name (vfr->current_method), | |
2170 | vfy_clinit_name()); | |
2171 | ||
2172 | if (! vfy_is_static (vfr->current_method)) | |
2173 | { | |
2174 | type kurr = make_type_from_class (vfr->current_class); | |
2175 | if (is_init) | |
2176 | { | |
2177 | type_set_uninitialized (&kurr, SELF); | |
2178 | is_init = true; | |
2179 | } | |
2180 | else if (is_clinit) | |
2181 | verify_fail ("<clinit> method must be static"); | |
2182 | set_variable (0, kurr); | |
2183 | state_set_this_type (vfr->current_state, &kurr); | |
2184 | ++var; | |
2185 | } | |
2186 | else | |
2187 | { | |
2188 | if (is_init) | |
2189 | verify_fail ("<init> method must be non-static"); | |
2190 | } | |
2191 | ||
2192 | /* We have to handle wide arguments specially here. */ | |
2193 | arg_count = vfy_count_arguments (vfy_get_signature (vfr->current_method)); | |
2194 | { | |
528d9c63 | 2195 | type *arg_types = (type *) vfy_alloc (arg_count * sizeof (type)); |
36739040 TT |
2196 | compute_argument_types (vfy_get_signature (vfr->current_method), arg_types); |
2197 | for (i = 0; i < arg_count; ++i) | |
2198 | { | |
2199 | set_variable (var, arg_types[i]); | |
2200 | ++var; | |
2201 | if (type_iswide (&arg_types[i])) | |
2202 | ++var; | |
2203 | } | |
528d9c63 | 2204 | vfy_free (arg_types); |
36739040 TT |
2205 | } |
2206 | ||
2207 | return is_init; | |
2208 | } | |
2209 | ||
2210 | static void | |
2211 | verify_instructions_0 (void) | |
2212 | { | |
2213 | int i; | |
2214 | bool this_is_init; | |
2215 | ||
2216 | vfr->current_state = make_state (vfr->current_method->max_stack, | |
2217 | vfr->current_method->max_locals); | |
2218 | ||
2219 | vfr->PC = 0; | |
2220 | vfr->start_PC = 0; | |
2221 | ||
2222 | /* True if we are verifying an instance initializer. */ | |
2223 | this_is_init = initialize_stack (); | |
2224 | ||
2225 | vfr->states = (state_list **) vfy_alloc (sizeof (state_list *) | |
2226 | * vfr->current_method->code_length); | |
2227 | ||
2228 | for (i = 0; i < vfr->current_method->code_length; ++i) | |
2229 | vfr->states[i] = NULL; | |
2230 | ||
2231 | vfr->next_verify_state = NULL; | |
2232 | ||
2233 | while (true) | |
2234 | { | |
2235 | java_opcode opcode; | |
2236 | ||
2237 | /* If the PC was invalidated, get a new one from the work list. */ | |
2238 | if (vfr->PC == NO_NEXT) | |
2239 | { | |
2240 | state *new_state = pop_jump (); | |
2241 | /* If it is null, we're done. */ | |
2242 | if (new_state == NULL) | |
2243 | break; | |
2244 | ||
a2da2c9a | 2245 | vfr->PC = new_state->pc; |
36739040 TT |
2246 | debug_print ("== State pop from pending list\n"); |
2247 | /* Set up the current state. */ | |
2248 | copy_state (vfr->current_state, new_state, | |
2249 | vfr->current_method->max_stack, vfr->current_method->max_locals); | |
2250 | } | |
2251 | else | |
2252 | { | |
2253 | /* We only have to do this checking in the situation where | |
aca02b7e TT |
2254 | control flow falls through from the previous instruction. |
2255 | Otherwise merging is done at the time we push the branch. | |
2256 | Note that we'll catch the off-the-end problem just | |
2257 | below. */ | |
2258 | if (vfr->PC < vfr->current_method->code_length | |
2259 | && vfr->states[vfr->PC] != NULL) | |
36739040 TT |
2260 | { |
2261 | /* We've already visited this instruction. So merge | |
2262 | the states together. It is simplest, but not most | |
2263 | efficient, to just always invalidate the PC here. */ | |
2264 | merge_into (vfr->PC, vfr->current_state); | |
2265 | invalidate_pc (); | |
2266 | continue; | |
2267 | } | |
2268 | } | |
2269 | ||
2270 | /* Control can't fall off the end of the bytecode. We need to | |
2271 | check this in both cases, not just the fall-through case, | |
2272 | because we don't check to see whether a `jsr' appears at | |
2273 | the end of the bytecode until we process a `ret'. */ | |
2274 | if (vfr->PC >= vfr->current_method->code_length) | |
2275 | verify_fail ("fell off end"); | |
2276 | vfr->flags[vfr->PC] |= FLAG_INSN_SEEN; | |
2277 | ||
2278 | /* We only have to keep saved state at branch targets. If | |
2279 | we're at a branch target and the state here hasn't been set | |
2280 | yet, we set it now. You might notice that `ret' targets | |
2281 | won't necessarily have FLAG_BRANCH_TARGET set. This | |
2282 | doesn't matter, since those states will be filled in by | |
2283 | merge_into. */ | |
2284 | /* Note that other parts of the compiler assume that there is a | |
2285 | label with a type map at PC=0. */ | |
2286 | if (vfr->states[vfr->PC] == NULL | |
2287 | && (vfr->PC == 0 || (vfr->flags[vfr->PC] & FLAG_BRANCH_TARGET) != 0)) | |
2288 | add_new_state (vfr->PC, vfr->current_state); | |
2289 | ||
2290 | /* Set this before handling exceptions so that debug output is | |
2291 | sane. */ | |
2292 | vfr->start_PC = vfr->PC; | |
2293 | ||
2294 | /* Update states for all active exception handlers. Ordinarily | |
2295 | there are not many exception handlers. So we simply run | |
2296 | through them all. */ | |
2297 | for (i = 0; i < vfr->current_method->exc_count; ++i) | |
2298 | { | |
2299 | int hpc, start, end, htype; | |
2300 | vfy_get_exception (vfr->exception, i, &hpc, &start, &end, &htype); | |
2301 | if (vfr->PC >= start && vfr->PC < end) | |
2302 | { | |
2303 | type handler = make_type_from_class (vfy_throwable_type ()); | |
2304 | if (htype != 0) | |
2305 | handler = check_class_constant (htype); | |
2306 | push_exception_jump (handler, hpc); | |
2307 | } | |
2308 | } | |
2309 | ||
2310 | ||
2311 | debug_print_state (vfr->current_state, " ", vfr->PC, | |
2312 | vfr->current_method->max_stack, | |
2313 | vfr->current_method->max_locals); | |
2314 | opcode = (java_opcode) vfr->bytecode[vfr->PC++]; | |
2315 | switch (opcode) | |
2316 | { | |
2317 | case op_nop: | |
2318 | break; | |
2319 | ||
2320 | case op_aconst_null: | |
2321 | push_type (null_type); | |
2322 | break; | |
2323 | ||
2324 | case op_iconst_m1: | |
2325 | case op_iconst_0: | |
2326 | case op_iconst_1: | |
2327 | case op_iconst_2: | |
2328 | case op_iconst_3: | |
2329 | case op_iconst_4: | |
2330 | case op_iconst_5: | |
2331 | push_type (int_type); | |
2332 | break; | |
2333 | ||
2334 | case op_lconst_0: | |
2335 | case op_lconst_1: | |
2336 | push_type (long_type); | |
2337 | break; | |
2338 | ||
2339 | case op_fconst_0: | |
2340 | case op_fconst_1: | |
2341 | case op_fconst_2: | |
2342 | push_type (float_type); | |
2343 | break; | |
2344 | ||
2345 | case op_dconst_0: | |
2346 | case op_dconst_1: | |
2347 | push_type (double_type); | |
2348 | break; | |
2349 | ||
2350 | case op_bipush: | |
2351 | get_byte (); | |
2352 | push_type (int_type); | |
2353 | break; | |
2354 | ||
2355 | case op_sipush: | |
2356 | get_short (); | |
2357 | push_type (int_type); | |
2358 | break; | |
2359 | ||
2360 | case op_ldc: | |
2361 | push_type_t (check_constant (get_byte ())); | |
2362 | break; | |
2363 | case op_ldc_w: | |
2364 | push_type_t (check_constant (get_ushort ())); | |
2365 | break; | |
2366 | case op_ldc2_w: | |
2367 | push_type_t (check_wide_constant (get_ushort ())); | |
2368 | break; | |
2369 | ||
2370 | case op_iload: | |
2371 | push_type_t (get_variable (get_byte (), int_type)); | |
2372 | break; | |
2373 | case op_lload: | |
2374 | push_type_t (get_variable (get_byte (), long_type)); | |
2375 | break; | |
2376 | case op_fload: | |
2377 | push_type_t (get_variable (get_byte (), float_type)); | |
2378 | break; | |
2379 | case op_dload: | |
2380 | push_type_t (get_variable (get_byte (), double_type)); | |
2381 | break; | |
2382 | case op_aload: | |
2383 | push_type_t (get_variable (get_byte (), reference_type)); | |
2384 | break; | |
2385 | ||
2386 | case op_iload_0: | |
2387 | case op_iload_1: | |
2388 | case op_iload_2: | |
2389 | case op_iload_3: | |
2390 | push_type_t (get_variable (opcode - op_iload_0, int_type)); | |
2391 | break; | |
2392 | case op_lload_0: | |
2393 | case op_lload_1: | |
2394 | case op_lload_2: | |
2395 | case op_lload_3: | |
2396 | push_type_t (get_variable (opcode - op_lload_0, long_type)); | |
2397 | break; | |
2398 | case op_fload_0: | |
2399 | case op_fload_1: | |
2400 | case op_fload_2: | |
2401 | case op_fload_3: | |
2402 | push_type_t (get_variable (opcode - op_fload_0, float_type)); | |
2403 | break; | |
2404 | case op_dload_0: | |
2405 | case op_dload_1: | |
2406 | case op_dload_2: | |
2407 | case op_dload_3: | |
2408 | push_type_t (get_variable (opcode - op_dload_0, double_type)); | |
2409 | break; | |
2410 | case op_aload_0: | |
2411 | case op_aload_1: | |
2412 | case op_aload_2: | |
2413 | case op_aload_3: | |
2414 | push_type_t (get_variable (opcode - op_aload_0, reference_type)); | |
2415 | break; | |
2416 | case op_iaload: | |
2417 | pop_type (int_type); | |
2418 | push_type_t (require_array_type (pop_init_ref (reference_type), | |
2419 | int_type)); | |
2420 | break; | |
2421 | case op_laload: | |
2422 | pop_type (int_type); | |
2423 | push_type_t (require_array_type (pop_init_ref (reference_type), | |
2424 | long_type)); | |
2425 | break; | |
2426 | case op_faload: | |
2427 | pop_type (int_type); | |
2428 | push_type_t (require_array_type (pop_init_ref (reference_type), | |
2429 | float_type)); | |
2430 | break; | |
2431 | case op_daload: | |
2432 | pop_type (int_type); | |
2433 | push_type_t (require_array_type (pop_init_ref (reference_type), | |
2434 | double_type)); | |
2435 | break; | |
2436 | case op_aaload: | |
2437 | pop_type (int_type); | |
2438 | push_type_t (require_array_type (pop_init_ref (reference_type), | |
2439 | reference_type)); | |
2440 | break; | |
2441 | case op_baload: | |
2442 | pop_type (int_type); | |
2443 | require_array_type (pop_init_ref (reference_type), byte_type); | |
2444 | push_type (int_type); | |
2445 | break; | |
2446 | case op_caload: | |
2447 | pop_type (int_type); | |
2448 | require_array_type (pop_init_ref (reference_type), char_type); | |
2449 | push_type (int_type); | |
2450 | break; | |
2451 | case op_saload: | |
2452 | pop_type (int_type); | |
2453 | require_array_type (pop_init_ref (reference_type), short_type); | |
2454 | push_type (int_type); | |
2455 | break; | |
2456 | case op_istore: | |
2457 | set_variable (get_byte (), pop_type (int_type)); | |
2458 | break; | |
2459 | case op_lstore: | |
2460 | set_variable (get_byte (), pop_type (long_type)); | |
2461 | break; | |
2462 | case op_fstore: | |
2463 | set_variable (get_byte (), pop_type (float_type)); | |
2464 | break; | |
2465 | case op_dstore: | |
2466 | set_variable (get_byte (), pop_type (double_type)); | |
2467 | break; | |
2468 | case op_astore: | |
2469 | set_variable (get_byte (), pop_ref_or_return ()); | |
2470 | break; | |
2471 | case op_istore_0: | |
2472 | case op_istore_1: | |
2473 | case op_istore_2: | |
2474 | case op_istore_3: | |
2475 | set_variable (opcode - op_istore_0, pop_type (int_type)); | |
2476 | break; | |
2477 | case op_lstore_0: | |
2478 | case op_lstore_1: | |
2479 | case op_lstore_2: | |
2480 | case op_lstore_3: | |
2481 | set_variable (opcode - op_lstore_0, pop_type (long_type)); | |
2482 | break; | |
2483 | case op_fstore_0: | |
2484 | case op_fstore_1: | |
2485 | case op_fstore_2: | |
2486 | case op_fstore_3: | |
2487 | set_variable (opcode - op_fstore_0, pop_type (float_type)); | |
2488 | break; | |
2489 | case op_dstore_0: | |
2490 | case op_dstore_1: | |
2491 | case op_dstore_2: | |
2492 | case op_dstore_3: | |
2493 | set_variable (opcode - op_dstore_0, pop_type (double_type)); | |
2494 | break; | |
2495 | case op_astore_0: | |
2496 | case op_astore_1: | |
2497 | case op_astore_2: | |
2498 | case op_astore_3: | |
2499 | set_variable (opcode - op_astore_0, pop_ref_or_return ()); | |
2500 | break; | |
2501 | case op_iastore: | |
2502 | pop_type (int_type); | |
2503 | pop_type (int_type); | |
2504 | require_array_type (pop_init_ref (reference_type), int_type); | |
2505 | break; | |
2506 | case op_lastore: | |
2507 | pop_type (long_type); | |
2508 | pop_type (int_type); | |
2509 | require_array_type (pop_init_ref (reference_type), long_type); | |
2510 | break; | |
2511 | case op_fastore: | |
2512 | pop_type (float_type); | |
2513 | pop_type (int_type); | |
2514 | require_array_type (pop_init_ref (reference_type), float_type); | |
2515 | break; | |
2516 | case op_dastore: | |
2517 | pop_type (double_type); | |
2518 | pop_type (int_type); | |
2519 | require_array_type (pop_init_ref (reference_type), double_type); | |
2520 | break; | |
2521 | case op_aastore: | |
2522 | pop_type (reference_type); | |
2523 | pop_type (int_type); | |
2524 | require_array_type (pop_init_ref (reference_type), reference_type); | |
2525 | break; | |
2526 | case op_bastore: | |
2527 | pop_type (int_type); | |
2528 | pop_type (int_type); | |
2529 | require_array_type (pop_init_ref (reference_type), byte_type); | |
2530 | break; | |
2531 | case op_castore: | |
2532 | pop_type (int_type); | |
2533 | pop_type (int_type); | |
2534 | require_array_type (pop_init_ref (reference_type), char_type); | |
2535 | break; | |
2536 | case op_sastore: | |
2537 | pop_type (int_type); | |
2538 | pop_type (int_type); | |
2539 | require_array_type (pop_init_ref (reference_type), short_type); | |
2540 | break; | |
2541 | case op_pop: | |
2542 | pop32 (); | |
2543 | break; | |
2544 | case op_pop2: | |
2545 | { | |
2546 | type t = pop_raw (); | |
2547 | if (! type_iswide (&t)) | |
2548 | pop32 (); | |
2549 | } | |
2550 | break; | |
2551 | case op_dup: | |
2552 | { | |
2553 | type t = pop32 (); | |
2554 | push_type_t (t); | |
2555 | push_type_t (t); | |
2556 | } | |
2557 | break; | |
2558 | case op_dup_x1: | |
2559 | { | |
2560 | type t1 = pop32 (); | |
2561 | type t2 = pop32 (); | |
2562 | push_type_t (t1); | |
2563 | push_type_t (t2); | |
2564 | push_type_t (t1); | |
2565 | } | |
2566 | break; | |
2567 | case op_dup_x2: | |
2568 | { | |
2569 | type t1 = pop32 (); | |
2570 | type t2 = pop_raw (); | |
2571 | if (! type_iswide (&t2)) | |
2572 | { | |
2573 | type t3 = pop32 (); | |
2574 | push_type_t (t1); | |
2575 | push_type_t (t3); | |
2576 | } | |
2577 | else | |
2578 | push_type_t (t1); | |
2579 | push_type_t (t2); | |
2580 | push_type_t (t1); | |
2581 | } | |
2582 | break; | |
2583 | case op_dup2: | |
2584 | { | |
2585 | type t = pop_raw (); | |
2586 | if (! type_iswide (&t)) | |
2587 | { | |
2588 | type t2 = pop32 (); | |
2589 | push_type_t (t2); | |
2590 | push_type_t (t); | |
2591 | push_type_t (t2); | |
2592 | } | |
2593 | else | |
2594 | push_type_t (t); | |
2595 | push_type_t (t); | |
2596 | } | |
2597 | break; | |
2598 | case op_dup2_x1: | |
2599 | { | |
2600 | type t1 = pop_raw (); | |
2601 | type t2 = pop32 (); | |
2602 | if (! type_iswide (&t1)) | |
2603 | { | |
2604 | type t3 = pop32 (); | |
2605 | push_type_t (t2); | |
2606 | push_type_t (t1); | |
2607 | push_type_t (t3); | |
2608 | } | |
2609 | else | |
2610 | push_type_t (t1); | |
2611 | push_type_t (t2); | |
2612 | push_type_t (t1); | |
2613 | } | |
2614 | break; | |
2615 | case op_dup2_x2: | |
2616 | { | |
2617 | type t1 = pop_raw (); | |
2618 | if (type_iswide (&t1)) | |
2619 | { | |
2620 | type t2 = pop_raw (); | |
2621 | if (type_iswide (&t2)) | |
2622 | { | |
2623 | push_type_t (t1); | |
2624 | push_type_t (t2); | |
2625 | } | |
2626 | else | |
2627 | { | |
2628 | type t3 = pop32 (); | |
2629 | push_type_t (t1); | |
2630 | push_type_t (t3); | |
2631 | push_type_t (t2); | |
2632 | } | |
2633 | push_type_t (t1); | |
2634 | } | |
2635 | else | |
2636 | { | |
2637 | type t2 = pop32 (); | |
2638 | type t3 = pop_raw (); | |
2639 | if (type_iswide (&t3)) | |
2640 | { | |
2641 | push_type_t (t2); | |
2642 | push_type_t (t1); | |
2643 | } | |
2644 | else | |
2645 | { | |
2646 | type t4 = pop32 (); | |
2647 | push_type_t (t2); | |
2648 | push_type_t (t1); | |
2649 | push_type_t (t4); | |
2650 | } | |
2651 | push_type_t (t3); | |
2652 | push_type_t (t2); | |
2653 | push_type_t (t1); | |
2654 | } | |
2655 | } | |
2656 | break; | |
2657 | case op_swap: | |
2658 | { | |
2659 | type t1 = pop32 (); | |
2660 | type t2 = pop32 (); | |
2661 | push_type_t (t1); | |
2662 | push_type_t (t2); | |
2663 | } | |
2664 | break; | |
2665 | case op_iadd: | |
2666 | case op_isub: | |
2667 | case op_imul: | |
2668 | case op_idiv: | |
2669 | case op_irem: | |
2670 | case op_ishl: | |
2671 | case op_ishr: | |
2672 | case op_iushr: | |
2673 | case op_iand: | |
2674 | case op_ior: | |
2675 | case op_ixor: | |
2676 | pop_type (int_type); | |
2677 | push_type_t (pop_type (int_type)); | |
2678 | break; | |
2679 | case op_ladd: | |
2680 | case op_lsub: | |
2681 | case op_lmul: | |
2682 | case op_ldiv: | |
2683 | case op_lrem: | |
2684 | case op_land: | |
2685 | case op_lor: | |
2686 | case op_lxor: | |
2687 | pop_type (long_type); | |
2688 | push_type_t (pop_type (long_type)); | |
2689 | break; | |
2690 | case op_lshl: | |
2691 | case op_lshr: | |
2692 | case op_lushr: | |
2693 | pop_type (int_type); | |
2694 | push_type_t (pop_type (long_type)); | |
2695 | break; | |
2696 | case op_fadd: | |
2697 | case op_fsub: | |
2698 | case op_fmul: | |
2699 | case op_fdiv: | |
2700 | case op_frem: | |
2701 | pop_type (float_type); | |
2702 | push_type_t (pop_type (float_type)); | |
2703 | break; | |
2704 | case op_dadd: | |
2705 | case op_dsub: | |
2706 | case op_dmul: | |
2707 | case op_ddiv: | |
2708 | case op_drem: | |
2709 | pop_type (double_type); | |
2710 | push_type_t (pop_type (double_type)); | |
2711 | break; | |
2712 | case op_ineg: | |
2713 | case op_i2b: | |
2714 | case op_i2c: | |
2715 | case op_i2s: | |
2716 | push_type_t (pop_type (int_type)); | |
2717 | break; | |
2718 | case op_lneg: | |
2719 | push_type_t (pop_type (long_type)); | |
2720 | break; | |
2721 | case op_fneg: | |
2722 | push_type_t (pop_type (float_type)); | |
2723 | break; | |
2724 | case op_dneg: | |
2725 | push_type_t (pop_type (double_type)); | |
2726 | break; | |
2727 | case op_iinc: | |
2728 | get_variable (get_byte (), int_type); | |
2729 | get_byte (); | |
2730 | break; | |
2731 | case op_i2l: | |
2732 | pop_type (int_type); | |
2733 | push_type (long_type); | |
2734 | break; | |
2735 | case op_i2f: | |
2736 | pop_type (int_type); | |
2737 | push_type (float_type); | |
2738 | break; | |
2739 | case op_i2d: | |
2740 | pop_type (int_type); | |
2741 | push_type (double_type); | |
2742 | break; | |
2743 | case op_l2i: | |
2744 | pop_type (long_type); | |
2745 | push_type (int_type); | |
2746 | break; | |
2747 | case op_l2f: | |
2748 | pop_type (long_type); | |
2749 | push_type (float_type); | |
2750 | break; | |
2751 | case op_l2d: | |
2752 | pop_type (long_type); | |
2753 | push_type (double_type); | |
2754 | break; | |
2755 | case op_f2i: | |
2756 | pop_type (float_type); | |
2757 | push_type (int_type); | |
2758 | break; | |
2759 | case op_f2l: | |
2760 | pop_type (float_type); | |
2761 | push_type (long_type); | |
2762 | break; | |
2763 | case op_f2d: | |
2764 | pop_type (float_type); | |
2765 | push_type (double_type); | |
2766 | break; | |
2767 | case op_d2i: | |
2768 | pop_type (double_type); | |
2769 | push_type (int_type); | |
2770 | break; | |
2771 | case op_d2l: | |
2772 | pop_type (double_type); | |
2773 | push_type (long_type); | |
2774 | break; | |
2775 | case op_d2f: | |
2776 | pop_type (double_type); | |
2777 | push_type (float_type); | |
2778 | break; | |
2779 | case op_lcmp: | |
2780 | pop_type (long_type); | |
2781 | pop_type (long_type); | |
2782 | push_type (int_type); | |
2783 | break; | |
2784 | case op_fcmpl: | |
2785 | case op_fcmpg: | |
2786 | pop_type (float_type); | |
2787 | pop_type (float_type); | |
2788 | push_type (int_type); | |
2789 | break; | |
2790 | case op_dcmpl: | |
2791 | case op_dcmpg: | |
2792 | pop_type (double_type); | |
2793 | pop_type (double_type); | |
2794 | push_type (int_type); | |
2795 | break; | |
2796 | case op_ifeq: | |
2797 | case op_ifne: | |
2798 | case op_iflt: | |
2799 | case op_ifge: | |
2800 | case op_ifgt: | |
2801 | case op_ifle: | |
2802 | pop_type (int_type); | |
2803 | push_jump (get_short ()); | |
2804 | break; | |
2805 | case op_if_icmpeq: | |
2806 | case op_if_icmpne: | |
2807 | case op_if_icmplt: | |
2808 | case op_if_icmpge: | |
2809 | case op_if_icmpgt: | |
2810 | case op_if_icmple: | |
2811 | pop_type (int_type); | |
2812 | pop_type (int_type); | |
2813 | push_jump (get_short ()); | |
2814 | break; | |
2815 | case op_if_acmpeq: | |
2816 | case op_if_acmpne: | |
2817 | pop_type (reference_type); | |
2818 | pop_type (reference_type); | |
2819 | push_jump (get_short ()); | |
2820 | break; | |
2821 | case op_goto: | |
2822 | push_jump (get_short ()); | |
2823 | invalidate_pc (); | |
2824 | break; | |
2825 | case op_jsr: | |
2826 | handle_jsr_insn (get_short ()); | |
2827 | break; | |
2828 | case op_ret: | |
2829 | handle_ret_insn (get_byte ()); | |
2830 | break; | |
2831 | case op_tableswitch: | |
2832 | { | |
2833 | int i; | |
2834 | jint low, high; | |
2835 | pop_type (int_type); | |
2836 | skip_padding (); | |
2837 | push_jump (get_int ()); | |
2838 | low = get_int (); | |
2839 | high = get_int (); | |
2840 | /* Already checked LOW -vs- HIGH. */ | |
2841 | for (i = low; i <= high; ++i) | |
2842 | push_jump (get_int ()); | |
2843 | invalidate_pc (); | |
2844 | } | |
2845 | break; | |
2846 | ||
2847 | case op_lookupswitch: | |
2848 | { | |
2849 | int i; | |
2850 | jint npairs, lastkey; | |
2851 | ||
2852 | pop_type (int_type); | |
2853 | skip_padding (); | |
2854 | push_jump (get_int ()); | |
2855 | npairs = get_int (); | |
2856 | /* Already checked NPAIRS >= 0. */ | |
2857 | lastkey = 0; | |
2858 | for (i = 0; i < npairs; ++i) | |
2859 | { | |
2860 | jint key = get_int (); | |
2861 | if (i > 0 && key <= lastkey) | |
2862 | verify_fail_pc ("lookupswitch pairs unsorted", vfr->start_PC); | |
2863 | lastkey = key; | |
2864 | push_jump (get_int ()); | |
2865 | } | |
2866 | invalidate_pc (); | |
2867 | } | |
2868 | break; | |
2869 | case op_ireturn: | |
2870 | check_return_type (pop_type (int_type)); | |
2871 | invalidate_pc (); | |
2872 | break; | |
2873 | case op_lreturn: | |
2874 | check_return_type (pop_type (long_type)); | |
2875 | invalidate_pc (); | |
2876 | break; | |
2877 | case op_freturn: | |
2878 | check_return_type (pop_type (float_type)); | |
2879 | invalidate_pc (); | |
2880 | break; | |
2881 | case op_dreturn: | |
2882 | check_return_type (pop_type (double_type)); | |
2883 | invalidate_pc (); | |
2884 | break; | |
2885 | case op_areturn: | |
2886 | check_return_type (pop_init_ref (reference_type)); | |
2887 | invalidate_pc (); | |
2888 | break; | |
2889 | case op_return: | |
6420fb77 TT |
2890 | /* We only need to check this when the return type is void, |
2891 | because all instance initializers return void. We also | |
2892 | need to special-case Object constructors, as they can't | |
2893 | call a superclass <init>. */ | |
2894 | if (this_is_init && vfr->current_class != vfy_object_type ()) | |
36739040 TT |
2895 | state_check_this_initialized (vfr->current_state); |
2896 | check_return_type (make_type (void_type)); | |
2897 | invalidate_pc (); | |
2898 | break; | |
2899 | case op_getstatic: | |
1870a43b | 2900 | push_type_t (check_field_constant (get_ushort (), NULL, false)); |
36739040 TT |
2901 | break; |
2902 | case op_putstatic: | |
1870a43b | 2903 | pop_type_t (check_field_constant (get_ushort (), NULL, false)); |
36739040 TT |
2904 | break; |
2905 | case op_getfield: | |
2906 | { | |
2907 | type klass; | |
1870a43b | 2908 | type field = check_field_constant (get_ushort (), &klass, false); |
36739040 TT |
2909 | pop_type_t (klass); |
2910 | push_type_t (field); | |
2911 | } | |
2912 | break; | |
2913 | case op_putfield: | |
2914 | { | |
2915 | type klass; | |
1870a43b | 2916 | type field = check_field_constant (get_ushort (), &klass, true); |
36739040 | 2917 | pop_type_t (field); |
36739040 TT |
2918 | pop_type_t (klass); |
2919 | } | |
2920 | break; | |
2921 | ||
2922 | case op_invokevirtual: | |
2923 | case op_invokespecial: | |
2924 | case op_invokestatic: | |
2925 | case op_invokeinterface: | |
2926 | { | |
2927 | vfy_string method_name, method_signature; | |
2928 | const char *namec; | |
2929 | int i, arg_count; | |
2930 | type rt; | |
2931 | bool is_init = false; | |
2932 | ||
2933 | type class_type | |
2934 | = check_method_constant (get_ushort (), | |
2935 | opcode == op_invokeinterface, | |
2936 | &method_name, | |
2937 | &method_signature); | |
2938 | /* NARGS is only used when we're processing | |
2939 | invokeinterface. It is simplest for us to compute it | |
2940 | here and then verify it later. */ | |
2941 | int nargs = 0; | |
2942 | if (opcode == op_invokeinterface) | |
2943 | { | |
2944 | nargs = get_byte (); | |
2945 | if (get_byte () != 0) | |
2946 | verify_fail ("invokeinterface dummy byte is wrong"); | |
2947 | } | |
2948 | ||
2949 | namec = vfy_string_bytes (method_name); | |
2950 | ||
2951 | if (vfy_strings_equal (method_name, vfy_init_name())) | |
2952 | { | |
2953 | is_init = true; | |
2954 | if (opcode != op_invokespecial) | |
2955 | verify_fail ("can't invoke <init>"); | |
2956 | } | |
2957 | else if (namec[0] == '<') | |
2958 | verify_fail ("can't invoke method starting with `<'"); | |
2959 | ||
2960 | arg_count = vfy_count_arguments (method_signature); | |
2961 | { | |
2962 | /* Pop arguments and check types. */ | |
528d9c63 | 2963 | type *arg_types = (type *) vfy_alloc (arg_count * sizeof (type)); |
36739040 TT |
2964 | |
2965 | compute_argument_types (method_signature, arg_types); | |
2966 | for (i = arg_count - 1; i >= 0; --i) | |
2967 | { | |
2968 | /* This is only used for verifying the byte for | |
2969 | invokeinterface. */ | |
2970 | nargs -= type_depth (&arg_types[i]); | |
2971 | pop_init_ref_t (arg_types[i]); | |
2972 | } | |
528d9c63 TT |
2973 | |
2974 | vfy_free (arg_types); | |
36739040 TT |
2975 | } |
2976 | ||
2977 | if (opcode == op_invokeinterface | |
2978 | && nargs != 1) | |
2979 | verify_fail ("wrong argument count for invokeinterface"); | |
2980 | ||
2981 | if (opcode != op_invokestatic) | |
2982 | { | |
2983 | type raw; | |
2984 | type t = class_type; | |
2985 | if (is_init) | |
2986 | { | |
2987 | /* In this case the PC doesn't matter. */ | |
2988 | type_set_uninitialized (&t, UNINIT); | |
2989 | /* FIXME: check to make sure that the <init> | |
2990 | call is to the right class. | |
2991 | It must either be super or an exact class | |
2992 | match. */ | |
2993 | } | |
2994 | raw = pop_raw (); | |
2995 | if (! types_compatible (&t, &raw)) | |
2996 | verify_fail ("incompatible type on stack"); | |
2997 | ||
2998 | if (is_init) | |
2999 | state_set_initialized (vfr->current_state, | |
3000 | type_get_pc (&raw), vfr->current_method->max_locals); | |
3001 | } | |
3002 | ||
3003 | rt = compute_return_type (method_signature); | |
3004 | if (! type_isvoid (&rt)) | |
3005 | push_type_t (rt); | |
3006 | } | |
3007 | break; | |
3008 | ||
3009 | case op_new: | |
3010 | { | |
3011 | type t = check_class_constant (get_ushort ()); | |
3012 | if (type_isarray (&t) || type_isinterface (&t) | |
3013 | || type_isabstract (&t)) | |
3014 | verify_fail ("type is array, interface, or abstract"); | |
3015 | type_set_uninitialized (&t, vfr->start_PC); | |
3016 | push_type_t (t); | |
3017 | } | |
3018 | break; | |
3019 | ||
3020 | case op_newarray: | |
3021 | { | |
3022 | int atype = get_byte (); | |
d9d3eaab | 3023 | vfy_jclass k; |
36739040 TT |
3024 | type t; |
3025 | /* We intentionally have chosen constants to make this | |
3026 | valid. */ | |
3027 | if (atype < boolean_type || atype > long_type) | |
3028 | verify_fail_pc ("type not primitive", vfr->start_PC); | |
3029 | pop_type (int_type); | |
d9d3eaab ILT |
3030 | k = construct_primitive_array_type ((type_val) atype); |
3031 | init_type_from_class (&t, k); | |
36739040 TT |
3032 | push_type_t (t); |
3033 | } | |
3034 | break; | |
3035 | case op_anewarray: | |
3036 | { | |
3037 | type t; | |
3038 | pop_type (int_type); | |
3039 | t = check_class_constant (get_ushort ()); | |
3040 | push_type_t (type_to_array (&t)); | |
3041 | } | |
3042 | break; | |
3043 | case op_arraylength: | |
3044 | { | |
3045 | type t = pop_init_ref (reference_type); | |
3046 | if (! type_isarray (&t) && ! type_isnull (&t)) | |
3047 | verify_fail ("array type expected"); | |
3048 | push_type (int_type); | |
3049 | } | |
3050 | break; | |
3051 | case op_athrow: | |
3052 | pop_type_t (make_type_from_class (vfy_throwable_type ())); | |
3053 | invalidate_pc (); | |
3054 | break; | |
3055 | case op_checkcast: | |
3056 | pop_init_ref (reference_type); | |
3057 | push_type_t (check_class_constant (get_ushort ())); | |
3058 | break; | |
3059 | case op_instanceof: | |
3060 | pop_init_ref (reference_type); | |
3061 | check_class_constant (get_ushort ()); | |
3062 | push_type (int_type); | |
3063 | break; | |
3064 | case op_monitorenter: | |
3065 | pop_init_ref (reference_type); | |
3066 | break; | |
3067 | case op_monitorexit: | |
3068 | pop_init_ref (reference_type); | |
3069 | break; | |
3070 | case op_wide: | |
3071 | { | |
3072 | switch (get_byte ()) | |
3073 | { | |
3074 | case op_iload: | |
3075 | push_type_t (get_variable (get_ushort (), int_type)); | |
3076 | break; | |
3077 | case op_lload: | |
3078 | push_type_t (get_variable (get_ushort (), long_type)); | |
3079 | break; | |
3080 | case op_fload: | |
3081 | push_type_t (get_variable (get_ushort (), float_type)); | |
3082 | break; | |
3083 | case op_dload: | |
3084 | push_type_t (get_variable (get_ushort (), double_type)); | |
3085 | break; | |
3086 | case op_aload: | |
3087 | push_type_t (get_variable (get_ushort (), reference_type)); | |
3088 | break; | |
3089 | case op_istore: | |
3090 | set_variable (get_ushort (), pop_type (int_type)); | |
3091 | break; | |
3092 | case op_lstore: | |
3093 | set_variable (get_ushort (), pop_type (long_type)); | |
3094 | break; | |
3095 | case op_fstore: | |
3096 | set_variable (get_ushort (), pop_type (float_type)); | |
3097 | break; | |
3098 | case op_dstore: | |
3099 | set_variable (get_ushort (), pop_type (double_type)); | |
3100 | break; | |
3101 | case op_astore: | |
3102 | set_variable (get_ushort (), pop_init_ref (reference_type)); | |
3103 | break; | |
3104 | case op_ret: | |
3105 | handle_ret_insn (get_short ()); | |
3106 | break; | |
3107 | case op_iinc: | |
3108 | get_variable (get_ushort (), int_type); | |
3109 | get_short (); | |
3110 | break; | |
3111 | default: | |
3112 | verify_fail_pc ("unrecognized wide instruction", vfr->start_PC); | |
3113 | } | |
3114 | } | |
3115 | break; | |
3116 | case op_multianewarray: | |
3117 | { | |
3118 | int i; | |
3119 | type atype = check_class_constant (get_ushort ()); | |
3120 | int dim = get_byte (); | |
3121 | if (dim < 1) | |
3122 | verify_fail_pc ("too few dimensions to multianewarray", vfr->start_PC); | |
3123 | type_verify_dimensions (&atype, dim); | |
3124 | for (i = 0; i < dim; ++i) | |
3125 | pop_type (int_type); | |
3126 | push_type_t (atype); | |
3127 | } | |
3128 | break; | |
3129 | case op_ifnull: | |
3130 | case op_ifnonnull: | |
3131 | pop_type (reference_type); | |
3132 | push_jump (get_short ()); | |
3133 | break; | |
3134 | case op_goto_w: | |
3135 | push_jump (get_int ()); | |
3136 | invalidate_pc (); | |
3137 | break; | |
3138 | case op_jsr_w: | |
3139 | handle_jsr_insn (get_int ()); | |
3140 | break; | |
3141 | ||
36739040 TT |
3142 | default: |
3143 | /* Unrecognized opcode. */ | |
3144 | verify_fail_pc ("unrecognized instruction in verify_instructions_0", | |
3145 | vfr->start_PC); | |
3146 | } | |
3147 | } | |
3148 | } | |
3149 | ||
3150 | /* This turns a `type' into something suitable for use by the type map | |
3151 | in the other parts of the compiler. In particular, reference types | |
3152 | are mapped to Object, primitive types are unchanged, and other | |
3153 | types are mapped using special functions declared in verify.h. */ | |
3154 | static vfy_jclass | |
3155 | collapse_type (type *t) | |
3156 | { | |
3157 | switch (t->key) | |
3158 | { | |
3159 | case void_type: | |
3160 | case boolean_type: | |
3161 | case char_type: | |
3162 | case float_type: | |
3163 | case double_type: | |
3164 | case byte_type: | |
3165 | case short_type: | |
3166 | case int_type: | |
3167 | case long_type: | |
3168 | return vfy_get_primitive_type (t->key); | |
3169 | ||
3170 | case unsuitable_type: | |
3171 | case continuation_type: | |
3172 | return vfy_unsuitable_type (); | |
3173 | ||
3174 | case return_address_type: | |
3175 | return vfy_return_address_type (); | |
3176 | ||
3177 | case null_type: | |
3178 | return vfy_null_type (); | |
3179 | ||
3180 | case reference_type: | |
3181 | case uninitialized_reference_type: | |
3182 | return vfy_object_type (); | |
3183 | } | |
3184 | ||
ab184b2a | 3185 | gcc_unreachable (); |
36739040 TT |
3186 | } |
3187 | ||
3188 | static void | |
3189 | verify_instructions (void) | |
3190 | { | |
3191 | int i; | |
3192 | ||
3193 | branch_prepass (); | |
3194 | verify_instructions_0 (); | |
3195 | ||
3196 | /* Now tell the rest of the compiler about the types we've found. */ | |
3197 | for (i = 0; i < vfr->current_method->code_length; ++i) | |
3198 | { | |
3199 | int j, slot; | |
3200 | struct state *curr; | |
3201 | ||
3202 | if ((vfr->flags[i] & FLAG_INSN_SEEN) != 0) | |
3203 | vfy_note_instruction_seen (i); | |
3204 | ||
3205 | if (! vfr->states[i]) | |
3206 | continue; | |
3207 | ||
3208 | curr = vfr->states[i]->val; | |
3209 | vfy_note_stack_depth (vfr->current_method, i, curr->stackdepth); | |
3210 | ||
3211 | /* Tell the compiler about each local variable. */ | |
3212 | for (j = 0; j < vfr->current_method->max_locals; ++j) | |
3213 | vfy_note_local_type (vfr->current_method, i, j, | |
3214 | collapse_type (&curr->locals[j])); | |
3215 | /* Tell the compiler about each stack slot. */ | |
3216 | for (slot = j = 0; j < curr->stacktop; ++j, ++slot) | |
3217 | { | |
3218 | vfy_note_stack_type (vfr->current_method, i, slot, | |
3219 | collapse_type (&curr->stack[j])); | |
3220 | if (type_iswide (&curr->stack[j])) | |
3221 | { | |
3222 | ++slot; | |
3223 | vfy_note_stack_type (vfr->current_method, i, slot, | |
3224 | vfy_unsuitable_type ()); | |
3225 | } | |
3226 | } | |
ab184b2a | 3227 | gcc_assert (slot == curr->stackdepth); |
36739040 TT |
3228 | } |
3229 | } | |
3230 | ||
36739040 TT |
3231 | static void |
3232 | make_verifier_context (vfy_method *m) | |
3233 | { | |
3234 | vfr = (verifier_context *) vfy_alloc (sizeof (struct verifier_context)); | |
3235 | ||
3236 | vfr->current_method = m; | |
3237 | vfr->bytecode = vfy_get_bytecode (m); | |
3238 | vfr->exception = vfy_get_exceptions (m); | |
3239 | vfr->current_class = m->defining_class; | |
3240 | ||
3241 | vfr->states = NULL; | |
3242 | vfr->flags = NULL; | |
3243 | vfr->utf8_list = NULL; | |
3244 | vfr->isect_list = NULL; | |
3245 | } | |
3246 | ||
3247 | static void | |
3248 | free_verifier_context (void) | |
3249 | { | |
3250 | vfy_string_list *utf8_list; | |
3251 | ref_intersection *isect_list; | |
3252 | ||
3253 | if (vfr->flags) | |
3254 | vfy_free (vfr->flags); | |
3255 | ||
3256 | utf8_list = vfr->utf8_list; | |
3257 | while (utf8_list != NULL) | |
3258 | { | |
3259 | vfy_string_list *n = utf8_list->next; | |
3260 | vfy_free (utf8_list); | |
3261 | utf8_list = n; | |
3262 | } | |
3263 | ||
3264 | isect_list = vfr->isect_list; | |
3265 | while (isect_list != NULL) | |
3266 | { | |
3267 | ref_intersection *next = isect_list->alloc_next; | |
3268 | vfy_free (isect_list); | |
3269 | isect_list = next; | |
3270 | } | |
3271 | ||
3272 | if (vfr->states != NULL) | |
3273 | { | |
3274 | int i; | |
3275 | for (i = 0; i < vfr->current_method->code_length; ++i) | |
3276 | { | |
3277 | state_list *iter = vfr->states[i]; | |
3278 | while (iter != NULL) | |
3279 | { | |
3280 | state_list *next = iter->next; | |
a2da2c9a | 3281 | free_state (iter->val); |
36739040 TT |
3282 | vfy_free (iter->val); |
3283 | vfy_free (iter); | |
3284 | iter = next; | |
3285 | } | |
3286 | } | |
3287 | vfy_free (vfr->states); | |
3288 | } | |
3289 | ||
3290 | vfy_free (vfr); | |
3291 | } | |
3292 | ||
3293 | int | |
3294 | verify_method (vfy_method *meth) | |
3295 | { | |
3296 | debug_print ("verify_method (%s) %i\n", vfy_string_bytes (meth->name), | |
3297 | meth->code_length); | |
3298 | ||
3299 | if (vfr != NULL) | |
3300 | verify_fail ("verifier re-entered"); | |
3301 | ||
3302 | make_verifier_context (meth); | |
3303 | verify_instructions (); | |
3304 | free_verifier_context (); | |
3305 | vfr = NULL; | |
3306 | ||
3307 | return 1; | |
3308 | } |