DEADSOFTWARE

Patched for Linux
[mp3cc.git] / MPC.3.5.LINUX / preverifier / check_class.c
1 /*
2 * @(#)check_class.c 1.6 02/09/27
3 *
4 * Copyright 1995-1998 by Sun Microsystems, Inc.,
5 * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
6 * All rights reserved.
7 *
8 * This software is the confidential and proprietary information
9 * of Sun Microsystems, Inc. ("Confidential Information"). You
10 * shall not disclose such Confidential Information and shall use
11 * it only in accordance with the terms of the license agreement
12 * you entered into with Sun.
13 * Use is subject to license terms.
14 */
16 /*=========================================================================
17 * SYSTEM: Verifier
18 * SUBSYSTEM: Verifies ClassClass structure.
19 * FILE: check_class.c
20 * OVERVIEW: Code for verifying the ClassClass structure for internal
21 * consistency.
22 * AUTHOR: Sheng Liang, Consumer & Embedded
23 * Initial implementation based on the Classic VM Verifier.
24 * Edited by Tasneem Sayeed, Java Consumer Technologies
25 *=======================================================================*/
27 /*=========================================================================
28 * Include files
29 *=======================================================================*/
31 #include <ctype.h>
33 #include "oobj.h"
34 #include "utf.h"
35 #include "tree.h"
36 #include "sys_api.h"
38 /*=========================================================================
39 * Globals and extern declarations
40 *=======================================================================*/
42 extern bool_t verify_class_codes(ClassClass *cb);
44 //static bool_t verify_constant_pool(ClassClass *cb);
46 //static bool_t is_legal_fieldname(ClassClass *cb, char *name, int type);
47 //static bool_t is_legal_method_signature(ClassClass *cb, char *name, char *signature);
48 //static bool_t is_legal_field_signature(ClassClass *cb, char *name, char *signature);
50 //static char *skip_over_fieldname(char *name, bool_t slash_okay);
51 //static char *skip_over_field_signature(char *name, bool_t void_okay);
53 //static void CCerror (ClassClass *cb, char *format, ...);
56 /* Argument for is_legal_fieldname */
57 enum { LegalClass, LegalField, LegalMethod };
60 /*=========================================================================
61 * FUNCTION: VerifyClass
62 * OVERVIEW: Verifies a class given a pointer to the ClassClass struct.
63 * Returns true if the class is ok.
64 * INTERFACE:
65 * parameters: pointer to the ClassClass structure.
66 *
67 * returns: boolean type
68 *=======================================================================*/
69 bool_t
70 VerifyClass(ClassClass *cb)
71 {
72 verify_class_codes(cb);
73 return TRUE;
74 /*
75 bool_t result = TRUE;
76 struct methodblock *mb;
77 struct fieldblock *fb;
78 int i;
79 if (!verify_constant_pool(cb))
80 return FALSE;
81 /* Make sure all the method names and signatures are okay
82 for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
83 char *name = mb->fb.name;
84 char *signature = mb->fb.signature;
85 if (! (is_legal_fieldname(cb, name, LegalMethod) &&
86 is_legal_method_signature(cb, name, signature)))
87 result = FALSE;
88 }
89 /* Make sure all the field names and signatures are okay
90 for (i = cbFieldsCount(cb), fb = cbFields(cb); --i >= 0; fb++) {
91 if (! (is_legal_fieldname(cb, fb->name, LegalField) &&
92 is_legal_field_signature(cb, fb->name, fb->signature)))
93 result = FALSE;
94 }
95 /* Make sure we are not overriding any final methods or classes
96 if (cbIsInterface(cb)) {
97 struct methodblock *mb;
98 if ((cbSuperclass(cb) == NULL) ||
99 (cbSuperclass(cb) != classJavaLangObject)) {
100 // CCerror(cb, "Interface %s has bad superclass", cbName(cb));
101 result = FALSE;
103 for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
104 if (mb->fb.access & ACC_STATIC) {
105 if (mb->fb.name[0] != '<') {
106 /* Only internal methods can be static
107 // CCerror(cb, "Illegal static method %s in interface %s",
108 // mb->fb.name, cbName(cb));
109 result = FALSE;
113 } else if (cbSuperclass(cb)) {
114 ClassClass *super_cb;
115 unsigned bitvector_size = (unsigned)(cbMethodTableSize(cb) + 31) >> 5;
116 long *bitvector = sysCalloc(bitvector_size, sizeof(long));
117 for (super_cb = cbSuperclass(cb); ; super_cb = cbSuperclass(super_cb)) {
118 if (cbAccess(super_cb) & ACC_FINAL) {
119 // CCerror(cb, "Class %s is subclass of final class %s",
120 // cbName(cb), cbName(super_cb));
121 result = FALSE;
123 mb = cbMethods(super_cb);
124 for (i = cbMethodsCount(super_cb); --i >= 0; mb++) {
125 if (mb->fb.access & ACC_FINAL) {
126 unsigned offset = mb->fb.u.offset;
127 bitvector[offset >> 5] |= (1 << (offset & 0x1F));
130 if (cbSuperclass(super_cb) == NULL) break;
132 for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
133 unsigned offset = mb->fb.u.offset;
134 if ((offset > 0)
135 && bitvector[offset >> 5] & (1 << (offset & 0x1F))) {
136 // CCerror(cb, "Class %s overrides final method %s.%s",
137 // cbName(cb), mb->fb.name, mb->fb.signature);
138 result = FALSE;
141 sysFree(bitvector);
142 } else if (cb != classJavaLangObject) {
143 // CCerror(cb, "Class %s does not have superclass", cbName(cb));
144 result = FALSE;
147 if (result)
148 result = verify_class_codes(cb);
149 return result;*/
153 /*=========================================================================
154 * FUNCTION: verify_constant_pool
155 * OVERVIEW: Verifies the constant pool given a pointer to the
156 * ClassClass structure.
157 * Makes two quick passes over the constant pool. The first
158 * pass ensures that everything is of the right type.
159 * Returns true if the constant pool is ok.
160 * INTERFACE:
161 * parameters: pointer to the ClassClass structure.
162 *
163 * returns: boolean type
164 *=======================================================================*/
165 /*
166 static bool_t
167 verify_constant_pool(ClassClass *cb)
169 union cp_item_type *cp = cbConstantPool(cb);
170 long cp_count = cbConstantPoolCount(cb);
171 unsigned char *type_table;
172 int i, type;
174 const int utf8_resolved = (CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED);
176 if (cp_count == 0) /* Primitive classes
177 return TRUE;
178 type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
179 /* Let's make two quick passes over the constant pool. The first one
180 * checks that everything is of the right type.
181 for (i = 1; i < cp_count; i++) {
182 switch(type = type_table[i]) {
183 case CONSTANT_String:
184 case CONSTANT_Class: {
185 int index = cp[i].i;
186 if ( (index < 1)
187 || (index >= cp_count)
188 || (type_table[index] != utf8_resolved)) {
189 // CCerror(cb, "Bad index in constant pool #%d", i);
190 return FALSE;
192 break;
195 case CONSTANT_String | CONSTANT_POOL_ENTRY_RESOLVED:
196 /* This can only happen if a string is the "initial" value of
197 * some final static String. We assume that the checking has
198 * already been done.
200 break;
202 case CONSTANT_Fieldref:
203 case CONSTANT_Methodref:
204 case CONSTANT_InterfaceMethodref:
205 case CONSTANT_NameAndType: {
206 unsigned index = (unsigned)(cp[i].i);
207 int key1 = index >> 16;
208 int key2 = index & 0xFFFF;
209 if (key1 < 1 || key1 >= cp_count
210 || key2 < 1 || key2 >= cp_count) {
211 // CCerror(cb, "Bad index in constant pool #%d", i);
212 return FALSE;
214 if (type == CONSTANT_NameAndType) {
215 if ( (type_table[key1] != utf8_resolved)
216 || (type_table[key2] != utf8_resolved)) {
217 // CCerror(cb, "Bad index in constant pool.");
218 return FALSE;
220 } else {
221 if ( ((type_table[key1] & CONSTANT_POOL_ENTRY_TYPEMASK)
222 != CONSTANT_Class)
223 || ((type_table[key2] != CONSTANT_NameAndType))) {
224 // CCerror(cb, "Bad index in constant pool #%d", i);
225 return FALSE;
228 break;
231 case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
232 case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
233 case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
234 case CONSTANT_NameAndType | CONSTANT_POOL_ENTRY_RESOLVED:
235 // CCerror(cb, "Improperly resolved constant pool #%d", i);
236 return FALSE;
239 case CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED:
240 case CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED:
241 case CONSTANT_Integer | CONSTANT_POOL_ENTRY_RESOLVED:
242 case CONSTANT_Float | CONSTANT_POOL_ENTRY_RESOLVED:
243 break;
245 case CONSTANT_Long | CONSTANT_POOL_ENTRY_RESOLVED:
246 case CONSTANT_Double | CONSTANT_POOL_ENTRY_RESOLVED:
247 if ((i + 1 >= cp_count) ||
248 (type_table[i + 1] != CONSTANT_POOL_ENTRY_RESOLVED)) {
249 // CCerror(cb, "Improper constant pool long/double #%d", i);
250 return FALSE;
251 } else {
252 i++;
253 break;
256 case CONSTANT_Integer:
257 case CONSTANT_Float:
258 case CONSTANT_Long:
259 case CONSTANT_Double:
260 case CONSTANT_Utf8:
261 // CCerror(cb, "Improperly unresolved constant pool #%d", i);
262 return FALSE;
265 default:
266 // CCerror(cb, "Illegal constant pool type at #%d", i);
267 return FALSE;
272 for (i = 1; i < cp_count; i++) {
273 switch(type = type_table[i]) {
274 case CONSTANT_Class: {
275 int index = cp[i].i;
276 if (!is_legal_fieldname(cb, cp[index].cp, LegalClass))
277 return FALSE;
278 break;
281 case CONSTANT_Fieldref:
282 case CONSTANT_Methodref:
283 case CONSTANT_InterfaceMethodref: {
284 unsigned index = (unsigned)(cp[i].i);
285 int name_type_index = index & 0xFFFF;
286 int name_type_key = cp[name_type_index].i;
287 int name_index = name_type_key >> 16;
288 int signature_index = name_type_key & 0xFFFF;
289 char *name = cp[name_index].cp;
290 char *signature = cp[signature_index].cp;
292 if (type == CONSTANT_Fieldref) {
293 if (! (is_legal_fieldname(cb, name, LegalField) &&
294 is_legal_field_signature(cb, name, signature)))
295 return FALSE;
296 } else {
297 if (! (is_legal_fieldname(cb, name, LegalMethod) &&
298 is_legal_method_signature(cb, name, signature)))
299 return FALSE;
301 break;
305 return TRUE;
307 */
309 /*=========================================================================
310 * FUNCTION: is_legal_fieldname
311 * OVERVIEW: Returns true if the given name within the given ClassClass
312 * structure consists of a legal fieldname or a classname
313 * if the third argument is LegalClass.
314 * INTERFACE:
315 * parameters: pointer to the ClassClass structure.
316 * char*: legal field name or a classname
317 * int: type of name (class or field name)
318 *
319 * returns: boolean type
320 *=======================================================================*/
321 #if 0
322 static bool_t
323 is_legal_fieldname(ClassClass *cb, char *name, int type)
325 bool_t result;
326 if (name[0] == '<') {
327 result = (type == LegalMethod) &&
328 ((strcmp(name, "<init>") == 0) ||
329 (strcmp(name, "<clinit>") == 0));
330 } else {
331 char *p;
332 if (type == LegalClass && name[0] == SIGNATURE_ARRAY) {
333 p = skip_over_field_signature(name, FALSE);
334 } else {
335 p = skip_over_fieldname(name, type == LegalClass);
337 result = (p != 0 && p[0] == '\0');
339 if (!result) {
340 char *thing = (type == LegalField) ? "Field"
341 : (type == LegalMethod) ? "Method" : "Class";
343 // CCerror(cb, "Illegal %s name \"%s\"", thing, name);
344 return FALSE;
345 } else {
346 return TRUE;
352 /*=========================================================================
353 * FUNCTION: is_legal_field_signature
354 * OVERVIEW: Returns true if the entire given string within the given
355 * ClassClass structure consists of a legal field signature.
356 * INTERFACE:
357 * parameters: pointer to the ClassClass structure.
358 * char*: field name
359 * char*: field signature
360 *
361 * returns: boolean type
362 *=======================================================================*/
363 static bool_t
364 is_legal_field_signature(ClassClass *cb, char *fieldname, char *signature)
366 char *p = skip_over_field_signature(signature, FALSE);
367 if (p != 0 && p[0] == '\0') {
368 return TRUE;
369 } else {
370 // CCerror(cb, "Field \"%s\" has illegal signature \"%s\"",
371 // fieldname, signature);
372 return FALSE;
377 /*=========================================================================
378 * FUNCTION: is_legal_method_signature
379 * OVERVIEW: Returns true if the entire given string within the given
380 * ClassClass structure consists of a legal method signature.
381 * INTERFACE:
382 * parameters: pointer to the ClassClass structure.
383 * char*: method name
384 * char*: method signature
385 *
386 * returns: boolean type
387 *=======================================================================*/
388 static bool_t
389 is_legal_method_signature(ClassClass *cb, char *methodname, char *signature)
391 char *p = signature;
392 char *next_p;
393 /* The first character must be a '(' */
394 if (*p++ == SIGNATURE_FUNC) {
395 /* Skip over however many legal field signatures there are */
396 while ((next_p = skip_over_field_signature(p, FALSE)) != 0)
397 p = next_p;
398 /* The first non-signature thing better be a ')' */
399 if (*p++ == SIGNATURE_ENDFUNC) {
400 if (methodname[0] == '<') {
401 /* All internal methods must return void */
402 if ((p[0] == SIGNATURE_VOID) && (p[1] == '\0'))
403 return TRUE;
404 } else {
405 /* Now, we better just have a return value. */
406 next_p = skip_over_field_signature(p, TRUE);
407 if (next_p && next_p[0] == '\0')
408 return TRUE;
412 // CCerror(cb, "Method \"%s\" has illegal signature \"%s\"",
413 // methodname, signature);
414 return FALSE;
417 #endif
419 #if 0
421 /*=========================================================================
422 * Automatic code generation tables
423 *=======================================================================*/
424 /* The following tables and code generated using: */
425 /* java GenerateCharacter -verbose -c -identifiers -spec UnicodeData-2.1.2.txt -template check_class.c.template -o check_class.c 8 4 4 */
426 /* The X table has 256 entries for a total of 256 bytes. */
428 static unsigned char X[256] = {
429 0, 1, 2, 3, 4, 5, 6, 7, /* 0x0000 */
430 7, 8, 9, 10, 11, 12, 13, 14, /* 0x0800 */
431 15, 16, 7, 7, 7, 7, 7, 7, /* 0x1000 */
432 7, 7, 7, 7, 7, 7, 17, 18, /* 0x1800 */
433 19, 20, 7, 7, 7, 7, 7, 7, /* 0x2000 */
434 7, 7, 7, 7, 7, 7, 7, 7, /* 0x2800 */
435 21, 22, 7, 7, 7, 7, 7, 7, /* 0x3000 */
436 7, 7, 7, 7, 7, 7, 7, 7, /* 0x3800 */
437 7, 7, 7, 7, 7, 7, 7, 7, /* 0x4000 */
438 7, 7, 7, 7, 7, 7, 23, 23, /* 0x4800 */
439 23, 23, 23, 23, 23, 23, 23, 23, /* 0x5000 */
440 23, 23, 23, 23, 23, 23, 23, 23, /* 0x5800 */
441 23, 23, 23, 23, 23, 23, 23, 23, /* 0x6000 */
442 23, 23, 23, 23, 23, 23, 23, 23, /* 0x6800 */
443 23, 23, 23, 23, 23, 23, 23, 23, /* 0x7000 */
444 23, 23, 23, 23, 23, 23, 23, 23, /* 0x7800 */
445 23, 23, 23, 23, 23, 23, 23, 23, /* 0x8000 */
446 23, 23, 23, 23, 23, 23, 23, 23, /* 0x8800 */
447 23, 23, 23, 23, 23, 23, 23, 23, /* 0x9000 */
448 23, 23, 23, 23, 23, 23, 23, 24, /* 0x9800 */
449 7, 7, 7, 7, 7, 7, 7, 7, /* 0xA000 */
450 7, 7, 7, 7, 23, 23, 23, 23, /* 0xA800 */
451 23, 23, 23, 23, 23, 23, 23, 23, /* 0xB000 */
452 23, 23, 23, 23, 23, 23, 23, 23, /* 0xB800 */
453 23, 23, 23, 23, 23, 23, 23, 23, /* 0xC000 */
454 23, 23, 23, 23, 23, 23, 23, 23, /* 0xC800 */
455 23, 23, 23, 23, 23, 23, 23, 25, /* 0xD000 */
456 7, 7, 7, 7, 7, 7, 7, 7, /* 0xD800 */
457 7, 7, 7, 7, 7, 7, 7, 7, /* 0xE000 */
458 7, 7, 7, 7, 7, 7, 7, 7, /* 0xE800 */
459 7, 7, 7, 7, 7, 7, 7, 7, /* 0xF000 */
460 7, 23, 26, 27, 23, 28, 29, 30 /* 0xF800 */
461 };
463 /* The Y table has 496 entries for a total of 496 bytes. */
465 static unsigned char Y[496] = {
466 0, 0, 1, 2, 3, 4, 3, 5, /* 0 */
467 0, 0, 6, 7, 8, 9, 8, 9, /* 0 */
468 8, 8, 8, 8, 8, 8, 8, 8, /* 1 */
469 8, 8, 8, 8, 8, 8, 8, 10, /* 1 */
470 8, 11, 0, 0, 0, 8, 8, 8, /* 2 */
471 8, 8, 12, 13, 14, 14, 15, 0, /* 2 */
472 16, 16, 16, 16, 17, 0, 18, 19, /* 3 */
473 20, 8, 21, 8, 22, 23, 24, 25, /* 3 */
474 26, 8, 8, 8, 8, 26, 8, 8, /* 4 */
475 27, 8, 8, 8, 28, 8, 29, 30, /* 4 */
476 0, 0, 0, 3, 8, 31, 3, 8, /* 5 */
477 11, 32, 33, 34, 35, 8, 5, 36, /* 5 */
478 0, 0, 3, 5, 37, 38, 2, 39, /* 6 */
479 8, 8, 8, 40, 22, 41, 42, 2, /* 6 */
480 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */
481 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */
482 43, 8, 8, 44, 45, 46, 47, 0, /* 8 */
483 48, 49, 50, 51, 52, 53, 47, 25, /* 8 */
484 54, 49, 50, 55, 56, 57, 58, 59, /* 9 */
485 60, 21, 50, 61, 62, 0, 63, 0, /* 9 */
486 48, 49, 50, 64, 65, 66, 67, 0, /* 10 */
487 68, 69, 70, 71, 72, 73, 74, 0, /* 10 */
488 75, 24, 50, 76, 77, 78, 67, 0, /* 11 */
489 79, 24, 50, 76, 77, 80, 67, 0, /* 11 */
490 79, 24, 50, 81, 82, 73, 67, 0, /* 12 */
491 0, 0, 0, 0, 0, 0, 0, 0, /* 12 */
492 3, 8, 22, 83, 84, 2, 0, 0, /* 13 */
493 85, 86, 87, 88, 89, 90, 0, 0, /* 13 */
494 0, 91, 2, 92, 93, 8, 94, 32, /* 14 */
495 95, 96, 45, 97, 0, 0, 0, 0, /* 14 */
496 0, 0, 0, 0, 0, 0, 0, 0, /* 15 */
497 0, 0, 8, 8, 98, 8, 8, 99, /* 15 */
498 8, 8, 8, 8, 8, 100, 8, 8, /* 16 */
499 8, 8, 101, 8, 8, 8, 8, 94, /* 16 */
500 8, 8, 8, 8, 8, 8, 8, 8, /* 17 */
501 8, 102, 8, 8, 8, 8, 8, 94, /* 17 */
502 8, 103, 8, 8, 103, 104, 8, 105, /* 18 */
503 8, 8, 8, 106, 107, 108, 109, 107, /* 18 */
504 0, 0, 0, 110, 111, 0, 0, 110, /* 19 */
505 0, 0, 109, 0, 0, 112, 113, 0, /* 19 */
506 114, 115, 116, 117, 0, 0, 8, 8, /* 20 */
507 36, 0, 0, 0, 0, 0, 0, 0, /* 20 */
508 118, 0, 119, 120, 3, 8, 8, 8, /* 21 */
509 8, 121, 3, 8, 8, 8, 8, 122, /* 21 */
510 123, 8, 109, 3, 8, 8, 8, 8, /* 22 */
511 22, 0, 0, 0, 0, 0, 0, 0, /* 22 */
512 8, 8, 8, 8, 8, 8, 8, 8, /* 23 */
513 8, 8, 8, 8, 8, 8, 8, 8, /* 23 */
514 8, 8, 8, 8, 8, 8, 8, 8, /* 24 */
515 8, 8, 98, 0, 0, 0, 0, 0, /* 24 */
516 8, 8, 8, 8, 8, 8, 8, 8, /* 25 */
517 8, 8, 25, 0, 0, 0, 0, 0, /* 25 */
518 8, 8, 105, 0, 0, 0, 0, 0, /* 26 */
519 0, 0, 0, 0, 0, 0, 0, 0, /* 26 */
520 99, 124, 50, 125, 126, 8, 8, 8, /* 27 */
521 8, 8, 8, 14, 0, 127, 8, 8, /* 27 */
522 8, 8, 8, 105, 0, 8, 8, 8, /* 28 */
523 8, 128, 8, 8, 11, 0, 0, 102, /* 28 */
524 0, 0, 129, 130, 131, 0, 132, 133, /* 29 */
525 8, 8, 8, 8, 8, 8, 8, 109, /* 29 */
526 1, 2, 3, 4, 3, 5, 134, 8, /* 30 */
527 8, 8, 8, 22, 135, 136, 137, 0 /* 30 */
528 };
530 /* The A table has 2208 entries for a total of 552 bytes. */
532 static unsigned long A[138] = {
533 0x00000000, /* 0 */
534 0x00000300, /* 1 */
535 0x00055555, /* 2 */
536 0xFFFFFFFC, /* 3 */
537 0xC03FFFFF, /* 4 */
538 0x003FFFFF, /* 5 */
539 0x00300FF0, /* 6 */
540 0x00300C00, /* 7 */
541 0xFFFFFFFF, /* 8 */
542 0xFFFF3FFF, /* 9 */
543 0xFFF00FFF, /* 10 */
544 0x0000FFFF, /* 11 */
545 0x0003FFFF, /* 12 */
546 0xFFC3FFFF, /* 13 */
547 0x0000000F, /* 14 */
548 0x000003FF, /* 15 */
549 0x55555555, /* 16 */
550 0x00000555, /* 17 */
551 0x00000005, /* 18 */
552 0x00300000, /* 19 */
553 0xF33F3000, /* 20 */
554 0xFFFFFFCF, /* 21 */
555 0x3FFFFFFF, /* 22 */
556 0x33303FFF, /* 23 */
557 0xFFFFFFF3, /* 24 */
558 0x000000FF, /* 25 */
559 0xF3FFFFFC, /* 26 */
560 0x0000154F, /* 27 */
561 0x03C3C3FF, /* 28 */
562 0xF0FFFFFF, /* 29 */
563 0x000F0FFF, /* 30 */
564 0x000C3FFF, /* 31 */
565 0x55555554, /* 32 */
566 0x55555545, /* 33 */
567 0x45455555, /* 34 */
568 0x00000114, /* 35 */
569 0x0000003F, /* 36 */
570 0x557FFFFF, /* 37 */
571 0x00000015, /* 38 */
572 0xFFFFFFFD, /* 39 */
573 0x3FF0FFFF, /* 40 */
574 0x41555CFF, /* 41 */
575 0x05517D55, /* 42 */
576 0xFFFFFC54, /* 43 */
577 0x5D0FFFFF, /* 44 */
578 0x05555555, /* 45 */
579 0xFFFF0154, /* 46 */
580 0x5555505F, /* 47 */
581 0xC3FFFC54, /* 48 */
582 0xFFFFFFC3, /* 49 */
583 0xFFF3FFFF, /* 50 */
584 0x510FF033, /* 51 */
585 0x05414155, /* 52 */
586 0xCF004000, /* 53 */
587 0xC03FFC10, /* 54 */
588 0x510F3CF3, /* 55 */
589 0x05414015, /* 56 */
590 0x33FC0000, /* 57 */
591 0x55555000, /* 58 */
592 0x000003F5, /* 59 */
593 0xCCFFFC54, /* 60 */
594 0x5D0FFCF3, /* 61 */
595 0x05454555, /* 62 */
596 0x55555003, /* 63 */
597 0x5D0FF0F3, /* 64 */
598 0x05414055, /* 65 */
599 0xCF005000, /* 66 */
600 0x5555500F, /* 67 */
601 0xF03FFC50, /* 68 */
602 0xF33C0FF3, /* 69 */
603 0xF03F03C0, /* 70 */
604 0x500FCFFF, /* 71 */
605 0x05515015, /* 72 */
606 0x00004000, /* 73 */
607 0x55554000, /* 74 */
608 0xF3FFFC54, /* 75 */
609 0x500FFCFF, /* 76 */
610 0x05515155, /* 77 */
611 0x00001400, /* 78 */
612 0xF3FFFC50, /* 79 */
613 0x30001400, /* 80 */
614 0x500FFFFF, /* 81 */
615 0x05515055, /* 82 */
616 0xC01555F7, /* 83 */
617 0x15557FFF, /* 84 */
618 0x0C33C33C, /* 85 */
619 0xFFFCFF00, /* 86 */
620 0x3CF0CCFC, /* 87 */
621 0x0D4555F7, /* 88 */
622 0x055533FF, /* 89 */
623 0x0F055555, /* 90 */
624 0x00050000, /* 91 */
625 0x50044400, /* 92 */
626 0xFFFCFFFF, /* 93 */
627 0x000FFFFF, /* 94 */
628 0x00555155, /* 95 */
629 0x55544555, /* 96 */
630 0x00045554, /* 97 */
631 0x00000FFF, /* 98 */
632 0x00003FFF, /* 99 */
633 0xC00FFFFF, /* 100 */
634 0xFFFF003F, /* 101 */
635 0x00FFFFFF, /* 102 */
636 0x0FFF0FFF, /* 103 */
637 0xCCCCFFFF, /* 104 */
638 0x0FFFFFFF, /* 105 */
639 0x33FFF3FF, /* 106 */
640 0x03FFF3F0, /* 107 */
641 0x00FFF0FF, /* 108 */
642 0x03FFFFFF, /* 109 */
643 0xC0000000, /* 110 */
644 0x00000003, /* 111 */
645 0x01555555, /* 112 */
646 0x00000004, /* 113 */
647 0xFFF0C030, /* 114 */
648 0x0FFF0CFF, /* 115 */
649 0xFFF33300, /* 116 */
650 0x0003FFCF, /* 117 */
651 0x0000CC00, /* 118 */
652 0x555FFFFC, /* 119 */
653 0x00000FFC, /* 120 */
654 0x3FD403FF, /* 121 */
655 0x3F3FFFFF, /* 122 */
656 0xFFFFFC00, /* 123 */
657 0xD000FFC0, /* 124 */
658 0x33FF3FFF, /* 125 */
659 0xFFFFF3CF, /* 126 */
660 0xFFFFFFC0, /* 127 */
661 0xFFFFFFF0, /* 128 */
662 0x00000055, /* 129 */
663 0x000003C0, /* 130 */
664 0xFC000000, /* 131 */
665 0x000C0000, /* 132 */
666 0xFFFFF33F, /* 133 */
667 0xFFFFF000, /* 134 */
668 0xFFF0FFF0, /* 135 */
669 0x03F0FFF0, /* 136 */
670 0x00003C0F /* 137 */
671 };
673 /* In all, the character property tables require 1304 bytes. */
675 /*
676 * This code mirrors Character.isJavaIdentifierStart. It determines whether
677 * the specified character is a legal start of a Java identifier as per JLS.
679 * The parameter ch is the character to be tested; return 1 if the
680 * character is a letter, 0 otherwise.
681 */
682 #define isJavaIdentifierStart(ch) (((A[Y[(X[ch>>8]<<4)|((ch>>4)&0xF)]]>>((ch&0xF)<<1))&3) & 0x2)
684 /*
685 * This code mirrors Character.isJavaIdentifierPart. It determines whether
686 * the specified character is a legal part of a Java identifier as per JLS.
687 *
688 * The parameter ch is the character to be tested; return 1 if the
689 * character is a digit, 0 otherwise.
690 */
691 #define isJavaIdentifierPart(ch) (((A[Y[(X[ch>>8]<<4)|((ch>>4)&0xF)]]>>((ch&0xF)<<1))&3) & 0x1)
694 /*=========================================================================
695 * FUNCTION: skip_over_fieldname
696 * OVERVIEW: Skips over the longest part of the string that could be
697 * taken as a fieldname given a pointer to a string.
698 * Allows '/' if slash_okay parameter is true.
699 * Returns a pointer to just past the fieldname.
700 * Returns NULL if no fieldname is found, or in the case of
701 * slash_okay being TRUE, we may see consecutive slashes
702 * (meaning that we were looking for a qualified path, but
703 * found something that was badly-formed.)
704 * INTERFACE:
705 * parameters: char*: name
706 * boolean: slash_okay
707 *
708 * returns: char* field name or NULL
709 *=======================================================================*/
710 static char *
711 skip_over_fieldname(char *name, bool_t slash_okay)
713 bool_t first;
714 char *p;
715 unicode last_ch = 0;
716 for (p = name, first = TRUE; ; first = FALSE) {
717 char *old_p = p;
718 unicode ch = next_utf2unicode(&p);
719 if (isJavaIdentifierStart(ch) || (!first && isJavaIdentifierPart(ch))
720 || (slash_okay && ch == '/' && !first)
721 || ch == '_' || ch == '$') {
722 if (ch == '/' && last_ch == '/') {
723 return 0; /* Don't permit consecutive slashes */
724 } else {
725 last_ch = ch;
727 } else {
728 return first ? 0 : old_p;
734 /*=========================================================================
735 * FUNCTION: skip_over_field_signature
736 * OVERVIEW: Skips over the longest part of the string that could be
737 * taken as a field signature given a pointer to a string.
738 * Allows "void" if void_okay parameter is true.
739 * Returns a pointer to just past the signature.
740 * Returns NULL if no legal signature is found.
741 * INTERFACE:
742 * parameters: char*: name
743 * boolean: void_okay
744 *
745 * returns: char* field signature or NULL
746 *=======================================================================*/
747 static char *
748 skip_over_field_signature(char *name, bool_t void_okay)
750 for (;;) {
751 switch (name[0]) {
752 case SIGNATURE_VOID:
753 if (!void_okay) return 0;
754 /* FALL THROUGH */
755 case SIGNATURE_BOOLEAN:
756 case SIGNATURE_BYTE:
757 case SIGNATURE_CHAR:
758 case SIGNATURE_SHORT:
759 case SIGNATURE_INT:
760 case SIGNATURE_LONG:
761 return name + 1;
763 case SIGNATURE_FLOAT:
764 case SIGNATURE_DOUBLE:
765 return no_floating_point ? NULL : name + 1;
767 case SIGNATURE_CLASS: {
768 /* Skip over the classname, if one is there. */
769 char *p = skip_over_fieldname(name + 1, TRUE);
770 /* The next character better be a semicolon. */
771 if (p && p[0] == ';') {
772 return p + 1;
774 return NULL;
777 case SIGNATURE_ARRAY:
778 /* The rest of what's there better be a legal signature. */
779 name++;
780 void_okay = FALSE;
781 break;
783 default:
784 return NULL;
790 /*=========================================================================
791 * FUNCTION: CCerror
792 * OVERVIEW: Handles formating errors found during class file
793 * verification.
794 * INTERFACE:
795 * parameters: pointer to the ClassClass structure.
796 * char *: format
797 *
798 * returns: nothing
799 *=======================================================================*/
800 static void
801 CCerror (ClassClass *cb, char *format, ...)
803 if (verbose) {
804 va_list args;
805 // jio_fprintf(stderr, "VERIFIER CLASS ERROR %s:\n", cbName(cb));
806 va_start(args, format);
807 jio_vfprintf(stderr, format, args);
808 va_end(args);
809 // jio_fprintf(stderr, "\n");
814 /*=========================================================================
815 * FUNCTION: IsLegalClassname
816 * OVERVIEW: Determines if the specified name is a legal UTF name for
817 * a class name.
818 * Note that this routine is intended for external use and
819 * expects the internal form of qualified classes
820 * (i.e. the dots should have been replaced by slashes.)
821 * INTERFACE:
822 * parameters: char*: name
823 * boolean: allowArrayClass
824 *
825 * returns: boolean type
826 *=======================================================================*/
827 bool_t IsLegalClassname(char *name, bool_t allowArrayClass)
828 {
829 char *p;
830 if (name[0] == SIGNATURE_ARRAY) {
831 if (!allowArrayClass) {
832 return FALSE;
833 } else {
834 /* Everything that's left better be a field signature */
835 p = skip_over_field_signature(name, FALSE);
837 } else {
838 /* skip over the fieldname. Slashes are okay */
839 p = skip_over_fieldname(name, TRUE);
841 return (p != 0 && p[0] == '\0');
844 #endif