OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [java/] [jcf-reader.c] - Blame information for rev 826

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 287 jeremybenn
/* This file read a Java(TM) .class file.
2
   It is not stand-alone:  It depends on tons of macros, and the
3
   intent is you #include this file after you've defined the macros.
4
   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
5
   2007, 2008 Free Software Foundation, Inc.
6
 
7
This file is part of GCC.
8
 
9
GCC is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 3, or (at your option)
12
any later version.
13
 
14
GCC is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
GNU General Public License for more details.
18
 
19
You should have received a copy of the GNU General Public License
20
along with GCC; see the file COPYING3.  If not see
21
<http://www.gnu.org/licenses/>.
22
 
23
Java and all Java-based marks are trademarks or registered trademarks
24
of Sun Microsystems, Inc. in the United States and other countries.
25
The Free Software Foundation is independent of Sun Microsystems, Inc.  */
26
 
27
#include "jcf.h"
28
#include "zipfile.h"
29
 
30
static int get_attribute (JCF *, int, jv_attr_type);
31
static int jcf_parse_preamble (JCF *);
32
static int jcf_parse_constant_pool (JCF *);
33
static void jcf_parse_class (JCF *);
34
static int jcf_parse_fields (JCF *);
35
static int jcf_parse_one_method (JCF *, int);
36
static int jcf_parse_methods (JCF *);
37
static int jcf_parse_final_attributes (JCF *);
38
#ifdef NEED_PEEK_ATTRIBUTE
39
static int peek_attribute (JCF *, int, const char *, int);
40
#endif
41
#ifdef NEED_SKIP_ATTRIBUTE
42
static void skip_attribute (JCF *, int);
43
#endif
44
 
45
/* Go through all available attribute (ATTRIBUTE_NUMER) and try to
46
   identify PEEKED_NAME.  Return 1 if PEEKED_NAME was found, 0
47
   otherwise. JCF is restored to its initial position before
48
   returning.  */
49
 
50
#ifdef NEED_PEEK_ATTRIBUTE      /* Not everyone uses this function */
51
static int
52
peek_attribute (JCF *jcf, int attribute_number, const char *peeked_name,
53
                int peeked_name_length)
54
{
55
  int to_return = 0;
56
  long absolute_offset = (long)JCF_TELL (jcf);
57
  int i;
58
 
59
  for (i = 0; !to_return && i < attribute_number; i++)
60
    {
61
      uint16 attribute_name = (JCF_FILL (jcf, 6), JCF_readu2 (jcf));
62
      uint32 attribute_length = JCF_readu4 (jcf);
63
      int name_length;
64
      const unsigned char *name_data;
65
 
66
      JCF_FILL (jcf, (long) attribute_length);
67
      if (attribute_name <= 0 || attribute_name >= JPOOL_SIZE(jcf)
68
          || JPOOL_TAG (jcf, attribute_name) != CONSTANT_Utf8)
69
        continue;
70
 
71
      name_length = JPOOL_UTF_LENGTH (jcf, attribute_name);
72
      name_data = JPOOL_UTF_DATA (jcf, attribute_name);
73
 
74
      if (name_length == peeked_name_length
75
          && ! memcmp (name_data, peeked_name, peeked_name_length))
76
        {
77
          to_return = 1;
78
          break;
79
        }
80
 
81
      JCF_SKIP (jcf, attribute_length);
82
    }
83
 
84
  JCF_SEEK (jcf, absolute_offset);
85
  return to_return;
86
}
87
#endif
88
 
89
#ifdef NEED_SKIP_ATTRIBUTE      /* Not everyone uses this function */
90
static void
91
skip_attribute (JCF *jcf, int number_of_attribute)
92
{
93
  while (number_of_attribute--)
94
    {
95
      JCF_u4 N;
96
      JCF_FILL (jcf, 6);
97
      (void) JCF_readu2 (jcf);
98
      N = JCF_readu4 (jcf);
99
      JCF_SKIP (jcf, N);
100
    }
101
}
102
#endif
103
 
104
static int
105
get_attribute (JCF *jcf, int index,
106
               jv_attr_type attr_type ATTRIBUTE_UNUSED)
