/* Verify field data */ static void verify_field(RefIndex list, FieldInfo *fields, jvalue *fvalues, int n_fields, jint index, jvalue value, jvmtiPrimitiveType primType) { HPROF_ASSERT(fvalues != NULL); HPROF_ASSERT(n_fields > 0); HPROF_ASSERT(index < n_fields); HPROF_ASSERT(index >= 0 ); if ( primType!=fields[index].primType ) { dump_fields(list, fields, fvalues, n_fields); debug_message("\nPROBLEM WITH:\n"); dump_field(fields, fvalues, n_fields, index, value, primType); debug_message("\n"); HPROF_ERROR(JNI_FALSE, "Trouble with fields and heap data"); } if ( primType == JVMTI_PRIMITIVE_TYPE_BOOLEAN && ( value.b != 1 && value.b != 0 ) ) { dump_fields(list, fields, fvalues, n_fields); debug_message("\nPROBLEM WITH:\n"); dump_field(fields, fvalues, n_fields, index, value, primType); debug_message("\n"); HPROF_ERROR(JNI_FALSE, "Trouble with fields and heap data"); } }
static void dump_fields(region r, const char *prefix, field_declaration fields) { while (fields) { if (fields->name) /* skip anon fields */ { type t = fields->type; printf(" %s%s ", prefix, fields->name); while (type_array(t)) { type base = type_array_of(t); expression size = type_array_size(t); printf("[%lu]", (unsigned long)constant_uint_value(size->cst)); t = base; } dump_type(t); assert(cval_isinteger(fields->offset)); printf(" %lu %lu\n", (unsigned long)cval_uint_value(fields->offset), (unsigned long) (!cval_istop(fields->bitwidth) ? cval_uint_value(fields->bitwidth) : BITSPERBYTE * cval_uint_value(type_size(t)))); if (type_aggregate(t)) { tag_declaration tdecl = type_tag(t); char *newprefix = rarrayalloc(r, strlen(prefix) + strlen(fields->name) + 2, char); sprintf(newprefix, "%s%s.", prefix, fields->name); dump_fields(r, newprefix, tdecl->fieldlist); printf(" %s%s AX\n", prefix, fields->name); } } fields = fields->next; }
int main(int argc, char* argv[]) { bool all = false; bool string = false; bool stringdata = false; bool type = false; bool proto = false; bool field = false; bool meth = false; bool clsdef = false; bool clsdata = false; bool code = false; bool enarr = false; bool anno = false; bool debug = false; uint32_t ddebug_offset = 0; char c; static const struct option options[] = { { "all", no_argument, nullptr, 'a' }, { "string", no_argument, nullptr, 's' }, { "stringdata", no_argument, nullptr, 'S' }, { "type", no_argument, nullptr, 't' }, { "proto", no_argument, nullptr, 'p' }, { "field", no_argument, nullptr, 'f' }, { "meth", no_argument, nullptr, 'm' }, { "clsdef", no_argument, nullptr, 'c' }, { "clsdata", no_argument, nullptr, 'C' }, { "code", no_argument, nullptr, 'x' }, { "enarr", no_argument, nullptr, 'e' }, { "anno", no_argument, nullptr, 'A' }, { "debug", no_argument, nullptr, 'd' }, { "ddebug", required_argument, nullptr, 'D' }, { "clean", no_argument, (int*)&clean, 1 }, { "help", no_argument, nullptr, 'h' }, { nullptr, 0, nullptr, 0 }, }; while ((c = getopt_long( argc, argv, "asStpfmcCxeAdDh", &options[0], nullptr)) != -1) { switch (c) { case 'a': all = true; break; case 's': string = true; break; case 'S': stringdata = true; break; case 't': type = true; break; case 'p': proto = true; break; case 'f': field = true; break; case 'm': meth = true; break; case 'c': clsdef = true; break; case 'C': clsdata = true; break; case 'x': code = true; break; case 'e': enarr = true; break; case 'A': anno = true; break; case 'd': debug = true; break; case 'D': sscanf(optarg, "%x", &ddebug_offset); break; case 'h': puts(ddump_usage_string); return 0; case '?': return 1; // getopt_long has printed an error case 0: // we're handling a long-only option break; default: abort(); } } if (optind == argc) { fprintf(stderr, "%s: no dex files given; use -h for help\n", argv[0]); return 1; } while (optind < argc) { const char* dexfile = argv[optind++]; ddump_data rd; open_dex_file(dexfile, &rd); redump(format_map(&rd).c_str()); if (string || all) { dump_strings(&rd); } if (stringdata || all) { dump_stringdata(&rd); } if (type || all) { dump_types(&rd); } if (proto || all) { dump_protos(&rd); } if (field || all) { dump_fields(&rd); } if (meth || all) { dump_methods(&rd); } if (clsdef || all) { dump_clsdefs(&rd); } if (clsdata || all) { dump_clsdata(&rd); } if (code || all) { dump_code(&rd); } if (enarr || all) { dump_enarr(&rd); } if (anno || all) { dump_anno(&rd); } if (debug || all) { dump_debug(&rd); } if (ddebug_offset != 0) { disassemble_debug(&rd, ddebug_offset); } fprintf(stdout, "\n"); fflush(stdout); } return 0; }