- added logic to check for registers in the debug info that are encoded as a signed LEB128, and keep the same format if the "preserve signed registers" option is on

- fixed several placement/write issues in the debug info

git-svn-id: https://smali.googlecode.com/svn/trunk@381 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2009-08-10 07:03:10 +00:00
parent d269393753
commit 2a8fa1a3b3
4 changed files with 130 additions and 27 deletions

View File

@ -71,33 +71,55 @@ public class DebugInstructionIterator {
} }
case 0x03: case 0x03:
{ {
int registerNum = in.readUnsignedLeb128(); int registerNum = in.readUnsignedOrSignedLeb128();
boolean isSignedRegister = false;
if (registerNum < 0) {
isSignedRegister = true;
registerNum = ~registerNum;
}
int nameIndex = in.readUnsignedLeb128() - 1; int nameIndex = in.readUnsignedLeb128() - 1;
int typeIndex = in.readUnsignedLeb128() - 1; int typeIndex = in.readUnsignedLeb128() - 1;
processDebugInstruction.ProcessStartLocal(startOffset, in.getCursor() - startOffset, registerNum, processDebugInstruction.ProcessStartLocal(startOffset, in.getCursor() - startOffset, registerNum,
nameIndex, typeIndex); nameIndex, typeIndex, isSignedRegister);
break; break;
} }
case 0x04: case 0x04:
{ {
int registerNum = in.readUnsignedLeb128(); int registerNum = in.readUnsignedOrSignedLeb128();
boolean isSignedRegister = false;
if (registerNum < 0) {
isSignedRegister = true;
registerNum = ~registerNum;
}
int nameIndex = in.readUnsignedLeb128() - 1; int nameIndex = in.readUnsignedLeb128() - 1;
int typeIndex = in.readUnsignedLeb128() - 1; int typeIndex = in.readUnsignedLeb128() - 1;
int signatureIndex = in.readUnsignedLeb128() - 1; int signatureIndex = in.readUnsignedLeb128() - 1;
processDebugInstruction.ProcessStartLocalExtended(startOffset, in.getCursor() - startOffset, processDebugInstruction.ProcessStartLocalExtended(startOffset, in.getCursor() - startOffset,
registerNum, nameIndex, typeIndex, signatureIndex); registerNum, nameIndex, typeIndex, signatureIndex, isSignedRegister);
break; break;
} }
case 0x05: case 0x05:
{ {
int registerNum = in.readUnsignedLeb128(); int registerNum = in.readUnsignedOrSignedLeb128();
processDebugInstruction.ProcessEndLocal(startOffset, in.getCursor() - startOffset, registerNum); boolean isSignedRegister = false;
if (registerNum < 0) {
isSignedRegister = true;
registerNum = ~registerNum;
}
processDebugInstruction.ProcessEndLocal(startOffset, in.getCursor() - startOffset, registerNum,
isSignedRegister);
break; break;
} }
case 0x06: case 0x06:
{ {
int registerNum = in.readUnsignedLeb128(); int registerNum = in.readUnsignedOrSignedLeb128();
processDebugInstruction.ProcessRestartLocal(startOffset, in.getCursor() - startOffset, registerNum); boolean isSignedRegister = false;
if (registerNum < 0) {
isSignedRegister = true;
registerNum = ~registerNum;
}
processDebugInstruction.ProcessRestartLocal(startOffset, in.getCursor() - startOffset, registerNum,
isSignedRegister);
break; break;
} }
case 0x07: case 0x07:
@ -255,18 +277,19 @@ public class DebugInstructionIterator {
ProcessStaticOpcode(startOffset, length); ProcessStaticOpcode(startOffset, length);
} }
public void ProcessStartLocal(int startOffset, int length, int registerNum, int nameIndex, int typeIndex) { public void ProcessStartLocal(int startOffset, int length, int registerNum, int nameIndex, int typeIndex,
boolean registerIsSigned) {
} }
public void ProcessStartLocalExtended(int startOffset, int length, int registerNum, int nameIndex, public void ProcessStartLocalExtended(int startOffset, int length, int registerNum, int nameIndex,
int typeIndex,int signatureIndex) { int typeIndex,int signatureIndex, boolean registerIsSigned) {
} }
public void ProcessEndLocal(int startOffset, int length, int registerNum) { public void ProcessEndLocal(int startOffset, int length, int registerNum, boolean registerIsSigned) {
ProcessStaticOpcode(startOffset, length); ProcessStaticOpcode(startOffset, length);
} }
public void ProcessRestartLocal(int startOffset, int length, int registerNum) { public void ProcessRestartLocal(int startOffset, int length, int registerNum, boolean registerIsSigned) {
ProcessStaticOpcode(startOffset, length); ProcessStaticOpcode(startOffset, length);
} }

