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

View File

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

View File

@ -152,6 +152,52 @@ public class ByteArrayInput
((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} */
public int readUnsignedLeb128() {
int end = cursor;

View File

@ -105,6 +105,17 @@ public interface Input {
*/
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.
*