107
{
108
  uint16 attribute_name = (JCF_FILL (jcf, 6), JCF_readu2 (jcf));
109
  uint32 attribute_length = JCF_readu4 (jcf);
110
  uint32 start_pos = JCF_TELL(jcf);
111
  int name_length;
112
  const unsigned char *name_data;
113
  JCF_FILL (jcf, (long) attribute_length);
114
  if (attribute_name <= 0 || attribute_name >= JPOOL_SIZE(jcf))
115
    return -2;
116
  if (JPOOL_TAG (jcf, attribute_name) != CONSTANT_Utf8)
117
    return -2;
118
  name_length = JPOOL_UTF_LENGTH (jcf, attribute_name);
119
  name_data = JPOOL_UTF_DATA (jcf, attribute_name);
120
 
121
#define MATCH_ATTRIBUTE(S) \
122
  (name_length == sizeof (S)-1 && memcmp (name_data, S, sizeof (S)-1) == 0)
123
 
124
#ifdef IGNORE_ATTRIBUTE
125
   if (IGNORE_ATTRIBUTE (jcf, attribute_name, attribute_length))
126
     {
127
       JCF_SKIP (jcf, attribute_length);
128
     }
129
   else
130
#endif
131
#ifdef HANDLE_SOURCEFILE
132
  if (MATCH_ATTRIBUTE ("SourceFile"))
133
    {
134
      uint16 sourcefile_index = JCF_readu2 (jcf);
135
      HANDLE_SOURCEFILE(sourcefile_index);
136
    }
137
  else
138
#endif
139
#ifdef HANDLE_CONSTANTVALUE
140
  if (MATCH_ATTRIBUTE ("ConstantValue"))
141
    {
142
      uint16 constantvalue_index = JCF_readu2 (jcf);
143
      if (constantvalue_index <= 0 || constantvalue_index >= JPOOL_SIZE(jcf))
144
        return -2;
145
      HANDLE_CONSTANTVALUE(constantvalue_index);
146
    }
147
  else
148
#endif
149
#ifdef HANDLE_CODE_ATTRIBUTE
150
  if (MATCH_ATTRIBUTE ("Code"))
151
    {
152
      uint16 j;
153
      uint16 max_stack ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
154
      uint16 max_locals ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
155
      uint32 code_length = JCF_readu4 (jcf);
156
      uint16 exception_table_length, attributes_count;
157
      if (code_length + 12 > attribute_length)
158
        return -1;
159
      HANDLE_CODE_ATTRIBUTE(max_stack, max_locals, code_length);
160
      JCF_SKIP (jcf, code_length);
161
      exception_table_length = JCF_readu2 (jcf);
162
      if (code_length + 8 * exception_table_length + 12 > attribute_length)
163
        return -1;
164
#ifdef HANDLE_EXCEPTION_TABLE
165
      HANDLE_EXCEPTION_TABLE (jcf->read_ptr, exception_table_length);
166
#endif
167
      JCF_SKIP (jcf, 2 * 4 * exception_table_length);
168
      attributes_count = JCF_readu2 (jcf);
169
      for (j = 0; j < attributes_count; j++)
170
        {
171
          int code = get_attribute (jcf, index, JV_METHOD_ATTR);
172
          if (code != 0)
173
            return code;
174
        }
175
    }
176
  else
177
#endif /* HANDLE_CODE_ATTRIBUTE */
178
#ifdef HANDLE_EXCEPTIONS_ATTRIBUTE
179
  if (MATCH_ATTRIBUTE ("Exceptions"))
180
    {
181
      uint16 count = JCF_readu2 (jcf);
182
      HANDLE_EXCEPTIONS_ATTRIBUTE (count);
183
    }
184
  else
185
#endif
186
#ifdef HANDLE_LINENUMBERTABLE_ATTRIBUTE
187
  if (MATCH_ATTRIBUTE ("LineNumberTable"))
188
    {
189
      uint16 count = JCF_readu2 (jcf);
190
      HANDLE_LINENUMBERTABLE_ATTRIBUTE (count);
191
    }
192
  else
193
#endif
194
#ifdef HANDLE_LOCALVARIABLETABLE_ATTRIBUTE
195
  if (MATCH_ATTRIBUTE ("LocalVariableTable"))
196
    {
197
      uint16 count = JCF_readu2 (jcf);
198
      HANDLE_LOCALVARIABLETABLE_ATTRIBUTE (count);
199
    }
200
  else
201
#endif
202
#ifdef HANDLE_LOCALVARIABLETYPETABLE_ATTRIBUTE
203
  if (MATCH_ATTRIBUTE ("LocalVariableTypeTable"))
204
    {
205
      uint16 count = JCF_readu2 (jcf);
206
      HANDLE_LOCALVARIABLETYPETABLE_ATTRIBUTE (count);
207
    }
208
  else
209
#endif
210
#ifdef HANDLE_INNERCLASSES_ATTRIBUTE
211
  if (MATCH_ATTRIBUTE ("InnerClasses"))
212
    {
213
      uint16 count = JCF_readu2 (jcf);
214
      HANDLE_INNERCLASSES_ATTRIBUTE (count);
215
    }
216
  else
217
#endif
218
#ifdef HANDLE_SYNTHETIC_ATTRIBUTE
219
  if (MATCH_ATTRIBUTE ("Synthetic"))
220
    {
221
      HANDLE_SYNTHETIC_ATTRIBUTE ();
222
    }
223
  else
224
#endif
225
#ifdef HANDLE_GCJCOMPILED_ATTRIBUTE
226
  if (MATCH_ATTRIBUTE ("gnu.gcj.gcj-compiled"))
227
    {
228
      HANDLE_GCJCOMPILED_ATTRIBUTE ();
229
    }
230
  else
231
#endif
232
#ifdef HANDLE_DEPRECATED_ATTRIBUTE
233
  if (MATCH_ATTRIBUTE ("Deprecated"))
234
    {
235
      HANDLE_DEPRECATED_ATTRIBUTE ();
236
    }
237
  else
238
#endif
239
#ifdef HANDLE_SOURCEDEBUGEXTENSION_ATTRIBUTE
240
  if (MATCH_ATTRIBUTE ("SourceDebugExtension")) /* JSR 45 */
241
    {
242
      HANDLE_SOURCEDEBUGEXTENSION_ATTRIBUTE (attribute_length);
243
    }
244
  else
245
#endif
246
#ifdef HANDLE_ENCLOSINGMETHOD_ATTRIBUTE
247
  if (MATCH_ATTRIBUTE ("EnclosingMethod"))
248
    {
249
      HANDLE_ENCLOSINGMETHOD_ATTRIBUTE ();
250
    }
251
  else
252
#endif
253
#ifdef HANDLE_SIGNATURE_ATTRIBUTE
254
  if (MATCH_ATTRIBUTE ("Signature"))
255
    {
256
      HANDLE_SIGNATURE_ATTRIBUTE ();
257
    }
258
  else
259
#endif
260
#ifdef HANDLE_RUNTIMEVISIBLEANNOTATIONS_ATTRIBUTE
261
  if (MATCH_ATTRIBUTE ("RuntimeVisibleAnnotations"))
262
    {
263
      HANDLE_RUNTIMEVISIBLEANNOTATIONS_ATTRIBUTE ();
264
    }
265
  else
266
#endif
267
#ifdef HANDLE_RUNTIMEINVISIBLEANNOTATIONS_ATTRIBUTE
268
  if (MATCH_ATTRIBUTE ("RuntimeInvisibleAnnotations"))
269
    {
270
      HANDLE_RUNTIMEINVISIBLEANNOTATIONS_ATTRIBUTE ();
271
    }
272
  else
273
#endif
274
#ifdef HANDLE_RUNTIMEVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE
275
  if (MATCH_ATTRIBUTE ("RuntimeVisibleParameterAnnotations"))
276
    {
277
      HANDLE_RUNTIMEVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE ();
278
    }
279
  else
280
#endif
281
#ifdef HANDLE_RUNTIMEINVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE
282
  if (MATCH_ATTRIBUTE ("RuntimeInvisibleParameterAnnotations"))
283
    {
284
      HANDLE_RUNTIMEINVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE ();
285
    }
286
  else
287
#endif
288
#ifdef HANDLE_ANNOTATIONDEFAULT_ATTRIBUTE
289
  if (MATCH_ATTRIBUTE ("AnnotationDefault"))
290
    {
291
      HANDLE_ANNOTATIONDEFAULT_ATTRIBUTE ();
292
    }
293
  else
294
#endif
295
    {
296
#ifdef PROCESS_OTHER_ATTRIBUTE
297
      PROCESS_OTHER_ATTRIBUTE(jcf, attribute_name, attribute_length);
298
#else
299
      JCF_SKIP (jcf, attribute_length);
300
#endif
301
    }
302
  if ((long) (start_pos + attribute_length) != JCF_TELL(jcf))
303
    return -1;
304
  return 0;
305
}
306
 
