1 /* Program to dump out a Java(TM) .class file.
2 Functionally similar to Sun's javap.
4 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5 2006 Free Software Foundation, Inc.
7 This file is part of GCC.
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 2, or (at your option)
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.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to
21 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA.
24 Java and all Java-based marks are trademarks or registered trademarks
25 of Sun Microsystems, Inc. in the United States and other countries.
26 The Free Software Foundation is independent of Sun Microsystems, Inc. */
28 /* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
31 jcf-dump is a program to print out the contents of class files.
32 Usage: jcf-dump [FLAGS] CLASS
34 + the name of a class in the CLASSPATH (e.g "java.lang.String"), or
35 + the name of a class *file* (e.g. "/home/me/work/package/Foo.class").
36 + The name of a .zip or .jar file (which prints all the classes in the
41 Dis-assemble each method.
45 Print nothing if there is no valid "main" method;
46 otherwise, print only the class name.
48 Print output in the style of Sun's javap program. VERY UNFINISHED.
54 #include "coretypes.h"
61 #include "java-tree.h"
70 /* Name of output file, if NULL if stdout. */
71 char *output_file = NULL;
75 int flag_disassemble_methods = 0;
76 int flag_print_class_info = 1;
77 int flag_print_constant_pool = 0;
78 int flag_print_fields = 1;
79 int flag_print_methods = 1;
80 int flag_print_attributes = 1;
82 /* When nonzero, warn when source file is newer than matching class
86 /* Print names of classes that have a "main" method. */
87 int flag_print_main = 0;
89 /* Index in constant pool of this class. */
90 int this_class_index = 0;
92 int class_access_flags = 0;
94 /* Print in format similar to javap. VERY INCOMPLETE. */
95 int flag_javap_compatible = 0;
97 static void print_access_flags (FILE *, uint16, char);
98 static void print_constant_terse (FILE*, JCF*, int, int);
99 static void print_constant_terse_with_index (FILE *, JCF *, int, int);
100 static void print_constant (FILE *, JCF *, int, int);
101 static void print_constant_ref (FILE *, JCF *, int);
102 static void disassemble_method (JCF*, const unsigned char *, int);
103 static void print_name (FILE*, JCF*, int);
104 static void print_signature (FILE*, JCF*, int, int);
105 static int utf8_equal_string (struct JCF*, int, const char *);
106 static void usage (void) ATTRIBUTE_NORETURN;
107 static void help (void) ATTRIBUTE_NORETURN;
108 static void version (void) ATTRIBUTE_NORETURN;
109 static void process_class (struct JCF *);
110 static void print_constant_pool (struct JCF *);
111 static void print_exception_table (struct JCF *, const unsigned char *entries,
113 static void indent (FILE *, int);
114 static void print_element_value (FILE *, JCF *, int);
115 static void print_annotation (FILE *, JCF *, int);
116 static void print_annotations (FILE *, JCF *, int);
117 static void print_parameter_annotations (FILE *, JCF *, int);
119 #define PRINT_SIGNATURE_RESULT_ONLY 1
120 #define PRINT_SIGNATURE_ARGS_ONLY 2
123 utf8_equal_string (JCF *jcf, int index, const char * value)
125 if (CPOOL_INDEX_IN_RANGE (&jcf->cpool, index)
126 && JPOOL_TAG (jcf, index) == CONSTANT_Utf8)
128 int len = strlen (value);
129 if (JPOOL_UTF_LENGTH (jcf, index) == len
130 && memcmp (JPOOL_UTF_DATA (jcf, index), value, len) == 0)
136 #define HANDLE_MAGIC(MAGIC, MINOR, MAJOR) \
137 this_class_index = 0; \
138 if (flag_print_class_info) \
140 "Magic number: 0x%0lx, minor_version: %ld, major_version: %ld.\n",\
141 (long) MAGIC, (long) MINOR, (long) MAJOR)
143 #define HANDLE_START_CONSTANT_POOL(COUNT) \
144 if (flag_print_constant_pool) \
145 fprintf (out, "\nConstant pool (count: %d):\n", COUNT)
147 #define HANDLE_SOURCEFILE(INDEX) \
148 { fprintf (out, "Attribute "); \
149 print_constant_terse (out, jcf, attribute_name, CONSTANT_Utf8); \
150 fprintf (out, ", length:%ld, #%d=", (long) attribute_length, INDEX); \
151 print_constant_terse (out, jcf, INDEX, CONSTANT_Utf8); fputc ('\n', out); }
153 #define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \
154 this_class_index = THIS; \
155 class_access_flags = ACCESS_FLAGS; \
156 if (flag_print_class_info) \
157 { fprintf (out, "\nAccess flags: 0x%x", ACCESS_FLAGS); \
158 print_access_flags (out, ACCESS_FLAGS, 'c'); \
160 fprintf (out, "This class: "); \
161 print_constant_terse_with_index (out, jcf, THIS, CONSTANT_Class); \
162 if (flag_print_constant_pool || SUPER != 0) \
163 fprintf (out, ", super: "); \
164 if (flag_print_constant_pool) \
166 fprintf (out, "%d", SUPER); \
171 print_constant_terse (out, jcf, SUPER, CONSTANT_Class); \
172 fprintf (out, "\nInterfaces (count: %d):\n", INTERFACES_COUNT); \
175 #define IGNORE_ATTRIBUTE(JCF, NAME, NAME_LENGTH) \
176 (flag_print_attributes <= 0)
178 #define HANDLE_CLASS_INTERFACE(INDEX) \
179 if (flag_print_class_info) \
180 { fprintf (out, "- Implements: "); \
181 print_constant_terse_with_index (out, jcf, INDEX, CONSTANT_Class); \
184 #define HANDLE_START_FIELDS(FIELDS_COUNT) \
185 if (flag_print_fields) \
186 fprintf (out, "\nFields (count: %d):\n", FIELDS_COUNT)
188 #define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
189 if (flag_print_fields) \
190 { fprintf (out, "Field name:"); \
191 print_constant_terse (out, jcf, NAME, CONSTANT_Utf8); \
192 print_access_flags (out, ACCESS_FLAGS, 'f'); \
193 fprintf (out, " Descriptor: "); \
194 if (flag_print_constant_pool) \
195 fprintf (out, "%d=", SIGNATURE); \
196 print_signature (out, jcf, SIGNATURE, 0); \
197 fputc ('\n', out); } \
199 flag_print_attributes--;
201 #define HANDLE_END_FIELD() \
202 if (! flag_print_fields) \
203 flag_print_attributes++;
205 #define HANDLE_START_METHODS(METHODS_COUNT) \
206 if (flag_print_methods) \
207 fprintf (out, "\nMethods (count: %d):\n", METHODS_COUNT); \
209 flag_print_attributes--;
212 #define HANDLE_END_METHODS() \
213 if (! flag_print_methods) \
214 flag_print_attributes++;
216 #define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
218 if (flag_print_methods) \
220 if (flag_javap_compatible) \
222 fprintf (out, " "); \
223 print_access_flags (out, ACCESS_FLAGS, 'm'); \
225 print_signature (out, jcf, SIGNATURE, PRINT_SIGNATURE_RESULT_ONLY); \
227 print_constant_terse (out, jcf, NAME, CONSTANT_Utf8); \
228 print_signature (out, jcf, SIGNATURE, PRINT_SIGNATURE_ARGS_ONLY); \
233 fprintf (out, "\nMethod name:"); \
234 print_constant_terse (out, jcf, NAME, CONSTANT_Utf8); \
235 print_access_flags (out, ACCESS_FLAGS, 'm'); \
236 fprintf (out, " Descriptor: "); \
237 if (flag_print_constant_pool) \
238 fprintf (out, "%d=", SIGNATURE); \
239 print_signature (out, jcf, SIGNATURE, 0); \
243 if (flag_print_main && ACCESS_FLAGS == (ACC_STATIC|ACC_PUBLIC) \
244 && utf8_equal_string (jcf, NAME, "main") \
245 && utf8_equal_string (jcf, SIGNATURE, "([Ljava/lang/String;)V") \
246 && this_class_index > 0 \
247 && (class_access_flags & ACC_PUBLIC)) \
249 print_constant_terse(out, jcf, this_class_index, CONSTANT_Class); \
254 #define COMMON_HANDLE_ATTRIBUTE(JCF, INDEX, LENGTH) \
255 ( fprintf (out, "Attribute "), \
256 print_constant_terse (out, jcf, INDEX, CONSTANT_Utf8), \
257 fprintf (out, ", length:%ld", (long) LENGTH) )
259 #define HANDLE_CONSTANTVALUE(VALUE_INDEX) \
260 ( COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length), \
261 fprintf (out, ", value: "), \
262 print_constant_ref (out, jcf, VALUE_INDEX), \
263 fprintf (out, "\n") )
265 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
266 { COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length); \
267 fprintf (out, ", max_stack:%ld, max_locals:%ld, code_length:%ld\n", \
268 (long) MAX_STACK, (long) MAX_LOCALS, (long) CODE_LENGTH); \
269 disassemble_method (jcf, jcf->read_ptr, CODE_LENGTH); }
271 #define HANDLE_EXCEPTION_TABLE(ENTRIES, COUNT) \
272 print_exception_table (jcf, ENTRIES, COUNT)
274 #define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
275 { int n = (COUNT); int i; \
276 COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length); \
277 fprintf (out, ", count: %d\n", n); \
278 for (i = 0; i < n; i++) {\
279 int ex_index = JCF_readu2 (jcf); \
280 fprintf (out, "%3d: ", i); \
281 print_constant_ref (out, jcf, ex_index); \
282 fputc ('\n', out); } }
284 #define HANDLE_LOCALVARIABLETABLE_ATTRIBUTE(COUNT) \
285 { int n = (COUNT); int i; \
286 COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length); \
287 fprintf (out, ", count: %d\n", n); \
288 for (i = 0; i < n; i++) {\
289 int start_pc = JCF_readu2 (jcf); \
290 int length = JCF_readu2 (jcf); \
291 int name_index = JCF_readu2 (jcf); \
292 int signature_index = JCF_readu2 (jcf); \
293 int slot = JCF_readu2 (jcf); \
294 fprintf (out, " slot#%d: name: ", slot); \
295 if (flag_print_constant_pool) \
296 fprintf (out, "%d=", name_index); \
297 print_name (out, jcf, name_index); \
298 fprintf (out, ", type: "); \
299 if (flag_print_constant_pool) \
300 fprintf (out, "%d=", signature_index); \
301 print_signature (out, jcf, signature_index, 0); \
302 fprintf (out, " (pc: %d length: %d)\n", start_pc, length); }}
304 #define HANDLE_LOCALVARIABLETYPETABLE_ATTRIBUTE(COUNT) \
305 { int n = (COUNT); int i; \
306 COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length); \
307 fprintf (out, ", count: %d\n", n); \
308 for (i = 0; i < n; i++) { \
309 int start_pc = JCF_readu2 (jcf); \
310 int length = JCF_readu2 (jcf); \
311 int name_index = JCF_readu2 (jcf); \
312 int signature_index = JCF_readu2 (jcf); \
313 int slot = JCF_readu2 (jcf); \
314 fprintf (out, " slot#%d: name: ", slot); \
315 if (flag_print_constant_pool) \
316 fprintf (out, "%d=", name_index); \
317 print_name (out, jcf, name_index); \
318 fprintf (out, ", type: "); \
319 if (flag_print_constant_pool) \
320 fprintf (out, "%d=", signature_index); \
321 print_signature (out, jcf, signature_index, 0); \
322 fprintf (out, " (pc: %d length: %d)\n", start_pc, length); }}
324 #define HANDLE_LINENUMBERTABLE_ATTRIBUTE(COUNT) \
325 { int n = (COUNT); int i; \
326 COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
327 fprintf (out, ", count: %d\n", n); \
328 if (flag_disassemble_methods) \
329 for (i = 0; i < n; i++) {\
330 int start_pc = JCF_readu2 (jcf); \
331 int line_number = JCF_readu2 (jcf); \
332 fprintf (out, " line: %d at pc: %d\n", line_number, start_pc); }\
334 JCF_SKIP (jcf, 4 * n); }
336 #define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
338 COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
341 uint16 inner_class_info_index = JCF_readu2 (jcf); \
342 uint16 outer_class_info_index = JCF_readu2 (jcf); \
343 uint16 inner_name_index = JCF_readu2 (jcf); \
344 uint16 inner_class_access_flags = JCF_readu2 (jcf); \
346 if (flag_print_class_info) \
348 fprintf (out, "\n inner: "); \
349 if (inner_class_info_index == 0) \
350 fprintf (out, " (no inner info index)"); \
352 print_constant_terse_with_index (out, jcf, \
353 inner_class_info_index, \
355 if (inner_name_index == 0) \
356 fprintf (out, " (anonymous)"); \
357 else if (verbose || flag_print_constant_pool) \
359 fprintf (out, " ("); \
360 print_constant_terse_with_index (out, jcf, inner_name_index, \
364 fprintf (out, ", access flags: 0x%x", inner_class_access_flags); \
365 print_access_flags (out, inner_class_access_flags, 'c'); \
366 fprintf (out, ", outer class: "); \
367 if (outer_class_info_index == 0) \
368 fprintf (out, "(not a member)"); \
370 print_constant_terse_with_index (out, jcf, \
371 outer_class_info_index, \
375 if (flag_print_class_info) \
379 #define HANDLE_SOURCEDEBUGEXTENSION_ATTRIBUTE(LENGTH) \
380 { int i, n = (LENGTH), c = 0; \
381 COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
383 for (i = 0; i < n; i++) { c = JCF_readu(jcf); fputc(c, out); } \
384 if (c != '\r' && c != '\n') fputc('\n', out); }
386 #define HANDLE_ENCLOSINGMETHOD_ATTRIBUTE() \
387 { uint16 class_index, method_index; \
388 COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
389 class_index = JCF_readu2 (jcf); \
390 method_index = JCF_readu2 (jcf); \
391 fprintf (out, "\n Class: "); \
392 print_constant_terse_with_index (out, jcf, class_index, CONSTANT_Class); \
393 fprintf (out, "\n Method: "); \
394 print_constant_terse_with_index (out, jcf, method_index, \
395 CONSTANT_NameAndType); \
399 #define HANDLE_SIGNATURE_ATTRIBUTE() \
402 COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
403 signature = JCF_readu2 (jcf); \
404 fprintf (out, "\n Value: "); \
405 print_constant_terse_with_index (out, jcf, signature, CONSTANT_Utf8); \
409 #define HANDLE_RUNTIMEVISIBLEANNOTATIONS_ATTRIBUTE() \
411 COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
412 print_annotations (out, jcf, 1); \
415 #define HANDLE_RUNTIMEINVISIBLEANNOTATIONS_ATTRIBUTE() \
417 COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
418 print_annotations (out, jcf, 1); \
421 #define HANDLE_RUNTIMEVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE() \
423 COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
424 print_parameter_annotations (out, jcf, 1); \
427 #define HANDLE_RUNTIMEINVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE() \
429 COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
430 print_parameter_annotations (out, jcf, 1); \
433 #define HANDLE_ANNOTATIONDEFAULT_ATTRIBUTE() \
435 COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
436 print_element_value (out, jcf, 1); \
440 #define PROCESS_OTHER_ATTRIBUTE(JCF, INDEX, LENGTH) \
441 { COMMON_HANDLE_ATTRIBUTE(JCF, INDEX, LENGTH); \
442 fputc ('\n', out); JCF_SKIP (JCF, LENGTH); }
444 #define START_FINAL_ATTRIBUTES(ATTRIBUTES_COUNT) \
445 if (flag_print_attributes > 0) \
446 fprintf (out, "\nAttributes (count: %d):\n", attributes_count);
453 indent (FILE *stream, int level)
456 for (i = 0; i < level; ++i)
457 fprintf (stream, " ");
461 print_element_value (FILE *stream, JCF *jcf, int level)
463 uint8 tag = JCF_readu (jcf);
464 indent (stream, level);
473 uint16 cindex = JCF_readu2 (jcf);
474 print_constant_terse_with_index (stream, jcf, cindex,
480 uint16 cindex = JCF_readu2 (jcf);
481 print_constant_terse_with_index (stream, jcf, cindex,
487 uint16 cindex = JCF_readu2 (jcf);
488 print_constant_terse_with_index (stream, jcf, cindex,
494 uint16 cindex = JCF_readu2 (jcf);
495 print_constant_terse_with_index (stream, jcf, cindex,
501 uint16 cindex = JCF_readu2 (jcf);
502 /* Despite what the JVM spec says, compilers generate a Utf8
503 constant here, not a String. */
504 print_constant_terse_with_index (stream, jcf, cindex,
511 uint16 type_name_index = JCF_readu2 (jcf);
512 uint16 const_name_index = JCF_readu2 (jcf);
513 fprintf (stream, "enum class: ");
514 print_constant_terse_with_index (stream, jcf, type_name_index,
516 fprintf (stream, "\n");
517 indent (stream, level);
518 fprintf (stream, "Field: ");
519 print_constant_terse_with_index (stream, jcf, const_name_index,
525 uint16 class_info_index = JCF_readu2 (jcf);
526 print_constant_terse_with_index (stream, jcf, class_info_index,
532 fprintf (stream, "Annotation:\n");
533 print_annotation (stream, jcf, level + 1);
538 uint16 n_array_elts = JCF_readu2 (jcf);
539 fprintf (stream, "array[%d]: [\n", (int) n_array_elts);
540 while (n_array_elts--)
541 print_element_value (stream, jcf, level + 1);
542 indent (stream, level);
543 fprintf (stream, "]");
547 fprintf (stream, "Unexpected tag value: %d", (int) tag);
550 fputc ('\n', stream);
554 print_annotation (FILE *stream, JCF *jcf, int level)
556 uint16 type_index = JCF_readu2 (jcf);
557 uint16 npairs = JCF_readu2 (jcf);
558 fprintf (stream, "\n");
559 indent (stream, level);
560 fprintf (stream, "Annotation name: ");
561 print_constant_terse_with_index (stream, jcf, type_index,
565 fprintf (stream, "\n");
568 uint16 name_index = JCF_readu2 (jcf);
569 indent (stream, level + 1);
570 fprintf (stream, "Name: ");
571 print_constant_terse_with_index (stream, jcf, name_index,
573 fprintf (stream, "\n");
574 print_element_value (stream, jcf, level + 2);
580 print_annotations (FILE *stream, JCF *jcf, int level)
582 uint16 num = JCF_readu2 (jcf);
584 print_annotation (stream, jcf, level);
588 print_parameter_annotations (FILE *stream, JCF *jcf, int level)
590 uint8 nparams = JCF_readu (jcf);
592 for (i = 0; i < nparams; ++i)
594 indent (stream, level);
595 fprintf (stream, "Parameter annotations (%d):\n", (int) i);
596 print_annotations (stream, jcf, level + 1);
603 print_constant_ref (FILE *stream, JCF *jcf, int index)
605 if (index <= 0 || index >= JPOOL_SIZE(jcf))
606 fprintf (stream, "<out of range>");
609 if (flag_print_constant_pool)
610 fprintf (stream, "#%d=", index);
612 print_constant (stream, jcf, index, 1);
617 /* Print the access flags given by FLAGS.
618 The CONTEXT is one of 'c' (class flags), 'f' (field flags),
619 or 'm' (method flags). */
622 print_access_flags (FILE *stream, uint16 flags, char context)
624 if (flags & ACC_PUBLIC) fprintf (stream, " public");
625 if (flags & ACC_PRIVATE) fprintf (stream, " private");
626 if (flags & ACC_PROTECTED) fprintf (stream, " protected");
627 if (flags & ACC_ABSTRACT) fprintf (stream, " abstract");
628 if (flags & ACC_STATIC) fprintf (stream, " static");
629 if (flags & ACC_FINAL) fprintf (stream, " final");
630 if (flags & ACC_TRANSIENT)
631 fprintf (stream, context == 'm' ? " varargs" : " transient");
632 if (flags & ACC_VOLATILE)
633 fprintf (stream, context == 'm' ? " bridge" : " volatile");
634 if (flags & ACC_NATIVE) fprintf (stream, " native");
635 if (flags & ACC_SYNCHRONIZED)
638 fprintf (stream, " super");
640 fprintf (stream, " synchronized");
642 if (flags & ACC_INTERFACE)
643 fprintf (stream, (flags & ACC_ANNOTATION) ? " @interface" : " interface");
644 if (flags & ACC_ENUM) fprintf (stream, " enum");
645 if (flags & ACC_STRICT) fprintf (stream, " strictfp");
646 if (flags & ACC_SYNTHETIC) fprintf (stream, " synthetic");
651 print_name (FILE* stream, JCF* jcf, int name_index)
653 if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
654 fprintf (stream, "<not a UTF8 constant>");
656 jcf_print_utf8 (stream, JPOOL_UTF_DATA (jcf,name_index),
657 JPOOL_UTF_LENGTH (jcf, name_index));
660 /* If the type of the constant at INDEX matches EXPECTED,
661 print it tersely, otherwise more verbosely. */
664 print_constant_terse (FILE *out, JCF *jcf, int index, int expected)
666 if (! CPOOL_INDEX_IN_RANGE (&jcf->cpool, index))
667 fprintf (out, "<constant pool index %d not in range>", index);
668 else if (JPOOL_TAG (jcf, index) != expected)
670 fprintf (out, "<Unexpected constant type ");
671 print_constant (out, jcf, index, 1);
675 print_constant (out, jcf, index, 0);
679 print_constant_terse_with_index (FILE *out, JCF *jcf, int index, int expected)
681 if (flag_print_constant_pool)
682 fprintf (out, "%d=", index);
683 print_constant_terse (out, jcf, index, expected);
686 /* Print the constant at INDEX in JCF's constant pool.
687 If verbosity==0, print very tersely (no extraneous text).
688 If verbosity==1, prefix the type of the constant.
689 If verbosity==2, add more descriptive text. */
692 print_constant (FILE *out, JCF *jcf, int index, int verbosity)
697 int kind = JPOOL_TAG (jcf, index);
701 n = JPOOL_USHORT1 (jcf, index);
705 fprintf (out, "Class name: %d=", n);
707 fprintf (out, "Class ");
709 if (! CPOOL_INDEX_IN_RANGE (&jcf->cpool, n))
710 fprintf (out, "<out of range>");
711 else if (verbosity < 2 && JPOOL_TAG (jcf, n) == CONSTANT_Utf8)
713 int len = JPOOL_UTF_LENGTH (jcf, n);
714 jcf_print_utf8_replace (out, JPOOL_UTF_DATA(jcf,n), len, '/', '.');
717 print_constant_terse (out, jcf, n, CONSTANT_Utf8);
719 case CONSTANT_Fieldref:
720 str = "Field"; goto field_or_method;
721 case CONSTANT_Methodref:
722 str = "Method"; goto field_or_method;
723 case CONSTANT_InterfaceMethodref:
724 str = "InterfaceMethod"; goto field_or_method;
727 uint16 tclass = JPOOL_USHORT1 (jcf, index);
728 uint16 name_and_type = JPOOL_USHORT2 (jcf, index);
730 fprintf (out, "%sref class: %d=", str, tclass);
731 else if (verbosity > 0)
732 fprintf (out, "%s ", str);
733 print_constant_terse (out, jcf, tclass, CONSTANT_Class);
737 fprintf (out, " name_and_type: %d=<", name_and_type);
738 print_constant_terse (out, jcf, name_and_type, CONSTANT_NameAndType);
743 case CONSTANT_String:
744 j = JPOOL_USHORT1 (jcf, index);
748 fprintf (out, "String %d=", j);
750 fprintf (out, "String ");
752 print_constant_terse (out, jcf, j, CONSTANT_Utf8);
754 case CONSTANT_Integer:
756 fprintf (out, "Integer ");
757 num = JPOOL_INT (jcf, index);
761 fprintf (out, "Long ");
762 num = JPOOL_LONG (jcf, index);
767 format_int (buffer, num, 10);
768 fprintf (out, "%s", buffer);
771 format_uint (buffer, (uint64)num, 16);
772 fprintf (out, "=0x%s", buffer);
778 jfloat fnum = JPOOL_FLOAT (jcf, index);
781 fputs ("Float ", out);
786 if (JFLOAT_FINITE (fnum))
789 int exponent = fnum.exponent - JFLOAT_EXP_BIAS;
791 uint32 mantissa = fnum.mantissa;
792 if (fnum.exponent == 0)
796 /* Normal; add the implicit bit. */
797 mantissa |= ((uint32)1 << 23);
799 f = frexp (mantissa, &dummy);
800 f = ldexp (f, exponent + 1);
801 fprintf (out, "%.10g", f);
805 if (fnum.mantissa == 0)
807 else if (fnum.mantissa & JFLOAT_QNAN_MASK)
808 fprintf (out, "QNaN(%u)", (fnum.mantissa & ~JFLOAT_QNAN_MASK));
810 fprintf (out, "SNaN(%u)", (fnum.mantissa & ~JFLOAT_QNAN_MASK));
814 fprintf (out, ", bits = 0x%08lx", (long) JPOOL_UINT (jcf, index));
818 case CONSTANT_Double:
820 jdouble dnum = JPOOL_DOUBLE (jcf, index);
823 fputs ("Double ", out);
828 if (JDOUBLE_FINITE (dnum))
831 int exponent = dnum.exponent - JDOUBLE_EXP_BIAS;
833 uint64 mantissa = ((((uint64) dnum.mantissa0) << 32)
835 if (dnum.exponent == 0)
839 /* Normal; add the implicit bit. */
840 mantissa |= ((uint64)1 << 52);
842 d = frexp (mantissa, &dummy);
843 d = ldexp (d, exponent + 1);
844 fprintf (out, "%.20g", d);
848 uint64 mantissa = dnum.mantissa0 & ~JDOUBLE_QNAN_MASK;
849 mantissa = (mantissa << 32) + dnum.mantissa1;
851 if (dnum.mantissa0 == 0 && dnum.mantissa1 == 0)
853 else if (dnum.mantissa0 & JDOUBLE_QNAN_MASK)
854 fprintf (out, "QNaN(%llu)", (unsigned long long)mantissa);
856 fprintf (out, "SNaN(%llu)", (unsigned long long)mantissa);
861 hi = JPOOL_UINT (jcf, index);
862 lo = JPOOL_UINT (jcf, index + 1);
863 fprintf (out, ", bits = 0x%08lx%08lx", (long) hi, (long) lo);
867 case CONSTANT_NameAndType:
869 uint16 name = JPOOL_USHORT1 (jcf, index);
870 uint16 sig = JPOOL_USHORT2 (jcf, index);
874 fprintf (out, "NameAndType name: %d=", name);
876 fprintf (out, "NameAndType ");
878 print_name (out, jcf, name);
882 fprintf (out, ", signature: %d=", sig);
883 print_signature (out, jcf, sig, 0);
888 const unsigned char *str = JPOOL_UTF_DATA (jcf, index);
889 int length = JPOOL_UTF_LENGTH (jcf, index);
891 { /* Print as 8-bit bytes. */
892 fputs ("Utf8: \"", out);
893 while (--length >= 0)
894 jcf_print_char (out, *str++);
897 { /* Print as Unicode. */
899 jcf_print_utf8 (out, str, length);
905 fprintf (out, "(Unknown constant type %d)", kind);
910 print_constant_pool (JCF *jcf)
913 for (i = 1; i < JPOOL_SIZE(jcf); i++)
915 int kind = JPOOL_TAG (jcf, i);
916 fprintf (out, "#%d: ", i);
917 print_constant (out, jcf, i, 2);
919 if (kind == CONSTANT_Double || kind == CONSTANT_Long)
920 i++; /* These take up two slots in the constant table */
925 print_signature_type (FILE* stream, const unsigned char **ptr,
926 const unsigned char *limit)
935 for ((*ptr)++; (*ptr) < limit && ISDIGIT (**ptr); (*ptr)++)
937 array_size = (array_size < 0 ? 0 : 10 * array_size) + *(*ptr) - '0';
939 print_signature_type (stream, ptr, limit);
940 if (array_size == -1)
941 fprintf (stream, "[]");
943 fprintf (stream, "[%d]", array_size);
948 fputc (*(*ptr)++, stream);
949 for (; **ptr != ')' && *ptr < limit; nargs++)
953 print_signature_type (stream, ptr, limit);
957 fputc (*(*ptr)++, stream);
958 print_signature_type (stream, ptr, limit);
961 fprintf (stream, "???");
965 case 'B': fprintf (stream, "byte"); (*ptr)++; break;
966 case 'C': fprintf (stream, "char"); (*ptr)++; break;
967 case 'D': fprintf (stream, "double"); (*ptr)++; break;
968 case 'F': fprintf (stream, "float"); (*ptr)++; break;
969 case 'S': fprintf (stream, "short"); (*ptr)++; break;
970 case 'I': fprintf (stream, "int"); (*ptr)++; break;
971 case 'J': fprintf (stream, "long"); (*ptr)++; break;
972 case 'Z': fprintf (stream, "boolean"); (*ptr)++; break;
973 case 'V': fprintf (stream, "void"); (*ptr)++; break;
976 for ((*ptr)++; (*ptr)<limit && *(*ptr) != ';'; (*ptr)++)
977 jcf_print_char (stream, *(*ptr) == '/' ? '.' : *(*ptr));
982 jcf_print_char (stream, *(*ptr)++);
987 print_signature (FILE* stream, JCF *jcf, int signature_index, int options)
989 if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
990 print_constant_terse (out, jcf, signature_index, CONSTANT_Utf8);
993 const unsigned char *str = JPOOL_UTF_DATA (jcf, signature_index);
994 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
995 const unsigned char *limit;
996 limit = str + length;
998 fprintf (stream, "<empty signature string>");
1001 if (options & PRINT_SIGNATURE_RESULT_ONLY)
1003 while (str < limit && *str++ != ')') ;
1005 if (options & PRINT_SIGNATURE_ARGS_ONLY)
1008 fputc ('(', stream);
1009 while (str < limit && *str != ')')
1011 print_signature_type (stream, &str, limit);
1013 fputs (", ", stream);
1015 fputc (')', stream);
1019 print_signature_type (stream, &str, limit);
1022 fprintf (stream, "<junk:");
1023 jcf_print_utf8 (stream, str, limit - str);
1024 fputc ('>', stream);
1033 print_exception_table (JCF *jcf, const unsigned char *entries, int count)
1035 /* Print exception table. */
1039 const unsigned char *ptr = entries;
1040 fprintf (out, "Exceptions (count: %d):\n", i);
1041 for (; --i >= 0; ptr+= 8)
1043 int start_pc = GET_u2 (ptr);
1044 int end_pc = GET_u2 (ptr+2);
1045 int handler_pc = GET_u2 (ptr+4);
1046 int catch_type = GET_u2 (ptr+6);
1047 fprintf (out, " start: %d, end: %d, handler: %d, type: ",
1048 start_pc, end_pc, handler_pc);
1049 if (catch_type == 0)
1050 fputs ("0 /* finally */", out);
1052 print_constant_terse_with_index (out, jcf,
1053 catch_type, CONSTANT_Class);
1059 #include "jcf-reader.c"
1062 process_class (JCF *jcf)
1065 if (jcf_parse_preamble (jcf) != 0)
1066 fprintf (stderr, _("Not a valid Java .class file.\n"));
1068 /* Parse and possibly print constant pool */
1069 code = jcf_parse_constant_pool (jcf);
1072 fprintf (stderr, _("error while parsing constant pool\n"));
1073 exit (FATAL_EXIT_CODE);
1075 code = verify_constant_pool (jcf);
1078 fprintf (stderr, _("error in constant pool entry #%d\n"), code);
1079 exit (FATAL_EXIT_CODE);
1081 if (flag_print_constant_pool)
1082 print_constant_pool (jcf);
1084 jcf_parse_class (jcf);
1085 code = jcf_parse_fields (jcf);
1088 fprintf (stderr, _("error while parsing fields\n"));
1089 exit (FATAL_EXIT_CODE);
1091 code = jcf_parse_methods (jcf);
1094 fprintf (stderr, _("error while parsing methods\n"));
1095 exit (FATAL_EXIT_CODE);
1097 code = jcf_parse_final_attributes (jcf);
1100 fprintf (stderr, _("error while parsing final attributes\n"));
1101 exit (FATAL_EXIT_CODE);
1103 jcf->filename = NULL;
1108 /* This is used to mark options with no short value. */
1109 #define LONG_OPT(Num) ((Num) + 128)
1111 #define OPT_classpath LONG_OPT (0)
1112 #define OPT_CLASSPATH OPT_classpath
1113 #define OPT_bootclasspath LONG_OPT (1)
1114 #define OPT_extdirs LONG_OPT (2)
1115 #define OPT_HELP LONG_OPT (3)
1116 #define OPT_VERSION LONG_OPT (4)
1117 #define OPT_JAVAP LONG_OPT (5)
1119 static const struct option options[] =
1121 { "classpath", required_argument, NULL, OPT_classpath },
1122 { "bootclasspath", required_argument, NULL, OPT_bootclasspath },
1123 { "extdirs", required_argument, NULL, OPT_extdirs },
1124 { "CLASSPATH", required_argument, NULL, OPT_CLASSPATH },
1125 { "help", no_argument, NULL, OPT_HELP },
1126 { "verbose", no_argument, NULL, 'v' },
1127 { "version", no_argument, NULL, OPT_VERSION },
1128 { "javap", no_argument, NULL, OPT_JAVAP },
1129 { "print-main", no_argument, &flag_print_main, 1 },
1130 { "print-constants", no_argument, &flag_print_constant_pool, 1 },
1131 { NULL, no_argument, NULL, 0 }
1137 fprintf (stderr, _("Try 'jcf-dump --help' for more information.\n"));
1144 printf (_("Usage: jcf-dump [OPTION]... CLASS...\n\n"));
1145 printf (_("Display contents of a class file in readable form.\n\n"));
1146 printf (_(" -c Disassemble method bodies\n"));
1147 printf (_(" --javap Generate output in 'javap' format\n"));
1149 printf (_(" --classpath PATH Set path to find .class files\n"));
1150 printf (_(" -IDIR Append directory to class path\n"));
1151 printf (_(" --bootclasspath PATH Override built-in class path\n"));
1152 printf (_(" --extdirs PATH Set extensions directory path\n"));
1153 printf (_(" -o FILE Set output file name\n"));
1155 printf (_(" --help Print this help, then exit\n"));
1156 printf (_(" --version Print version number, then exit\n"));
1157 printf (_(" -v, --verbose Print extra information while running\n"));
1159 printf (_("For bug reporting instructions, please see:\n"
1160 "%s.\n"), bug_report_url);
1167 printf ("jcf-dump (GCC) %s\n\n", version_string);
1168 printf ("Copyright %s 2006 Free Software Foundation, Inc.\n", _("(C)"));
1169 printf (_("This is free software; see the source for copying conditions. There is NO\n"
1170 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
1175 main (int argc, char** argv)
1180 /* Unlock the stdio streams. */
1181 unlock_std_streams ();
1183 gcc_init_libintl ();
1187 fprintf (stderr, _("jcf-dump: no classes specified\n"));
1193 /* We use getopt_long_only to allow single `-' long options. For
1194 some of our options this is more natural. */
1195 while ((opt = getopt_long_only (argc, argv, "o:I:vc", options, NULL)) != -1)
1200 /* Already handled. */
1204 output_file = optarg;
1208 jcf_path_include_arg (optarg);
1216 flag_disassemble_methods = 1;
1220 jcf_path_classpath_arg (optarg);
1223 case OPT_bootclasspath:
1224 jcf_path_bootclasspath_arg (optarg);
1228 jcf_path_extdirs_arg (optarg);
1240 flag_javap_compatible++;
1241 flag_print_constant_pool = 0;
1242 flag_print_attributes = 0;
1250 if (verbose && ! flag_javap_compatible)
1251 flag_print_constant_pool = 1;
1255 fprintf (stderr, _("jcf-dump: no classes specified\n"));
1259 jcf_path_seal (verbose);
1261 if (flag_print_main)
1263 flag_print_fields = 0;
1264 flag_print_methods = 0;
1265 flag_print_constant_pool = 0;
1266 flag_print_attributes = 0;
1267 flag_print_class_info = 0;
1272 out = fopen (output_file, "w");
1275 fprintf (stderr, _("Cannot open '%s' for output.\n"), output_file);
1276 return FATAL_EXIT_CODE;
1284 fprintf (out, "Reading .class from <standard input>.\n");
1285 open_class ("<stdio>", jcf, 0, NULL);
1286 process_class (jcf);
1290 for (argi = optind; argi < argc; argi++)
1292 char *arg = argv[argi];
1293 const char *class_filename = find_class (arg, strlen (arg), jcf, 0);
1294 if (class_filename == NULL)
1295 class_filename = find_classfile (arg, jcf, NULL);
1296 if (class_filename == NULL)
1298 perror ("Could not find class");
1299 return FATAL_EXIT_CODE;
1302 if (GET_u4 (jcf->read_ptr) == ZIPMAGIC)
1304 long compressed_size, member_size;
1305 int compression_method, filename_length, extra_length;
1306 int general_purpose_bits;
1307 const char *filename;
1309 if (flag_print_class_info)
1310 fprintf (out, "Reading classes from archive %s.\n",
1315 jcf_filbuf_t save_filbuf = jcf->filbuf;
1316 long magic = JCF_readu4_le (jcf);
1317 if (magic == 0x02014b50 || magic == 0x06054b50)
1318 break; /* got to central directory */
1319 if (magic != 0x04034b50) /* ZIPMAGIC (little-endian) */
1321 fprintf (stderr, _("bad format of .zip/.jar archive\n"));
1322 return FATAL_EXIT_CODE;
1326 general_purpose_bits = JCF_readu2_le (jcf);
1327 compression_method = JCF_readu2_le (jcf);
1329 compressed_size = JCF_readu4_le (jcf);
1330 member_size = JCF_readu4_le (jcf);
1331 filename_length = JCF_readu2_le (jcf);
1332 extra_length = JCF_readu2_le (jcf);
1333 total_length = filename_length + extra_length
1335 if (jcf->read_end - jcf->read_ptr < total_length)
1336 jcf_trim_old_input (jcf);
1337 JCF_FILL (jcf, total_length);
1338 filename = (const char *) jcf->read_ptr;
1339 JCF_SKIP (jcf, filename_length);
1340 JCF_SKIP (jcf, extra_length);
1341 if (filename_length > 0
1342 && filename[filename_length-1] == '/')
1344 if (flag_print_class_info)
1345 fprintf (out, "[Skipping directory %.*s]\n",
1346 filename_length, filename);
1349 else if (compression_method != 0)
1351 if (flag_print_class_info)
1352 fprintf (out, "[Skipping compressed file %.*s]\n",
1353 filename_length, filename);
1356 else if (member_size < 4
1357 || GET_u4 (jcf->read_ptr) != 0xcafebabe)
1359 if (flag_print_class_info)
1360 fprintf (out, "[Skipping non-.class member %.*s]\n",
1361 filename_length, filename);
1366 if (flag_print_class_info)
1367 fprintf (out, "Reading class member: %.*s.\n",
1368 filename_length, filename);
1372 JCF_SKIP (jcf, compressed_size);
1376 unsigned char *save_end;
1377 jcf->filbuf = jcf_unexpected_eof;
1378 save_end = jcf->read_end;
1379 jcf->read_end = jcf->read_ptr + compressed_size;
1380 process_class (jcf);
1381 jcf->filbuf = save_filbuf;
1382 jcf->read_end = save_end;
1388 if (flag_print_class_info)
1389 fprintf (out, "Reading .class from %s.\n", class_filename);
1390 process_class (jcf);
1396 return SUCCESS_EXIT_CODE;
1402 disassemble_method (JCF* jcf, const unsigned char *byte_ops, int len)
1408 if (flag_disassemble_methods == 0)
1410 #define BCODE byte_ops
1411 for (PC = 0; PC < len;)
1416 switch (byte_ops[PC++])
1419 /* This is the actual code emitted for each of opcodes in javaops.def.
1420 The actual opcode-specific stuff is handled by the OPKIND macro.
1421 I.e. for an opcode whose OPKIND is BINOP, the BINOP will be called.
1422 Those macros are defined below. The OPKINDs that do not have any
1423 inline parameters (such as BINOP) and therefore do mot need anything
1424 else to me printed out just use an empty body. */
1426 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
1428 fprintf (out, "%3d: %s", oldpc, #OPNAME); \
1429 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
1430 fputc ('\n', out); \
1433 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
1434 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
1435 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
1436 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
1438 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > len ? \
1439 (fprintf(stderr, _("Bad byte codes.\n")), exit(-1), 0) : 1)
1441 /* Print out operand (if not implied by the opcode) for PUSCH opcodes.
1442 These all push a constant onto the opcode stack. */
1443 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
1444 saw_index = 0, i = (OPERAND_VALUE); \
1445 if (oldpc+1 == PC) /* nothing */; \
1446 else if (saw_index) fprintf (out, " "), print_constant_ref (out, jcf, i); \
1447 else fprintf (out, " %d", i);
1449 /* Print out operand (a local variable index) for LOAD opcodes.
1450 These all push local variable onto the opcode stack. */
1451 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
1452 INT_temp = saw_wide ? IMMEDIATE_u2 : (OPERAND_VALUE); goto load_store;
1454 /* Handle STORE opcodes same as LOAD opcodes.
1455 These all store a value from the opcode stack in a local variable. */
1458 /* Handle more kind of opcodes. */
1459 #define STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1460 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1461 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1462 #define CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1463 #define CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1464 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1465 #define UNKNOWN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1467 /* Handle putfield and getfield opcodes, with static versions. */
1468 #define FIELD(MAYBE_STATIC, PUT_OR_GET) \
1469 fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2)
1471 /* Print operand for invoke opcodes. */
1472 #define INVOKE(OPERAND_TYPE, OPERAND_VALUE) \
1473 fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2);\
1474 if (OPERAND_VALUE) /* for invokeinterface */ \
1475 { int nargs = IMMEDIATE_u1; PC++; \
1476 fprintf (out, " nargs:%d", nargs); }
1478 #define OBJECT(OPERAND_TYPE, OPERAND_VALUE) \
1479 fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2);
1481 #define ARRAY(OPERAND_TYPE, SUBOP) \
1482 ARRAY_##SUBOP(OPERAND_TYPE)
1483 /* Handle sub-categories of ARRAY opcodes. */
1484 #define ARRAY_LOAD(TYPE) /* nothing */
1485 #define ARRAY_STORE(TYPE) /* nothing */
1486 #define ARRAY_LENGTH(TYPE) /* nothing */
1487 #define ARRAY_NEW(TYPE) ARRAY_NEW_##TYPE
1488 #define ARRAY_NEW_NUM \
1489 INT_temp = IMMEDIATE_u1; \
1490 { switch ((int) INT_temp) { \
1491 case 4: fputs (" boolean", out); break; \
1492 case 5: fputs (" char", out); break; \
1493 case 6: fputs (" float", out); break; \
1494 case 7: fputs (" double", out); break; \
1495 case 8: fputs (" byte", out); break; \
1496 case 9: fputs (" short", out); break; \
1497 case 10: fputs (" int", out); break; \
1498 case 11: fputs (" long", out); break; \
1499 default: fprintf (out, " <unknown type code %ld>", (long)INT_temp); break;\
1502 #define ARRAY_NEW_PTR \
1503 fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2);
1505 #define ARRAY_NEW_MULTI \
1506 fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2); \
1507 fprintf (out, " %d", IMMEDIATE_u1); /* number of dimensions */
1509 #define TEST(OPERAND_TYPE, OPERAND_VALUE) \
1510 fprintf (out, " %d", oldpc + IMMEDIATE_s2)
1512 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
1513 saw_index = 0, INT_temp = (OPERAND_VALUE); \
1514 fprintf (out, " %ld", (long) (saw_index ? INT_temp : oldpc + INT_temp))
1516 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
1517 saw_index = 0, INT_temp = (OPERAND_VALUE); \
1518 fprintf (out, " %ld", (long) (saw_index ? INT_temp : oldpc + INT_temp))
1520 #undef RET /* Defined by config/i386/i386.h */
1521 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
1522 INT_temp = saw_wide ? IMMEDIATE_u2 : (OPERAND_VALUE); \
1524 fprintf (out, " %ld", (long) INT_temp);
1526 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
1527 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
1529 #define LOOKUP_SWITCH \
1530 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
1531 fprintf (out, " npairs=%ld, default=%ld", (long) npairs, (long) default_offset+oldpc); \
1532 while (--npairs >= 0) { \
1533 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
1534 fprintf (out, "\n%10ld: %ld", (long)match, (long)(offset+oldpc)); } \
1537 #define TABLE_SWITCH \
1538 { jint default_offset = IMMEDIATE_s4; \
1539 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
1540 fprintf (out, " low=%ld, high=%ld, default=%ld", \
1541 (long) low, (long) high, (long) default_offset+oldpc); \
1542 for (; low <= high; low++) { \
1543 jint offset = IMMEDIATE_s4; \
1544 fprintf (out, "\n%10ld: %ld", (long)low, (long)(offset+oldpc)); } \
1547 #define SPECIAL(OPERAND_TYPE, OPERAND_VALUE) \
1548 SPECIAL_##OPERAND_VALUE(OPERAND_TYPE)
1550 #define SPECIAL_IINC(OPERAND_TYPE) \
1551 i = saw_wide ? IMMEDIATE_u2 : IMMEDIATE_u1; \
1552 fprintf (out, " %d", i); \
1553 i = saw_wide ? IMMEDIATE_s2 : IMMEDIATE_s1; \
1555 fprintf (out, " %d", i)
1557 #define SPECIAL_WIDE(OPERAND_TYPE) \
1560 #define SPECIAL_EXIT(OPERAND_TYPE) /* nothing */
1561 #define SPECIAL_ENTER(OPERAND_TYPE) /* nothing */
1562 #define SPECIAL_BREAK(OPERAND_TYPE) /* nothing */
1563 #define SPECIAL_THROW(OPERAND_TYPE) /* nothing */
1565 #define IMPL(OPERAND_TYPE, OPERAND_VALUE) \
1566 fprintf (out, " %d", IMMEDIATE_u##OPERAND_VALUE)
1568 #define COND(OPERAND_TYPE, OPERAND_VALUE) \
1569 TEST(OPERAND_TYPE, OPERAND_VALUE)
1571 #include "javaop.def"
1574 if (oldpc+1 == PC) /* nothing - local index implied by opcode */;
1578 fprintf (out, " %ld", (long) INT_temp);
1584 fprintf (out, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);