Automated import from //branches/master/...@142073,142073
diff --git a/dexdump/DexDump.c b/dexdump/DexDump.c
index 879288b..9929264 100644
--- a/dexdump/DexDump.c
+++ b/dexdump/DexDump.c
@@ -1060,6 +1060,45 @@
return (u1*) (((int) ptr + 3) & ~0x03);
}
+
+/*
+ * Dump a map in the "differential" format.
+ *
+ * TODO: show a hex dump of the compressed data. (We can show the
+ * uncompressed data if we move the compression code to libdex; otherwise
+ * it's too complex to merit a fast & fragile implementation here.)
+ */
+void dumpDifferentialCompressedMap(const u1** pData)
+{
+ const u1* data = *pData;
+ const u1* dataStart = data -1; // format byte already removed
+ u1 regWidth;
+ u2 numEntries;
+
+ /* standard header */
+ regWidth = *data++;
+ numEntries = *data++;
+ numEntries |= (*data++) << 8;
+
+ /* compressed data begins with the compressed data length */
+ int compressedLen = readUnsignedLeb128(&data);
+ int addrWidth = 1;
+ if ((*data & 0x80) != 0)
+ addrWidth++;
+
+ int origLen = 4 + (addrWidth + regWidth) * numEntries;
+ int compLen = (data - dataStart) + compressedLen;
+
+ printf(" (differential compression %d -> %d [%d -> %d])\n",
+ origLen, compLen,
+ (addrWidth + regWidth) * numEntries, compressedLen);
+
+ /* skip past end of entry */
+ data += compressedLen;
+
+ *pData = data;
+}
+
/*
* Dump register map contents of the current method.
*
@@ -1090,9 +1129,13 @@
addrWidth = 1;
} else if (format == 3) { /* kRegMapFormatCompact16 */
addrWidth = 2;
+ } else if (format == 4) { /* kRegMapFormatDifferential */
+ dumpDifferentialCompressedMap(&data);
+ goto bail;
} else {
printf(" (unknown format %d!)\n", format);
- addrWidth = -1;
+ /* don't know how to skip data; failure will cascade to end of class */
+ goto bail;
}
if (addrWidth > 0) {
@@ -1117,6 +1160,7 @@
}
}
+bail:
//if (addrWidth >= 0)
// *pData = align32(data);
*pData = data;
diff --git a/vm/analysis/RegisterMap.c b/vm/analysis/RegisterMap.c
index 9d88e34..5718507 100644
--- a/vm/analysis/RegisterMap.c
+++ b/vm/analysis/RegisterMap.c
@@ -1548,9 +1548,9 @@
addrDiff = addr - prevAddr;
assert(addrDiff > 0);
- if (addrDiff < 7) {
+ if (addrDiff < 8) {
/* small difference, encode in 3 bits */
- key = addr - prevAddr; /* set 00000AAA */
+ key = addrDiff -1; /* set 00000AAA */
if (debug)
LOGI(" : small %d, key=0x%02x\n", addrDiff, key);
} else {
@@ -1593,7 +1593,7 @@
* diff (if it didn't fit in 3 bits), then the changed bit info.
*/
*tmpPtr++ = key;
- if (addrDiff >= 7)
+ if ((key & 0x07) == 0x07)
tmpPtr = writeUnsignedLeb128(tmpPtr, addrDiff);
if ((key & 0x08) != 0) {
@@ -1768,7 +1768,7 @@
/* address diff follows in ULEB128 */
addrDiff = readUnsignedLeb128(&srcPtr);
} else {
- addrDiff = key & 0x07;
+ addrDiff = (key & 0x07) +1;
}
addr = prevAddr + addrDiff;