307
/* Read and handle the pre-amble. */
308
static int
309
jcf_parse_preamble (JCF* jcf)
310
{
311
  uint32 magic = (JCF_FILL (jcf, 8), JCF_readu4 (jcf));
312
  uint16 minor_version ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
313
  uint16 major_version ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
314
#ifdef HANDLE_MAGIC
315
  HANDLE_MAGIC (magic, minor_version, major_version);
316
#endif
317
  if (magic != 0xcafebabe)
318
    return -1;
319
  else
320
    return 0;
321
}
322
 
323
/* Read and handle the constant pool.
324
 
325
   Return 0 if OK.
326
   Return -2 if a bad cross-reference (index of other constant) was seen.
327
*/
328
static int
329
jcf_parse_constant_pool (JCF* jcf)
330
{
331
  int i, n;
332
  JPOOL_SIZE (jcf) = (JCF_FILL (jcf, 2), JCF_readu2 (jcf));
333
  jcf->cpool.tags = GGC_NEWVAR (uint8, JPOOL_SIZE (jcf));
334
  jcf->cpool.data = GGC_NEWVAR (union cpool_entry, sizeof (jword) * JPOOL_SIZE (jcf));
335
  jcf->cpool.tags[0] = 0;
336
#ifdef HANDLE_START_CONSTANT_POOL
337
  HANDLE_START_CONSTANT_POOL (JPOOL_SIZE (jcf));
338
#endif
339
  for (i = 1; i < (int) JPOOL_SIZE (jcf); i++)
340
    {
341
      int constant_kind;
342
 
343
      /* Make sure at least 9 bytes are available.  This is enough
344
         for all fixed-sized constant pool entries (so we don't need many
345
         more JCF_FILL calls below), but is is small enough that
346
         we are guaranteed to not hit EOF (in a valid .class file). */
347
      JCF_FILL (jcf, 9);
348
      constant_kind = JCF_readu (jcf);
349
      jcf->cpool.tags[i] = constant_kind;
350
      switch (constant_kind)
351
        {
352
        case CONSTANT_String:
353
        case CONSTANT_Class:
354
          jcf->cpool.data[i].w = JCF_readu2 (jcf);
355
          break;
356
        case CONSTANT_Fieldref:
357
        case CONSTANT_Methodref:
358
        case CONSTANT_InterfaceMethodref:
359
        case CONSTANT_NameAndType:
360
          jcf->cpool.data[i].w = JCF_readu2 (jcf);
361
          jcf->cpool.data[i].w |= JCF_readu2 (jcf) << 16;
362
          break;
363
        case CONSTANT_Integer:
364
        case CONSTANT_Float:
365
          jcf->cpool.data[i].w = JCF_readu4 (jcf);
366
          break;
367
        case CONSTANT_Long:
368
        case CONSTANT_Double:
369
          jcf->cpool.data[i].w = JCF_readu4 (jcf);
370
          i++; /* These take up two spots in the constant pool */
371
          jcf->cpool.tags[i] = 0;
372
          jcf->cpool.data[i].w = JCF_readu4 (jcf);
373
          break;
374
        case CONSTANT_Utf8:
375
          n = JCF_readu2 (jcf);
376
          JCF_FILL (jcf, n);
377
#ifdef HANDLE_CONSTANT_Utf8
378
          HANDLE_CONSTANT_Utf8(jcf, i, n);
379
#else
380
          jcf->cpool.data[i].w = JCF_TELL(jcf) - 2;
381
          JCF_SKIP (jcf, n);
382
#endif
383
          break;
384
        default:
385
          return i;
386
        }
387
    }
388
  return 0;
389
}
390
 