View File

@ -116,7 +116,7 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
new DebugInstructionIterator.ProcessRawDebugInstructionDelegate() { new DebugInstructionIterator.ProcessRawDebugInstructionDelegate() {
@Override @Override
public void ProcessStartLocal(int startOffset, int length, int registerNum, int nameIndex, public void ProcessStartLocal(int startOffset, int length, int registerNum, int nameIndex,
int typeIndex) { int typeIndex, boolean registerIsSigned) {
if (nameIndex != -1) { if (nameIndex != -1) {
referencedItemsList.add(dexFile.StringIdsSection.getItemByIndex(nameIndex)); referencedItemsList.add(dexFile.StringIdsSection.getItemByIndex(nameIndex));
} }
@ -127,7 +127,8 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
@Override @Override
public void ProcessStartLocalExtended(int startOffset, int length, int registerNume, int nameIndex, public void ProcessStartLocalExtended(int startOffset, int length, int registerNume, int nameIndex,
int typeIndex, int signatureIndex) { int typeIndex, int signatureIndex,
boolean registerIsSigned) {
if (nameIndex != -1) { if (nameIndex != -1) {
referencedItemsList.add(dexFile.StringIdsSection.getItemByIndex(nameIndex)); referencedItemsList.add(dexFile.StringIdsSection.getItemByIndex(nameIndex));
} }
@ -191,15 +192,20 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
@Override @Override
public void ProcessStartLocal(int startOffset, int length, int registerNum, int nameIndex, public void ProcessStartLocal(int startOffset, int length, int registerNum, int nameIndex,
int typeIndex) { int typeIndex, boolean registerIsSigned) {
this.length++;
if (dexFile.getPreserveSignedRegisters() && registerIsSigned) {
this.length += Leb128Utils.signedLeb128Size(registerNum);
} else {
this.length+=Leb128Utils.unsignedLeb128Size(registerNum); this.length+=Leb128Utils.unsignedLeb128Size(registerNum);
if (nameIndex != 0) { }
if (nameIndex != -1) {
this.length+= this.length+=
Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1);
} else { } else {
this.length++; this.length++;
} }
if (typeIndex != 0) { if (typeIndex != -1) {
this.length+= this.length+=
Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1);
} else { } else {
@ -210,21 +216,27 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
@Override @Override
public void ProcessStartLocalExtended(int startOffset, int length, int registerNum, int nameIndex, public void ProcessStartLocalExtended(int startOffset, int length, int registerNum, int nameIndex,
int typeIndex, int signatureIndex) { int typeIndex, int signatureIndex,
boolean registerIsSigned) {
this.length++;
if (dexFile.getPreserveSignedRegisters() && registerIsSigned) {
this.length += Leb128Utils.signedLeb128Size(registerNum);
} else {
this.length+=Leb128Utils.unsignedLeb128Size(registerNum); this.length+=Leb128Utils.unsignedLeb128Size(registerNum);
if (nameIndex != 0) { }
if (nameIndex != -1) {
this.length+= this.length+=
Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1);
} else { } else {
this.length++; this.length++;
} }
if (typeIndex != 0) { if (typeIndex != -1) {
this.length+= this.length+=
Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1);
} else { } else {
this.length++; this.length++;
} }
if (signatureIndex != 0) { if (signatureIndex != -1) {
this.length+= this.length+=
Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1);
} else { } else {
@ -234,7 +246,8 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
@Override @Override
public void ProcessSetFile(int startOffset, int length, int nameIndex) { public void ProcessSetFile(int startOffset, int length, int nameIndex) {
if (nameIndex != 0) { this.length++;
if (nameIndex != -1) {
this.length+= this.length+=
Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1);
} else { } else {
@ -270,7 +283,12 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
@Override @Override
public void ProcessStartLocal(int startOffset, int length, int registerNum, int nameIndex, public void ProcessStartLocal(int startOffset, int length, int registerNum, int nameIndex,
int typeIndex) { int typeIndex, boolean registerIsSigned) {
if (dexFile.getPreserveSignedRegisters() && registerIsSigned) {
out.writeSignedLeb128(registerNum);
} else {
out.writeUnsignedLeb128(registerNum);
}
out.writeUnsignedLeb128(registerNum); out.writeUnsignedLeb128(registerNum);
if (nameIndex != -1) { if (nameIndex != -1) {
out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1);
@ -286,8 +304,13 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
@Override @Override
public void ProcessStartLocalExtended(int startOffset, int length, int registerNum, int nameIndex, public void ProcessStartLocalExtended(int startOffset, int length, int registerNum, int nameIndex,
int typeIndex, int signatureIndex) { int typeIndex, int signatureIndex,
boolean registerIsSigned) {
if (dexFile.getPreserveSignedRegisters() && registerIsSigned) {
out.writeSignedLeb128(registerNum);
} else {
out.writeUnsignedLeb128(registerNum); out.writeUnsignedLeb128(registerNum);
}
if (nameIndex != -1) { if (nameIndex != -1) {
out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1);
} else { } else {

View File

@ -152,6 +152,52 @@ public class ByteArrayInput
((data[readAt + 7] & 0xffL) << 58); ((data[readAt + 7] & 0xffL) << 58);
} }
/** {@inheritDoc} */
public int readUnsignedOrSignedLeb128() {
int end = cursor;
int currentByteValue;
int result;
result = data[end++] & 0xff;
if (result > 0x7f) {
currentByteValue = data[end++] & 0xff;
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 14;
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 21;
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
if (currentByteValue > 0x0f) {
throwInvalidLeb();
}
result |= currentByteValue << 28;
}
}
}
} else {
cursor = end;
return result;
}
cursor = end;
//If the last byte is 0, then this was an unsigned value (incorrectly) written in a signed format
//The caller wants to know if this is the case, so we'll return the negated value instead
//If there was only a single byte that had a value of 0, then we would have returned in the above
//"else"
if (data[end-1] == 0) {
return ~result;
}
return result;
}
/** {@inheritDoc} */ /** {@inheritDoc} */
public int readUnsignedLeb128() { public int readUnsignedLeb128() {
int end = cursor; int end = cursor;

View File

@ -105,6 +105,17 @@ public interface Input {
*/ */
public int readUnsignedLeb128(); public int readUnsignedLeb128();
/**
* Reads a unsigned value as a DWARFv3-style LEB128 integer. It specifically
* checks for the case when the value was incorrectly formatted as a signed
* LEB128, and returns the appropriate unsigned value, but negated
* @return If the value was formatted as a ULEB128, it returns the actual unsigned
* value. Otherwise, if the value was formatted as a signed LEB128, it negates the
* "correct" unsigned value and returns that
*/
public int readUnsignedOrSignedLeb128();
/** /**
* reads a <code>byte[]</code> from this instance. * reads a <code>byte[]</code> from this instance.
* *