summaryrefslogtreecommitdiffstats
path: root/dexdump
diff options
context:
space:
mode:
authorAndy McFadden <fadden@android.com>2010-04-20 14:18:59 -0700
committerAndy McFadden <fadden@android.com>2010-04-20 15:30:37 -0700
commit0ea77b9be67b3491d878ed0f9314f6ecf6f79d61 (patch)
tree1138bd06810aa9ad1d7e7ad76e5c7521027d6dd3 /dexdump
parent0d90503b1b0e29ec0060938341457f8548ca4ac8 (diff)
downloadandroid_dalvik-0ea77b9be67b3491d878ed0f9314f6ecf6f79d61.tar.gz
android_dalvik-0ea77b9be67b3491d878ed0f9314f6ecf6f79d61.tar.bz2
android_dalvik-0ea77b9be67b3491d878ed0f9314f6ecf6f79d61.zip
Add some .odex info to dexdump output.
"dexdump -f" will now show the contents of the optimized DEX header if one is present. A "table of contents" for the auxillary data is also displayed. As an added bonus, stop being lazy and sanitize the DEX magic before printing it (it has an embedded newline and \0). Change-Id: If9c5278785062cd0f44fc3d3ea0725ef0009932a
Diffstat (limited to 'dexdump')
-rw-r--r--dexdump/DexDump.c120
1 files changed, 118 insertions, 2 deletions
diff --git a/dexdump/DexDump.c b/dexdump/DexDump.c
index b3b0839f7..09b072efb 100644
--- a/dexdump/DexDump.c
+++ b/dexdump/DexDump.c
@@ -357,14 +357,73 @@ static char* createAccessFlagStr(u4 flags, AccessFor forWhat)
/*
+ * Copy character data from "data" to "out", converting non-ASCII values
+ * to printf format chars or an ASCII filler ('.' or '?').
+ *
+ * The output buffer must be able to hold (2*len)+1 bytes. The result is
+ * NUL-terminated.
+ */
+static void asciify(char* out, const unsigned char* data, size_t len)
+{
+ while (len--) {
+ if (*data < 0x20) {
+ /* could do more here, but we don't need them yet */
+ switch (*data) {
+ case '\0':
+ *out++ = '\\';
+ *out++ = '0';
+ break;
+ case '\n':
+ *out++ = '\\';
+ *out++ = 'n';
+ break;
+ default:
+ *out++ = '.';
+ break;
+ }
+ } else if (*data >= 0x80) {
+ *out++ = '?';
+ } else {
+ *out++ = *data;
+ }
+ data++;
+ }
+ *out = '\0';
+}
+
+/*
* Dump the file header.
*/
void dumpFileHeader(const DexFile* pDexFile)
{
+ const DexOptHeader* pOptHeader = pDexFile->pOptHeader;
const DexHeader* pHeader = pDexFile->pHeader;
+ char sanitized[sizeof(pHeader->magic)*2 +1];
+
+ assert(sizeof(pHeader->magic) == sizeof(pOptHeader->magic));
+
+ if (pOptHeader != NULL) {
+ printf("Optimized DEX file header:\n");
+
+ asciify(sanitized, pOptHeader->magic, sizeof(pOptHeader->magic));
+ printf("magic : '%s'\n", sanitized);
+ printf("dex_offset : %d (0x%06x)\n",
+ pOptHeader->dexOffset, pOptHeader->dexOffset);
+ printf("dex_length : %d\n", pOptHeader->dexLength);
+ printf("deps_offset : %d (0x%06x)\n",
+ pOptHeader->depsOffset, pOptHeader->depsOffset);
+ printf("deps_length : %d\n", pOptHeader->depsLength);
+ printf("aux_offset : %d (0x%06x)\n",
+ pOptHeader->auxOffset, pOptHeader->auxOffset);
+ printf("aux_length : %d\n", pOptHeader->auxLength);
+ printf("flags : %08x\n", pOptHeader->flags);
+ printf("checksum : %08x\n", pOptHeader->checksum);
+ printf("\n");
+ }
printf("DEX file header:\n");
- printf("magic : '%.8s'\n", pHeader->magic);
+ asciify(sanitized, pHeader->magic, sizeof(pHeader->magic));
+ printf("magic : '%s'\n", sanitized);
printf("checksum : %08x\n", pHeader->checksum);
printf("signature : %02x%02x...%02x%02x\n",
pHeader->signature[0], pHeader->signature[1],
@@ -397,6 +456,61 @@ void dumpFileHeader(const DexFile* pDexFile)
}
/*
+ * Dump the "table of contents" for the aux area.
+ */
+void dumpAuxDirectory(const DexFile* pDexFile)
+{
+ const DexOptHeader* pOptHeader = pDexFile->pOptHeader;
+ if (pOptHeader == NULL)
+ return;
+
+ printf("AUX section contents:\n");
+
+ const u4* pAux = (const u4*) ((u1*) pOptHeader + pOptHeader->auxOffset);
+
+ if (*pAux == 0) {
+ printf("(1.0 format, only class lookup table is present)\n\n");
+ return;
+ }
+
+ /*
+ * The "aux" section is in "chunk" format: a 32-bit identifier, a 32-bit
+ * length, then the data. Chunks start on 64-bit boundaries.
+ */
+ while (*pAux != kDexChunkEnd) {
+ const char* verboseStr;
+
+ u4 size = *(pAux+1);
+
+ switch (*pAux) {
+ case kDexChunkClassLookup:
+ verboseStr = "class lookup hash table";
+ break;
+ case kDexChunkRegisterMaps:
+ verboseStr = "register maps";
+ break;
+ case kDexChunkReducingIndexMap:
+ verboseStr = "'reducing' index map";
+ break;
+ case kDexChunkExpandingIndexMap:
+ verboseStr = "'expanding' index map";
+ break;
+ default:
+ verboseStr = "(unknown chunk type)";
+ break;
+ }
+
+ printf("Chunk %08x (%c%c%c%c) - %s (%d bytes)\n", *pAux,
+ *pAux >> 24, (char)(*pAux >> 16), (char)(*pAux >> 8), (char)*pAux,
+ verboseStr, size);
+
+ size = (size + 8 + 7) & ~7;
+ pAux += size / sizeof(u4);
+ }
+ printf("\n");
+}
+
+/*
* Dump a class_def_item.
*/
void dumpClassDef(DexFile* pDexFile, int idx)
@@ -1609,8 +1723,10 @@ void processDexFile(const char* fileName, DexFile* pDexFile)
return;
}
- if (gOptions.showFileHeaders)
+ if (gOptions.showFileHeaders) {
dumpFileHeader(pDexFile);
+ dumpAuxDirectory(pDexFile);
+ }
if (gOptions.outputFormat == OUTPUT_XML)
printf("<api>\n");