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 dataOffset;
private int dataSize;
private boolean forDumping;
private final DexFile dexFile = this;
@ -97,9 +98,15 @@ public class DexFile
}
public DexFile(File file) {
this(file, false);
}
public DexFile(File file, boolean forDumping) {
this();
Input in = new ByteArrayInput(FileUtils.readFile(file));
this.forDumping = forDumping;
HeaderItemSection.readFrom(1, in);
HeaderItem headerItem = HeaderItemSection.items.get(0);
@ -180,6 +187,10 @@ public class DexFile
return dataSize;
}
public boolean isForDumping() {
return forDumping;
}
public void place() {
int offset = 0;
@ -316,7 +327,7 @@ public class DexFile
public final OffsettedSection<DebugInfoItem> DebugInfoItemsSection = new OffsettedSection<DebugInfoItem>() {
protected DebugInfoItem make(int offset) {
return new DebugInfoItem(dexFile, offset);
return new DebugInfoItem(dexFile, offset);
}
};

View File

@ -41,7 +41,7 @@ public class Leb128Field extends CachedIntegerValueField {
super(value, fieldName);
}
public void readFrom(Input in) {
public void readFrom(Input in) {
value = in.readUnsignedLeb128();
}
@ -52,4 +52,44 @@ public class Leb128Field extends CachedIntegerValueField {
public void writeValue(Output out) {
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:
return new EndLocal();
case 0x06:
return new RestartLocal();
return new RestartLocal(dexFile.isForDumping());
case 0x07:
return new SetPrologueEnd();
case 0x08:

View File

@ -28,25 +28,23 @@
package org.jf.dexlib.debug;
import org.jf.dexlib.ByteField;
import org.jf.dexlib.CompositeField;
import org.jf.dexlib.Field;
import org.jf.dexlib.Leb128Field;
import org.jf.dexlib.*;
public class RestartLocal extends CompositeField<RestartLocal> implements DebugInstruction<RestartLocal> {
private final ByteField opcode;
private final Leb128Field registerNumber;
public RestartLocal() {
public RestartLocal(boolean forDumping) {
super("DBG_RESTART_LOCAL");
fields = new Field[] {
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) {
this();
this(false);
this.registerNumber.cacheValue(registerNumber);
}

View File

@ -40,7 +40,8 @@ public class StartLocal extends CompositeField<StartLocal> implements DebugInstr
super("DBG_START_LOCAL");
fields = new Field[] {
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,
new Leb128p1Field(null), "name_idx"),
localType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection,

View File

@ -41,7 +41,8 @@ public class StartLocalExtended extends CompositeField<StartLocalExtended> imple
super("DBG_START_LOCAL_EXTENDED");
fields = new Field[] {
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,
new Leb128p1Field(null), "name_idx"),
localType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection,