This commit was manufactured by cvs2svn to create branch 'egcs'.
[official-gcc.git] / gcc / java / jcf-reader.c
blobcf5c04277894da913d8afc5e23caed04ae5eea77
1 /* 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.
5 Copyright (C) 1996 Free Software Foundation, Inc.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
26 #include "jcf.h"
27 #include "zipfile.h"
29 int
30 DEFUN(get_attribute, (jcf),
31 JCF *jcf)
33 uint16 attribute_name = (JCF_FILL (jcf, 6), JCF_readu2 (jcf));
34 uint32 attribute_length = JCF_readu4 (jcf);
35 uint32 start_pos = JCF_TELL(jcf);
36 int name_length;
37 unsigned char *name_data;
38 JCF_FILL (jcf, attribute_length);
39 if (attribute_name <= 0 || attribute_name >= JPOOL_SIZE(jcf))
40 return -2;
41 if (JPOOL_TAG (jcf, attribute_name) != CONSTANT_Utf8)
42 return -2;
43 name_length = JPOOL_UTF_LENGTH (jcf, attribute_name);
44 name_data = JPOOL_UTF_DATA (jcf, attribute_name);
46 #ifdef IGNORE_ATTRIBUTE
47 if (IGNORE_ATTRIBUTE (jcf, attribute_name, attribute_length))
49 JCF_SKIP (jcf, attribute_length);
51 else
52 #endif
53 #ifdef HANDLE_SOURCEFILE
54 if (name_length == 10 && memcmp (name_data, "SourceFile", 10) == 0)
56 uint16 sourcefile_index = JCF_readu2 (jcf);
57 HANDLE_SOURCEFILE(sourcefile_index);
59 else
60 #endif
61 #ifdef HANDLE_CONSTANTVALUE
62 if (name_length == 13 && memcmp (name_data, "ConstantValue", 13) == 0)
64 uint16 constantvalue_index = JCF_readu2 (jcf);
65 if (constantvalue_index <= 0 || constantvalue_index >= JPOOL_SIZE(jcf))
66 return -2;
67 HANDLE_CONSTANTVALUE(constantvalue_index);
69 else
70 #endif
71 #ifdef HANDLE_CODE_ATTRIBUTE
72 if (name_length == 4 && memcmp (name_data, "Code", 4) == 0)
74 uint16 j;
75 uint16 max_stack = JCF_readu2 (jcf);
76 uint16 max_locals = JCF_readu2 (jcf);
77 uint32 code_length = JCF_readu4 (jcf);
78 uint16 exception_table_length, attributes_count;
79 if (code_length + 12 > attribute_length)
80 return -1;
81 HANDLE_CODE_ATTRIBUTE(max_stack, max_locals, code_length);
82 JCF_SKIP (jcf, code_length);
83 exception_table_length = JCF_readu2 (jcf);
84 if (code_length + 8 * exception_table_length + 12 > attribute_length)
85 return -1;
86 JCF_SKIP (jcf, 2 * 4 * exception_table_length);
87 attributes_count = JCF_readu2 (jcf);
88 for (j = 0; j < attributes_count; j++)
90 int code = get_attribute (jcf);
91 if (code != 0)
92 return code;
95 else
96 #endif /* HANDLE_CODE_ATTRIBUTE */
97 #ifdef HANDLE_EXCEPTIONS_ATTRIBUTE
98 if (name_length == 10 && memcmp (name_data, "Exceptions", 10) == 0)
100 uint16 count = JCF_readu2 (jcf);
101 HANDLE_EXCEPTIONS_ATTRIBUTE (count);
103 else
104 #endif
105 #ifdef HANDLE_LINENUMBERTABLE_ATTRIBUTE
106 if (name_length == 15 && memcmp (name_data, "LineNumberTable", 15) == 0)
108 uint16 count = JCF_readu2 (jcf);
109 HANDLE_LINENUMBERTABLE_ATTRIBUTE (count);
111 else
112 #endif
113 #ifdef HANDLE_LOCALVARIABLETABLE_ATTRIBUTE
114 if (name_length == 18 && memcmp (name_data, "LocalVariableTable", 18) == 0)
116 uint16 count = JCF_readu2 (jcf);
117 HANDLE_LOCALVARIABLETABLE_ATTRIBUTE (count);
119 else
120 #endif
122 #ifdef PROCESS_OTHER_ATTRIBUTE
123 PROCESS_OTHER_ATTRIBUTE(jcf, attribute_name, attribute_length);
124 #else
125 JCF_SKIP (jcf, attribute_length);
126 #endif
128 if (start_pos + attribute_length != JCF_TELL(jcf))
129 return -1;
130 return 0;
133 /* Read and handle the pre-amble. */
135 DEFUN(jcf_parse_preamble, (jcf),
136 JCF* jcf)
138 uint32 magic = (JCF_FILL (jcf, 8), JCF_readu4 (jcf));
139 uint16 minor_version = JCF_readu2 (jcf);
140 uint16 major_version = JCF_readu2 (jcf);
141 #ifdef HANDLE_MAGIC
142 HANDLE_MAGIC (magic, minor_version, major_version);
143 #endif
144 if (magic != 0xcafebabe)
145 return -1;
146 else
147 return 0;
150 /* Read and handle the constant pool.
152 Return 0 if OK.
153 Return -2 if a bad cross-reference (index of other constant) was seen.
156 DEFUN(jcf_parse_constant_pool, (jcf),
157 JCF* jcf)
159 int i, n;
160 JPOOL_SIZE (jcf) = (JCF_FILL (jcf, 2), JCF_readu2 (jcf));
161 jcf->cpool.tags = ALLOC (JPOOL_SIZE (jcf));
162 jcf->cpool.data = ALLOC (sizeof (jword) * JPOOL_SIZE (jcf));
163 jcf->cpool.tags[0] = 0;
164 #ifdef HANDLE_START_CONSTANT_POOL
165 HANDLE_START_CONSTANT_POOL (JPOOL_SIZE (jcf));
166 #endif
167 for (i = 1; i < (int) JPOOL_SIZE (jcf); i++)
169 int constant_kind;
171 /* Make sure at least 9 bytes are available. This is enough
172 for all fixed-sized constant pool entries (so we don't need many
173 more JCF_FILL calls below), but is is small enough that
174 we are guaranteed to not hit EOF (in a valid .class file). */
175 JCF_FILL (jcf, 9);
176 constant_kind = JCF_readu (jcf);
177 jcf->cpool.tags[i] = constant_kind;
178 switch (constant_kind)
180 case CONSTANT_String:
181 case CONSTANT_Class:
182 jcf->cpool.data[i] = JCF_readu2 (jcf);
183 break;
184 case CONSTANT_Fieldref:
185 case CONSTANT_Methodref:
186 case CONSTANT_InterfaceMethodref:
187 case CONSTANT_NameAndType:
188 jcf->cpool.data[i] = JCF_readu2 (jcf);
189 jcf->cpool.data[i] |= JCF_readu2 (jcf) << 16;
190 break;
191 case CONSTANT_Integer:
192 case CONSTANT_Float:
193 jcf->cpool.data[i] = JCF_readu4 (jcf);
194 break;
195 case CONSTANT_Long:
196 case CONSTANT_Double:
197 jcf->cpool.data[i] = JCF_readu4 (jcf);
198 i++; /* These take up two spots in the constant pool */
199 jcf->cpool.tags[i] = 0;
200 jcf->cpool.data[i] = JCF_readu4 (jcf);
201 break;
202 case CONSTANT_Utf8:
203 n = JCF_readu2 (jcf);
204 JCF_FILL (jcf, n);
205 #ifdef HANDLE_CONSTANT_Utf8
206 HANDLE_CONSTANT_Utf8(jcf, i, n);
207 #else
208 jcf->cpool.data[i] = JCF_TELL(jcf) - 2;
209 JCF_SKIP (jcf, n);
210 #endif
211 break;
212 default:
213 return i;
216 return 0;
219 /* Read various class flags and numbers. */
221 void
222 DEFUN(jcf_parse_class, (jcf),
223 JCF* jcf)
225 int i;
226 uint16 interfaces_count;
227 JCF_FILL (jcf, 8);
228 jcf->access_flags = JCF_readu2 (jcf);
229 jcf->this_class = JCF_readu2 (jcf);
230 jcf->super_class = JCF_readu2 (jcf);
231 interfaces_count = JCF_readu2 (jcf);
233 #ifdef HANDLE_CLASS_INFO
234 HANDLE_CLASS_INFO(jcf->access_flags, jcf->this_class, jcf->super_class, interfaces_count);
235 #endif
237 JCF_FILL (jcf, 2 * interfaces_count);
239 /* Read interfaces. */
240 for (i = 0; i < interfaces_count; i++)
242 uint16 index = JCF_readu2 (jcf);
243 #ifdef HANDLE_CLASS_INTERFACE
244 HANDLE_CLASS_INTERFACE (index);
245 #endif
249 /* Read fields. */
251 DEFUN(jcf_parse_fields, (jcf),
252 JCF* jcf)
254 int i, j;
255 uint16 fields_count;
256 JCF_FILL (jcf, 2);
257 fields_count = JCF_readu2 (jcf);
259 #ifdef HANDLE_START_FIELDS
260 HANDLE_START_FIELDS (fields_count);
261 #endif
262 for (i = 0; i < fields_count; i++)
264 uint16 access_flags = (JCF_FILL (jcf, 8), JCF_readu2 (jcf));
265 uint16 name_index = JCF_readu2 (jcf);
266 uint16 signature_index = JCF_readu2 (jcf);
267 uint16 attribute_count = JCF_readu2 (jcf);
268 #ifdef HANDLE_START_FIELD
269 HANDLE_START_FIELD (access_flags, name_index, signature_index,
270 attribute_count);
271 #endif
272 for (j = 0; j < attribute_count; j++)
274 int code = get_attribute (jcf);
275 if (code != 0)
276 return code;
278 #ifdef HANDLE_END_FIELD
279 HANDLE_END_FIELD ();
280 #endif
282 #ifdef HANDLE_END_FIELDS
283 HANDLE_END_FIELDS ();
284 #endif
285 return 0;
288 /* Read methods. */
291 DEFUN(jcf_parse_one_method, (jcf),
292 JCF* jcf)
294 int i;
295 uint16 access_flags = (JCF_FILL (jcf, 8), JCF_readu2 (jcf));
296 uint16 name_index = JCF_readu2 (jcf);
297 uint16 signature_index = JCF_readu2 (jcf);
298 uint16 attribute_count = JCF_readu2 (jcf);
299 #ifdef HANDLE_METHOD
300 HANDLE_METHOD(access_flags, name_index, signature_index, attribute_count);
301 #endif
302 for (i = 0; i < attribute_count; i++)
304 int code = get_attribute (jcf);
305 if (code != 0)
306 return code;
308 return 0;
312 DEFUN(jcf_parse_methods, (jcf),
313 JCF* jcf)
315 int i;
316 uint16 methods_count;
317 JCF_FILL (jcf, 2);
318 methods_count = JCF_readu2 (jcf);
319 #ifdef HANDLE_START_METHODS
320 HANDLE_START_METHODS (methods_count);
321 #endif
322 for (i = 0; i < methods_count; i++)
324 int code = jcf_parse_one_method (jcf);
325 if (code != 0)
326 return code;
328 #ifdef HANDLE_END_METHODS
329 HANDLE_END_METHODS ();
330 #endif
331 return 0;
334 /* Read attributes. */
336 DEFUN(jcf_parse_final_attributes, (jcf),
337 JCF *jcf)
339 int i;
340 uint16 attributes_count = (JCF_FILL (jcf, 2), JCF_readu2 (jcf));
341 #ifdef START_FINAL_ATTRIBUTES
342 START_FINAL_ATTRIBUTES (attributes_count)
343 #endif
344 for (i = 0; i < attributes_count; i++)
346 int code = get_attribute (jcf);
347 if (code != 0)
348 return code;
350 return 0;