Fixed an issue with alignment for the pseudo opcodes, and a test to exercise the issue

git-svn-id: https://smali.googlecode.com/svn/trunk@153 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2009-06-16 03:31:44 +00:00
parent acf2ddb67e
commit 2fb16c8f4b
5 changed files with 119 additions and 3 deletions

View File

@ -39,8 +39,14 @@ import java.util.ArrayList;
public class ArrayDataPseudoInstruction extends Instruction
{
private int elementWidth;
private List<byte[]> values;
public ArrayDataPseudoInstruction(DexFile dexFile, int elementWidth, List<byte[]> values) {
super(dexFile, Opcode.NOP, (IndexedItem)null);
this.elementWidth = elementWidth;
this.values = values;
int byteCount = 0;
@ -88,7 +94,7 @@ public class ArrayDataPseudoInstruction extends Instruction
throw new RuntimeException("Invalid opcode byte for an ArrayData pseudo-instruction");
}
byte subopcodeByte = input.readByte();
if (subopcodeByte != 0x02) {
if (subopcodeByte != 0x03) {
throw new RuntimeException("Invalid sub-opcode byte for an ArrayData pseudo-instruction");
}
@ -111,4 +117,12 @@ public class ArrayDataPseudoInstruction extends Instruction
protected Instruction makeClone() {
return new ArrayDataPseudoInstruction();
}
public int getElementWidth() {
return elementWidth;
}
public List<byte[]> getValues() {
return values;
}
}

View File

@ -36,8 +36,13 @@ import org.jf.dexlib.util.Input;
public class PackedSwitchDataPseudoInstruction extends Instruction
{
private int firstKey;
private int[] targets;
public PackedSwitchDataPseudoInstruction(DexFile dexFile, int firstKey, int[] targets) {
super(dexFile, Opcode.NOP, (IndexedItem)null);
this.firstKey = firstKey;
this.targets = targets;
if (targets.length > 0xFFFF) {
throw new RuntimeException("The packed-switch data contains too many elements. " +
@ -100,6 +105,14 @@ public class PackedSwitchDataPseudoInstruction extends Instruction
}
public Format getFormat() {
return Format.SparseSwitchData;
return Format.PackedSwitchData;
}
public int getFirstKey() {
return firstKey;
}
public int[] getTargets() {
return targets;
}
}

View File

@ -36,9 +36,15 @@ import org.jf.dexlib.util.Input;
public class SparseSwitchDataPseudoInstruction extends Instruction
{
private int[] keys;
private int[] targets;
public SparseSwitchDataPseudoInstruction(DexFile dexFile, int[] keys, int[] targets) {
super(dexFile, Opcode.NOP, (IndexedItem)null);
this.keys = keys;
this.targets = targets;
if (keys.length != targets.length) {
throw new RuntimeException("The number of keys and offsets don't match");
}
@ -130,4 +136,12 @@ public class SparseSwitchDataPseudoInstruction extends Instruction
public Format getFormat() {
return Format.SparseSwitchData;
}
public int[] getKeys() {
return keys;
}
public int[] getTargets() {
return targets;
}
}

View File

@ -63,4 +63,79 @@ PackedSwitch:
Label12:
Label13:
.end packed-switch
.end method
.method public test2()V
.registers 2
.annotation runtime Lorg/junit/Test;
.end annotation
const v0, 0
invoke-static {}, LSpecialInstructionPaddingTest;->paddingTest()I
move-result v0
const/16 v1, 12
#the real test is that dalvik loaded and verified this class. This is
#mostly just to make sure that the method was actually called
invoke-static {v0, v1}, LAssert;->assertEquals(II)V
return-void
.end method
.method public static paddingTest()I
.registers 2
const v0, 12
packed-switch v0, PackedSwitch:
packed-switch v0, PackedSwitch2:
Label10:
const v1, 10
return v1
Label11:
const v1, 11
return v1
Label12:
const v1, 12
return v1
Label13:
const v1, 13
return v1
PackedSwitch:
.packed-switch 10
Label10:
Label11:
Label12:
Label13:
.end packed-switch
#this tests out an issue that occured where the prior packed switch data starts at a byte offset
#that is 4 byte aligned but isn't 8 byte aligned, which caused the code to report the size of the
#instruction to be 2 bytes more than it should be.
#
#Normally, if things are working correctly, this nop will cause the following packed-switch data
#to be unaligned. But with the above issue, the logic will *think* that the packed switch data
#is aligned, and won't output the extra nop to align it, thus causing a verification error.
nop
PackedSwitch2:
.packed-switch 10
Label10:
Label11:
Label12:
Label13:
.end packed-switch
.end method

View File

@ -686,7 +686,7 @@ statements[int totalMethodRegisters, int methodParameterRegisters] returns[Array
{
if ($instruction.instruction != null) {
$instructions.add($instruction.instruction);
$method::currentAddress += $instruction.instruction.getSize($method::currentAddress) / 2;
$method::currentAddress += $instruction.instruction.getSize($method::currentAddress * 2) / 2;
}
})*);