391
/* Read various class flags and numbers. */
392
 
393
static void
394
jcf_parse_class (JCF* jcf)
395
{
396
  int i;
397
  uint16 interfaces_count;
398
  JCF_FILL (jcf, 8);
399
  jcf->access_flags = JCF_readu2 (jcf);
400
  jcf->this_class = JCF_readu2 (jcf);
401
  jcf->super_class = JCF_readu2 (jcf);
402
  interfaces_count = JCF_readu2 (jcf);
403
 
404
#ifdef HANDLE_CLASS_INFO
405
  HANDLE_CLASS_INFO(jcf->access_flags, jcf->this_class, jcf->super_class, interfaces_count);
406
#endif
407
 
408
  JCF_FILL (jcf, 2 * interfaces_count);
409
 
410
  /* Read interfaces. */
411
  for (i = 0; i < interfaces_count; i++)
412
    {
413
      uint16 index ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
414
#ifdef HANDLE_CLASS_INTERFACE
415
      HANDLE_CLASS_INTERFACE (index);
416
#endif
417
    }
418
}
419
 
420
/* Read fields. */
421
static int
422
jcf_parse_fields (JCF* jcf)
423
{
424
  int i, j;
425
  uint16 fields_count;
426
  JCF_FILL (jcf, 2);
427
  fields_count = JCF_readu2 (jcf);
428
 
429
#ifdef HANDLE_START_FIELDS
430
  HANDLE_START_FIELDS (fields_count);
431
#endif
432
  for (i = 0; i < fields_count; i++)
433
    {
434
      uint16 access_flags = (JCF_FILL (jcf, 8), JCF_readu2 (jcf));
435
      uint16 name_index = JCF_readu2 (jcf);
436
      uint16 signature_index = JCF_readu2 (jcf);
437
      uint16 attribute_count = JCF_readu2 (jcf);
438
#ifdef HANDLE_START_FIELD
439
      HANDLE_START_FIELD (access_flags, name_index, signature_index,
440
                          attribute_count);
441
#endif
442
      for (j = 0; j < attribute_count; j++)
443
        {
444
          int code = get_attribute (jcf, i, JV_FIELD_ATTR);
445
          if (code != 0)
446
            return code;
447
        }
448
#ifdef HANDLE_END_FIELD
449
      HANDLE_END_FIELD ();
450
#endif
451
    }
452
#ifdef HANDLE_END_FIELDS
453
  HANDLE_END_FIELDS ();
454
#endif
455
  return 0;
456
}
457
 
