📄 jcf-dump.c
字号:
If verbosity==0, print very tersely (no extraneous text). If verbosity==1, prefix the type of the constant. If verbosity==2, add more descriptive text. */static voidDEFUN(print_constant, (out, jcf, index, verbosity), FILE *out AND JCF *jcf AND int index AND int verbosity){ int j, n; jlong num; const char *str; int kind = JPOOL_TAG (jcf, index); switch (kind) { case CONSTANT_Class: n = JPOOL_USHORT1 (jcf, index); if (verbosity > 0) fprintf (out, verbosity > 1 ? "Class name: %d=" : "Class ", n); if (! CPOOL_INDEX_IN_RANGE (&jcf->cpool, n)) fprintf (out, "<out of range>"); else if (verbosity < 2 && JPOOL_TAG (jcf, n) == CONSTANT_Utf8) { int len = JPOOL_UTF_LENGTH (jcf, n); jcf_print_utf8_replace (out, JPOOL_UTF_DATA(jcf,n), len, '/', '.'); } else print_constant_terse (out, jcf, n, CONSTANT_Utf8); break; case CONSTANT_Fieldref: str = "Field"; goto field_or_method; case CONSTANT_Methodref: str = "Method"; goto field_or_method; case CONSTANT_InterfaceMethodref: str = "InterfaceMethod"; goto field_or_method; field_or_method: { uint16 tclass = JPOOL_USHORT1 (jcf, index); uint16 name_and_type = JPOOL_USHORT2 (jcf, index); if (verbosity == 2) fprintf (out, "%sref class: %d=", str, tclass); else if (verbosity > 0) fprintf (out, "%s ", str); print_constant_terse (out, jcf, tclass, CONSTANT_Class); fprintf (out, verbosity < 2 ? "." : " name_and_type: %d=<", name_and_type); print_constant_terse (out, jcf, name_and_type, CONSTANT_NameAndType); if (verbosity == 2) fputc ('>', out); } break; case CONSTANT_String: j = JPOOL_USHORT1 (jcf, index); if (verbosity > 0) fprintf (out, verbosity > 1 ? "String %d=" : "String ", j); print_constant_terse (out, jcf, j, CONSTANT_Utf8); break; case CONSTANT_Integer: if (verbosity > 0) fprintf (out, "Integer "); num = JPOOL_INT (jcf, index); goto integer; case CONSTANT_Long: if (verbosity > 0) fprintf (out, "Long "); num = JPOOL_LONG (jcf, index); goto integer; integer: { char buffer[25]; format_int (buffer, num, 10); fprintf (out, "%s", buffer); if (verbosity > 1) { format_uint (buffer, (uint64)num, 16); fprintf (out, "=0x%s", buffer); } } break; case CONSTANT_Float: { jfloat fnum = JPOOL_FLOAT (jcf, index); fprintf (out, "%s%.10g", verbosity > 1 ? "Float " : "", (double) fnum); if (verbosity > 1) fprintf (out, ", bits = 0x%08lx", (long) (* (int32 *) &fnum)); break; } case CONSTANT_Double: { jdouble dnum = JPOOL_DOUBLE (jcf, index); fprintf (out, "%s%.20g", verbosity > 1 ? "Double " : "", dnum); if (verbosity > 1) { int32 hi, lo; hi = JPOOL_UINT (jcf, index); lo = JPOOL_UINT (jcf, index + 1); fprintf (out, ", bits = 0x%08lx%08lx", (long) hi, (long) lo); } break; } case CONSTANT_NameAndType: { uint16 name = JPOOL_USHORT1 (jcf, index); uint16 sig = JPOOL_USHORT2 (jcf, index); if (verbosity > 0) fprintf (out, verbosity > 1 ? "%s name: %d=" : "%s ", "NameAndType", name); print_name (out, jcf, name); if (verbosity <= 1) fputc (' ', out); else fprintf (out, ", signature: %d=", sig); print_signature (out, jcf, sig, 0); } break; case CONSTANT_Utf8: { register unsigned char *str = JPOOL_UTF_DATA (jcf, index); int length = JPOOL_UTF_LENGTH (jcf, index); if (verbosity > 0) { /* Print as 8-bit bytes. */ fputs ("Utf8: \"", out); while (--length >= 0) jcf_print_char (out, *str++); } else { /* Print as Unicode. */ fputc ('\"', out); jcf_print_utf8 (out, str, length); } fputc ('\"', out); } break; default: fprintf (out, "(Unknown constant type %d)", kind); }}voidDEFUN(print_constant_pool, (jcf), JCF *jcf){ int i; for (i = 1; i < JPOOL_SIZE(jcf); i++) { int kind = JPOOL_TAG (jcf, i); fprintf (out, "#%d: ", i); print_constant (out, jcf, i, 2); fprintf (out, "\n"); if (kind == CONSTANT_Double || kind == CONSTANT_Long) i++; /* These take up two slots in the constant table */ }}static voidDEFUN(print_signature_type, (stream, ptr, limit), FILE* stream AND const unsigned char **ptr AND const unsigned char *limit){ int array_size; if ((*ptr) >= limit) return; switch (*(*ptr)) { case '[': array_size = -1; for ((*ptr)++; (*ptr) < limit && ISDIGIT (**ptr); (*ptr)++) { array_size = (array_size < 0 ? 0 : 10 * array_size) + *(*ptr) - '0'; } print_signature_type (stream, ptr, limit); if (array_size == -1) fprintf (stream, "[]"); else fprintf (stream, "[%d]", array_size); break; case '(': { int nargs = 0; fputc (*(*ptr)++, stream); for (; **ptr != ')' && *ptr < limit; nargs++) { if (nargs > 0) fputc (',', stream); print_signature_type (stream, ptr, limit); } if (*ptr < limit) { fputc (*(*ptr)++, stream); print_signature_type (stream, ptr, limit); } else fprintf (stream, "???"); } break; case 'B': fprintf (stream, "byte"); (*ptr)++; break; case 'C': fprintf (stream, "char"); (*ptr)++; break; case 'D': fprintf (stream, "double"); (*ptr)++; break; case 'F': fprintf (stream, "float"); (*ptr)++; break; case 'S': fprintf (stream, "short"); (*ptr)++; break; case 'I': fprintf (stream, "int"); (*ptr)++; break; case 'J': fprintf (stream, "long"); (*ptr)++; break; case 'Z': fprintf (stream, "boolean"); (*ptr)++; break; case 'V': fprintf (stream, "void"); (*ptr)++; break; case 'L': for ((*ptr)++; (*ptr)<limit && *(*ptr) != ';'; (*ptr)++) jcf_print_char (stream, *(*ptr) == '/' ? '.' : *(*ptr)); if (*(*ptr) == ';') (*ptr)++; break; default: jcf_print_char (stream, *(*ptr)++); }}static voidDEFUN(print_signature, (stream, jcf, signature_index, int options), FILE* stream AND JCF *jcf AND int signature_index AND int options){ if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8) print_constant_terse (out, jcf, signature_index, CONSTANT_Utf8); else { const unsigned char *str = JPOOL_UTF_DATA (jcf, signature_index); int length = JPOOL_UTF_LENGTH (jcf, signature_index); const unsigned char *limit; limit = str + length; if (str >= limit) fprintf (stream, "<empty signature string>"); else { if (options & PRINT_SIGNATURE_RESULT_ONLY) { while (str < limit && *str++ != ')') ; } if (options & PRINT_SIGNATURE_ARGS_ONLY) { str++; fputc ('(', stream); while (str < limit && *str != ')') { print_signature_type (stream, &str, limit); if (*str != ')') fputs (", ", stream); } fputc (')', stream); } else { print_signature_type (stream, &str, limit); if (str < limit) { fprintf (stream, "<junk:"); jcf_print_utf8 (stream, str, limit - str); fputc ('>', stream); } } } }}static voidDEFUN(print_exception_table, (jcf, entries, count), JCF *jcf AND unsigned char *entries AND int count){ /* Print exception table. */ int i = count; if (i > 0) { unsigned char *ptr = entries; fprintf (out, "Exceptions (count: %d):\n", i); for (; --i >= 0; ptr+= 8) { int start_pc = GET_u2 (ptr); int end_pc = GET_u2 (ptr+2); int handler_pc = GET_u2 (ptr+4); int catch_type = GET_u2 (ptr+6); fprintf (out, " start: %d, end: %d, handler: %d, type: %d", start_pc, end_pc, handler_pc, catch_type); if (catch_type == 0) fputs (" /* finally */", out); else { fputc('=', out); print_constant_terse (out, jcf, catch_type, CONSTANT_Class); } fputc ('\n', out); } }}#include "jcf-reader.c"static intDEFUN (usage, (), ){ fprintf (stderr, "Usage: jcf-dump [-o outputfile] [-c] classname\n"); exit(1);}static voidDEFUN(process_class, (jcf), JCF *jcf){ int code; if (jcf_parse_preamble (jcf) != 0) fprintf (stderr, "Not a valid Java .class file.\n"); /* Parse and possibly print constant pool */ code = jcf_parse_constant_pool (jcf); if (code != 0) { fprintf (stderr, "error while parsing constant pool\n"); exit (FATAL_EXIT_CODE); } code = verify_constant_pool (jcf); if (code > 0) { fprintf (stderr, "error in constant pool entry #%d\n", code); exit (FATAL_EXIT_CODE); } if (flag_print_constant_pool) print_constant_pool (jcf); jcf_parse_class (jcf); code = jcf_parse_fields (jcf); if (code != 0) { fprintf (stderr, "error while parsing fields\n"); exit (FATAL_EXIT_CODE); } code = jcf_parse_methods (jcf); if (code != 0) { fprintf (stderr, "error while parsing methods\n"); exit (FATAL_EXIT_CODE); } code = jcf_parse_final_attributes (jcf); if (code != 0) { fprintf (stderr, "error while parsing final attributes\n"); exit (FATAL_EXIT_CODE); } jcf->filename = NULL;}intDEFUN(main, (argc, argv), int argc AND char** argv){ JCF jcf[1]; int argi; if (argc <= 1) usage (); jcf_path_init (); for (argi = 1; argi < argc; argi++) { char *arg = argv[argi]; if (arg[0] != '-' || ! strcmp (arg, "--")) break; /* Just let all arguments be given in either "-" or "--" form. */ if (arg[1] == '-') ++arg;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -