00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "jcf.h"
00027 #include "zipfile.h"
00028
00029 static int get_attribute PARAMS ((JCF *));
00030 static int jcf_parse_preamble PARAMS ((JCF *));
00031 static int jcf_parse_constant_pool PARAMS ((JCF *));
00032 static void jcf_parse_class PARAMS ((JCF *));
00033 static int jcf_parse_fields PARAMS ((JCF *));
00034 static int jcf_parse_one_method PARAMS ((JCF *));
00035 static int jcf_parse_methods PARAMS ((JCF *));
00036 static int jcf_parse_final_attributes PARAMS ((JCF *));
00037 #ifdef NEED_PEEK_ATTRIBUTE
00038 static int peek_attribute PARAMS ((JCF *, int, const char *, int));
00039 #endif
00040 #ifdef NEED_SKIP_ATTRIBUTE
00041 static void skip_attribute PARAMS ((JCF *, int));
00042 #endif
00043
00044
00045
00046
00047
00048
00049 #ifdef NEED_PEEK_ATTRIBUTE
00050 static int
00051 peek_attribute (jcf, attribute_number, peeked_name, peeked_name_length)
00052 JCF *jcf;
00053 int attribute_number;
00054 const char *peeked_name;
00055 int peeked_name_length;
00056 {
00057 int to_return = 0;
00058 long absolute_offset = (long)JCF_TELL (jcf);
00059 int i;
00060
00061 for (i = 0; !to_return && i < attribute_number; i++)
00062 {
00063 uint16 attribute_name = (JCF_FILL (jcf, 6), JCF_readu2 (jcf));
00064 uint32 attribute_length = JCF_readu4 (jcf);
00065 int name_length;
00066 const unsigned char *name_data;
00067
00068 JCF_FILL (jcf, (long) attribute_length);
00069 if (attribute_name <= 0 || attribute_name >= JPOOL_SIZE(jcf)
00070 || JPOOL_TAG (jcf, attribute_name) != CONSTANT_Utf8)
00071 continue;
00072
00073 name_length = JPOOL_UTF_LENGTH (jcf, attribute_name);
00074 name_data = JPOOL_UTF_DATA (jcf, attribute_name);
00075
00076 if (name_length == peeked_name_length
00077 && ! memcmp (name_data, peeked_name, peeked_name_length))
00078 {
00079 to_return = 1;
00080 break;
00081 }
00082
00083 JCF_SKIP (jcf, attribute_length);
00084 }
00085
00086 JCF_SEEK (jcf, absolute_offset);
00087 return to_return;
00088 }
00089 #endif
00090
00091 #ifdef NEED_SKIP_ATTRIBUTE
00092 static void
00093 skip_attribute (jcf, number_of_attribute)
00094 JCF *jcf;
00095 int number_of_attribute;
00096 {
00097 while (number_of_attribute--)
00098 {
00099 JCF_FILL (jcf, 6);
00100 (void) JCF_readu2 (jcf);
00101 JCF_SKIP (jcf, JCF_readu4 (jcf));
00102 }
00103 }
00104 #endif
00105
00106 static int
00107 DEFUN(get_attribute, (jcf),
00108 JCF *jcf)
00109 {
00110 uint16 attribute_name = (JCF_FILL (jcf, 6), JCF_readu2 (jcf));
00111 uint32 attribute_length = JCF_readu4 (jcf);
00112 uint32 start_pos = JCF_TELL(jcf);
00113 int name_length;
00114 const unsigned char *name_data;
00115 JCF_FILL (jcf, (long) attribute_length);
00116 if (attribute_name <= 0 || attribute_name >= JPOOL_SIZE(jcf))
00117 return -2;
00118 if (JPOOL_TAG (jcf, attribute_name) != CONSTANT_Utf8)
00119 return -2;
00120 name_length = JPOOL_UTF_LENGTH (jcf, attribute_name);
00121 name_data = JPOOL_UTF_DATA (jcf, attribute_name);
00122
00123 #define MATCH_ATTRIBUTE(S) \
00124 (name_length == sizeof (S)-1 && memcmp (name_data, S, sizeof (S)-1) == 0)
00125
00126 #ifdef IGNORE_ATTRIBUTE
00127 if (IGNORE_ATTRIBUTE (jcf, attribute_name, attribute_length))
00128 {
00129 JCF_SKIP (jcf, attribute_length);
00130 }
00131 else
00132 #endif
00133 #ifdef HANDLE_SOURCEFILE
00134 if (MATCH_ATTRIBUTE ("SourceFile"))
00135 {
00136 uint16 sourcefile_index = JCF_readu2 (jcf);
00137 HANDLE_SOURCEFILE(sourcefile_index);
00138 }
00139 else
00140 #endif
00141 #ifdef HANDLE_CONSTANTVALUE
00142 if (MATCH_ATTRIBUTE ("ConstantValue"))
00143 {
00144 uint16 constantvalue_index = JCF_readu2 (jcf);
00145 if (constantvalue_index <= 0 || constantvalue_index >= JPOOL_SIZE(jcf))
00146 return -2;
00147 HANDLE_CONSTANTVALUE(constantvalue_index);
00148 }
00149 else
00150 #endif
00151 #ifdef HANDLE_CODE_ATTRIBUTE
00152 if (MATCH_ATTRIBUTE ("Code"))
00153 {
00154 uint16 j;
00155 uint16 max_stack ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
00156 uint16 max_locals ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
00157 uint32 code_length = JCF_readu4 (jcf);
00158 uint16 exception_table_length, attributes_count;
00159 if (code_length + 12 > attribute_length)
00160 return -1;
00161 HANDLE_CODE_ATTRIBUTE(max_stack, max_locals, code_length);
00162 JCF_SKIP (jcf, code_length);
00163 exception_table_length = JCF_readu2 (jcf);
00164 if (code_length + 8 * exception_table_length + 12 > attribute_length)
00165 return -1;
00166 #ifdef HANDLE_EXCEPTION_TABLE
00167 HANDLE_EXCEPTION_TABLE (jcf->read_ptr, exception_table_length);
00168 #endif
00169 JCF_SKIP (jcf, 2 * 4 * exception_table_length);
00170 attributes_count = JCF_readu2 (jcf);
00171 for (j = 0; j < attributes_count; j++)
00172 {
00173 int code = get_attribute (jcf);
00174 if (code != 0)
00175 return code;
00176 }
00177 }
00178 else
00179 #endif
00180 #ifdef HANDLE_EXCEPTIONS_ATTRIBUTE
00181 if (MATCH_ATTRIBUTE ("Exceptions"))
00182 {
00183 uint16 count = JCF_readu2 (jcf);
00184 HANDLE_EXCEPTIONS_ATTRIBUTE (count);
00185 }
00186 else
00187 #endif
00188 #ifdef HANDLE_LINENUMBERTABLE_ATTRIBUTE
00189 if (MATCH_ATTRIBUTE ("LineNumberTable"))
00190 {
00191 uint16 count = JCF_readu2 (jcf);
00192 HANDLE_LINENUMBERTABLE_ATTRIBUTE (count);
00193 }
00194 else
00195 #endif
00196 #ifdef HANDLE_LOCALVARIABLETABLE_ATTRIBUTE
00197 if (MATCH_ATTRIBUTE ("LocalVariableTable"))
00198 {
00199 uint16 count = JCF_readu2 (jcf);
00200 HANDLE_LOCALVARIABLETABLE_ATTRIBUTE (count);
00201 }
00202 else
00203 #endif
00204 #ifdef HANDLE_INNERCLASSES_ATTRIBUTE
00205 if (MATCH_ATTRIBUTE ("InnerClasses"))
00206 {
00207 uint16 count = JCF_readu2 (jcf);
00208 HANDLE_INNERCLASSES_ATTRIBUTE (count);
00209 }
00210 else
00211 #endif
00212 #ifdef HANDLE_SYNTHETIC_ATTRIBUTE
00213 if (MATCH_ATTRIBUTE ("Synthetic"))
00214 {
00215 HANDLE_SYNTHETIC_ATTRIBUTE ();
00216 }
00217 else
00218 #endif
00219 #ifdef HANDLE_GCJCOMPILED_ATTRIBUTE
00220 if (MATCH_ATTRIBUTE ("gnu.gcj.gcj-compiled"))
00221 {
00222 HANDLE_GCJCOMPILED_ATTRIBUTE ();
00223 }
00224 else
00225 #endif
00226 {
00227 #ifdef PROCESS_OTHER_ATTRIBUTE
00228 PROCESS_OTHER_ATTRIBUTE(jcf, attribute_name, attribute_length);
00229 #else
00230 JCF_SKIP (jcf, attribute_length);
00231 #endif
00232 }
00233 if ((long) (start_pos + attribute_length) != JCF_TELL(jcf))
00234 return -1;
00235 return 0;
00236 }
00237
00238
00239 static int
00240 DEFUN(jcf_parse_preamble, (jcf),
00241 JCF* jcf)
00242 {
00243 uint32 magic = (JCF_FILL (jcf, 8), JCF_readu4 (jcf));
00244 uint16 minor_version ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
00245 uint16 major_version ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
00246 #ifdef HANDLE_MAGIC
00247 HANDLE_MAGIC (magic, minor_version, major_version);
00248 #endif
00249 if (magic != 0xcafebabe)
00250 return -1;
00251 else
00252 return 0;
00253 }
00254
00255
00256
00257
00258
00259
00260 static int
00261 DEFUN(jcf_parse_constant_pool, (jcf),
00262 JCF* jcf)
00263 {
00264 int i, n;
00265 JPOOL_SIZE (jcf) = (JCF_FILL (jcf, 2), JCF_readu2 (jcf));
00266 jcf->cpool.tags = ALLOC (JPOOL_SIZE (jcf));
00267 jcf->cpool.data = ALLOC (sizeof (jword) * JPOOL_SIZE (jcf));
00268 jcf->cpool.tags[0] = 0;
00269 #ifdef HANDLE_START_CONSTANT_POOL
00270 HANDLE_START_CONSTANT_POOL (JPOOL_SIZE (jcf));
00271 #endif
00272 for (i = 1; i < (int) JPOOL_SIZE (jcf); i++)
00273 {
00274 int constant_kind;
00275
00276
00277
00278
00279
00280 JCF_FILL (jcf, 9);
00281 constant_kind = JCF_readu (jcf);
00282 jcf->cpool.tags[i] = constant_kind;
00283 switch (constant_kind)
00284 {
00285 case CONSTANT_String:
00286 case CONSTANT_Class:
00287 jcf->cpool.data[i] = JCF_readu2 (jcf);
00288 break;
00289 case CONSTANT_Fieldref:
00290 case CONSTANT_Methodref:
00291 case CONSTANT_InterfaceMethodref:
00292 case CONSTANT_NameAndType:
00293 jcf->cpool.data[i] = JCF_readu2 (jcf);
00294 jcf->cpool.data[i] |= JCF_readu2 (jcf) << 16;
00295 break;
00296 case CONSTANT_Integer:
00297 case CONSTANT_Float:
00298 jcf->cpool.data[i] = JCF_readu4 (jcf);
00299 break;
00300 case CONSTANT_Long:
00301 case CONSTANT_Double:
00302 jcf->cpool.data[i] = JCF_readu4 (jcf);
00303 i++;
00304 jcf->cpool.tags[i] = 0;
00305 jcf->cpool.data[i] = JCF_readu4 (jcf);
00306 break;
00307 case CONSTANT_Utf8:
00308 n = JCF_readu2 (jcf);
00309 JCF_FILL (jcf, n);
00310 #ifdef HANDLE_CONSTANT_Utf8
00311 HANDLE_CONSTANT_Utf8(jcf, i, n);
00312 #else
00313 jcf->cpool.data[i] = JCF_TELL(jcf) - 2;
00314 JCF_SKIP (jcf, n);
00315 #endif
00316 break;
00317 default:
00318 return i;
00319 }
00320 }
00321 return 0;
00322 }
00323
00324
00325
00326 static void
00327 DEFUN(jcf_parse_class, (jcf),
00328 JCF* jcf)
00329 {
00330 int i;
00331 uint16 interfaces_count;
00332 JCF_FILL (jcf, 8);
00333 jcf->access_flags = JCF_readu2 (jcf);
00334 jcf->this_class = JCF_readu2 (jcf);
00335 jcf->super_class = JCF_readu2 (jcf);
00336 interfaces_count = JCF_readu2 (jcf);
00337
00338 #ifdef HANDLE_CLASS_INFO
00339 HANDLE_CLASS_INFO(jcf->access_flags, jcf->this_class, jcf->super_class, interfaces_count);
00340 #endif
00341
00342 JCF_FILL (jcf, 2 * interfaces_count);
00343
00344
00345 for (i = 0; i < interfaces_count; i++)
00346 {
00347 uint16 index ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
00348 #ifdef HANDLE_CLASS_INTERFACE
00349 HANDLE_CLASS_INTERFACE (index);
00350 #endif
00351 }
00352 }
00353
00354
00355 static int
00356 DEFUN(jcf_parse_fields, (jcf),
00357 JCF* jcf)
00358 {
00359 int i, j;
00360 uint16 fields_count;
00361 JCF_FILL (jcf, 2);
00362 fields_count = JCF_readu2 (jcf);
00363
00364 #ifdef HANDLE_START_FIELDS
00365 HANDLE_START_FIELDS (fields_count);
00366 #endif
00367 for (i = 0; i < fields_count; i++)
00368 {
00369 uint16 access_flags = (JCF_FILL (jcf, 8), JCF_readu2 (jcf));
00370 uint16 name_index = JCF_readu2 (jcf);
00371 uint16 signature_index = JCF_readu2 (jcf);
00372 uint16 attribute_count = JCF_readu2 (jcf);
00373 #ifdef HANDLE_START_FIELD
00374 HANDLE_START_FIELD (access_flags, name_index, signature_index,
00375 attribute_count);
00376 #endif
00377 for (j = 0; j < attribute_count; j++)
00378 {
00379 int code = get_attribute (jcf);
00380 if (code != 0)
00381 return code;
00382 }
00383 #ifdef HANDLE_END_FIELD
00384 HANDLE_END_FIELD ();
00385 #endif
00386 }
00387 #ifdef HANDLE_END_FIELDS
00388 HANDLE_END_FIELDS ();
00389 #endif
00390 return 0;
00391 }
00392
00393
00394
00395 static int
00396 DEFUN(jcf_parse_one_method, (jcf),
00397 JCF* jcf)
00398 {
00399 int i;
00400 uint16 access_flags = (JCF_FILL (jcf, 8), JCF_readu2 (jcf));
00401 uint16 name_index = JCF_readu2 (jcf);
00402 uint16 signature_index = JCF_readu2 (jcf);
00403 uint16 attribute_count = JCF_readu2 (jcf);
00404 #ifdef HANDLE_METHOD
00405 HANDLE_METHOD(access_flags, name_index, signature_index, attribute_count);
00406 #endif
00407 for (i = 0; i < attribute_count; i++)
00408 {
00409 int code = get_attribute (jcf);
00410 if (code != 0)
00411 return code;
00412 }
00413 #ifdef HANDLE_END_METHOD
00414 HANDLE_END_METHOD ();
00415 #endif
00416 return 0;
00417 }
00418
00419 static int
00420 DEFUN(jcf_parse_methods, (jcf),
00421 JCF* jcf)
00422 {
00423 int i;
00424 uint16 methods_count;
00425 JCF_FILL (jcf, 2);
00426 methods_count = JCF_readu2 (jcf);
00427 #ifdef HANDLE_START_METHODS
00428 HANDLE_START_METHODS (methods_count);
00429 #endif
00430 for (i = 0; i < methods_count; i++)
00431 {
00432 int code = jcf_parse_one_method (jcf);
00433 if (code != 0)
00434 return code;
00435 }
00436 #ifdef HANDLE_END_METHODS
00437 HANDLE_END_METHODS ();
00438 #endif
00439 return 0;
00440 }
00441
00442
00443 static int
00444 DEFUN(jcf_parse_final_attributes, (jcf),
00445 JCF *jcf)
00446 {
00447 int i;
00448 uint16 attributes_count = (JCF_FILL (jcf, 2), JCF_readu2 (jcf));
00449 #ifdef START_FINAL_ATTRIBUTES
00450 START_FINAL_ATTRIBUTES (attributes_count)
00451 #endif
00452 for (i = 0; i < attributes_count; i++)
00453 {
00454 int code = get_attribute (jcf);
00455 if (code != 0)
00456 return code;
00457 }
00458 return 0;
00459 }
00460