458
/* Read methods. */
459
 
460
static int
461
jcf_parse_one_method (JCF* jcf, int index)
462
{
463
  int i;
464
  uint16 access_flags = (JCF_FILL (jcf, 8), JCF_readu2 (jcf));
465
  uint16 name_index = JCF_readu2 (jcf);
466
  uint16 signature_index = JCF_readu2 (jcf);
467
  uint16 attribute_count = JCF_readu2 (jcf);
468
#ifdef HANDLE_METHOD
469
  HANDLE_METHOD(access_flags, name_index, signature_index, attribute_count);
470
#endif
471
  for (i = 0; i < attribute_count; i++)
472
    {
473
      int code = get_attribute (jcf, index, JV_METHOD_ATTR);
474
      if (code != 0)
475
        return code;
476
    }
477
#ifdef HANDLE_END_METHOD
478
  HANDLE_END_METHOD ();
479
#endif
480
  return 0;
481
}
482
 
483
static int
484
jcf_parse_methods (JCF* jcf)
485
{
486
  int i;
487
  uint16 methods_count;
488
  JCF_FILL (jcf, 2);
489
  methods_count = JCF_readu2 (jcf);
490
#ifdef HANDLE_START_METHODS
491
  HANDLE_START_METHODS (methods_count);
492
#endif
493
  for (i = 0; i < methods_count; i++)
494
    {
495
      int code = jcf_parse_one_method (jcf, i);
496
      if (code != 0)
497
        return code;
498
    }
499
#ifdef HANDLE_END_METHODS
500
  HANDLE_END_METHODS ();
501
#endif
502
  return 0;
503
}
504
 
505
/* Read attributes. */
506
static int
507
jcf_parse_final_attributes (JCF *jcf)
508
{
509
  int i;
510
  uint16 attributes_count = (JCF_FILL (jcf, 2), JCF_readu2 (jcf));
511
#ifdef START_FINAL_ATTRIBUTES
512
  START_FINAL_ATTRIBUTES (attributes_count)
513
#endif
514
  for (i = 0; i < attributes_count; i++)
515
    {
516
      int code = get_attribute (jcf, i, JV_CLASS_ATTR);
517
      if (code != 0)
518
        return code;
519
    }
520
  return 0;
521
}
522
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.