Added a flag and logic to preserve the signed leb128 encoded registers in the debug info, for dumping purposes

git-svn-id: https://smali.googlecode.com/svn/trunk@182 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2009-06-20 21:34:51 +00:00
parent 4517100574
commit a950eddc2a
6 changed files with 63 additions and 12 deletions

View File

@ -48,6 +48,7 @@ public class DexFile
private int fileSize; private int fileSize;
private int dataOffset; private int dataOffset;
private int dataSize; private int dataSize;
private boolean forDumping;
private final DexFile dexFile = this; private final DexFile dexFile = this;
@ -97,9 +98,15 @@ public class DexFile
} }
public DexFile(File file) { public DexFile(File file) {
this(file, false);
}
public DexFile(File file, boolean forDumping) {
this(); this();
Input in = new ByteArrayInput(FileUtils.readFile(file)); Input in = new ByteArrayInput(FileUtils.readFile(file));
this.forDumping = forDumping;
HeaderItemSection.readFrom(1, in); HeaderItemSection.readFrom(1, in);
HeaderItem headerItem = HeaderItemSection.items.get(0); HeaderItem headerItem = HeaderItemSection.items.get(0);
@ -180,6 +187,10 @@ public class DexFile
return dataSize; return dataSize;
} }
public boolean isForDumping() {
return forDumping;
}
public void place() { public void place() {
int offset = 0; int offset = 0;

View File

@ -52,4 +52,44 @@ public class Leb128Field extends CachedIntegerValueField {
public void writeValue(Output out) { public void writeValue(Output out) {
out.writeUnsignedLeb128(value); out.writeUnsignedLeb128(value);
} }
/**
* dx had a bug where it would write registers in the debug
* info as signed leb 128 values instead of unsigned. This class
* is used when it is important to keep the same format as the
* file being read in - for example when the intent is to immediately
* write the file back out (typically for dumping/annotation purposes)
*/
public static class PossiblySignedLeb128Field extends Leb128Field {
private boolean signed = false;
public PossiblySignedLeb128Field(String fieldName) {
super (fieldName);
}
public void readFrom(Input in) {
int start = in.getCursor();
value = in.readUnsignedLeb128();
int end = in.getCursor();
if (Leb128Utils.unsignedLeb128Size(value) != (end - start)) {
signed = true;
}
}
public int place(int offset) {
if (signed) {
return offset + Leb128Utils.signedLeb128Size(value);
}
return offset + Leb128Utils.unsignedLeb128Size(value);
}
public void writeValue(Output out) {
if (signed) {
out.writeSignedLeb128(value);
} else {
out.writeUnsignedLeb128(value);
}
}
}
} }

View File

@ -57,7 +57,7 @@ public abstract class DebugInstructionFactory {
case 0x05: case 0x05:
return new EndLocal(); return new EndLocal();
case 0x06: case 0x06:
return new RestartLocal(); return new RestartLocal(dexFile.isForDumping());
case 0x07: case 0x07:
return new SetPrologueEnd(); return new SetPrologueEnd();
case 0x08: case 0x08:

View File

@ -28,25 +28,23 @@
package org.jf.dexlib.debug; package org.jf.dexlib.debug;
import org.jf.dexlib.ByteField; import org.jf.dexlib.*;
import org.jf.dexlib.CompositeField;
import org.jf.dexlib.Field;
import org.jf.dexlib.Leb128Field;
public class RestartLocal extends CompositeField<RestartLocal> implements DebugInstruction<RestartLocal> { public class RestartLocal extends CompositeField<RestartLocal> implements DebugInstruction<RestartLocal> {
private final ByteField opcode; private final ByteField opcode;
private final Leb128Field registerNumber; private final Leb128Field registerNumber;
public RestartLocal() { public RestartLocal(boolean forDumping) {
super("DBG_RESTART_LOCAL"); super("DBG_RESTART_LOCAL");
fields = new Field[] { fields = new Field[] {
opcode = new ByteField((byte)0x06, "opcode"), opcode = new ByteField((byte)0x06, "opcode"),
registerNumber = new Leb128Field("register_num") registerNumber = forDumping?new Leb128Field.PossiblySignedLeb128Field("register_num"):
new Leb128Field("register_num")
}; };
} }
public RestartLocal(int registerNumber) { public RestartLocal(int registerNumber) {
this(); this(false);
this.registerNumber.cacheValue(registerNumber); this.registerNumber.cacheValue(registerNumber);
} }

View File

@ -40,7 +40,8 @@ public class StartLocal extends CompositeField<StartLocal> implements DebugInstr
super("DBG_START_LOCAL"); super("DBG_START_LOCAL");
fields = new Field[] { fields = new Field[] {
opcodeField = new ByteField((byte)0x03, "opcode"), opcodeField = new ByteField((byte)0x03, "opcode"),
registerNumber = new Leb128Field("register_num"), registerNumber = dexFile.isForDumping()?new Leb128Field.PossiblySignedLeb128Field("register_num"):
new Leb128Field("register_num"),
localName = new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, localName = new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection,
new Leb128p1Field(null), "name_idx"), new Leb128p1Field(null), "name_idx"),
localType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, localType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection,

View File

@ -41,7 +41,8 @@ public class StartLocalExtended extends CompositeField<StartLocalExtended> imple
super("DBG_START_LOCAL_EXTENDED"); super("DBG_START_LOCAL_EXTENDED");
fields = new Field[] { fields = new Field[] {
opcodeField = new ByteField((byte)0x04, "opcode"), opcodeField = new ByteField((byte)0x04, "opcode"),
registerNumber = new Leb128Field("register_num"), registerNumber = dexFile.isForDumping()?new Leb128Field.PossiblySignedLeb128Field("register_num"):
new Leb128Field("register_num"),
localName = new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, localName = new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection,
new Leb128p1Field(null), "name_idx"), new Leb128p1Field(null), "name_idx"),
localType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, localType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection,