mirror of
https://github.com/revanced/smali.git
synced 2025-05-28 03:40:12 +02:00
Improve the way sparse/packed switch data blocks are found and processed
This commit is contained in:
parent
82cdb8a8af
commit
cb3e0ea38a
@ -40,9 +40,8 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchDataPseudoInstruction>
|
||||
implements Iterable<LabelMethodItem> {
|
||||
private final List<LabelMethodItem> labels;
|
||||
public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchDataPseudoInstruction> {
|
||||
private final List<PackedSwitchTarget> targets;
|
||||
|
||||
public PackedSwitchMethodItem(MethodDefinition methodDefinition, CodeItem codeItem, int codeAddress,
|
||||
PackedSwitchDataPseudoInstruction instruction) {
|
||||
@ -50,13 +49,29 @@ public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchDa
|
||||
|
||||
int baseCodeAddress = methodDefinition.getPackedSwitchBaseAddress(codeAddress);
|
||||
|
||||
labels = new ArrayList<LabelMethodItem>();
|
||||
targets = new ArrayList<PackedSwitchTarget>();
|
||||
Iterator<PackedSwitchDataPseudoInstruction.PackedSwitchTarget> iterator = instruction.iterateKeysAndTargets();
|
||||
while (iterator.hasNext()) {
|
||||
PackedSwitchDataPseudoInstruction.PackedSwitchTarget target = iterator.next();
|
||||
LabelMethodItem label = new LabelMethodItem(baseCodeAddress + target.targetAddressOffset, "pswitch_");
|
||||
label = methodDefinition.getLabelCache().internLabel(label);
|
||||
labels.add(label);
|
||||
|
||||
if (baseCodeAddress >= 0) {
|
||||
while (iterator.hasNext()) {
|
||||
PackedSwitchDataPseudoInstruction.PackedSwitchTarget target = iterator.next();
|
||||
PackedSwitchLabelTarget packedSwitchLabelTarget = new PackedSwitchLabelTarget();
|
||||
|
||||
|
||||
LabelMethodItem label = new LabelMethodItem(baseCodeAddress + target.targetAddressOffset, "pswitch_");
|
||||
label = methodDefinition.getLabelCache().internLabel(label);
|
||||
packedSwitchLabelTarget.Target = label;
|
||||
targets.add(packedSwitchLabelTarget);
|
||||
}
|
||||
} else {
|
||||
while (iterator.hasNext()) {
|
||||
PackedSwitchDataPseudoInstruction.PackedSwitchTarget target = iterator.next();
|
||||
PackedSwitchOffsetTarget packedSwitchOffsetTarget = new PackedSwitchOffsetTarget();
|
||||
|
||||
|
||||
packedSwitchOffsetTarget.Target = target.targetAddressOffset;
|
||||
targets.add(packedSwitchOffsetTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,8 +81,8 @@ public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchDa
|
||||
IntegerRenderer.writeTo(writer, instruction.getFirstKey());
|
||||
writer.indent(4);
|
||||
writer.write('\n');
|
||||
for (LabelMethodItem label: labels) {
|
||||
label.writeTo(writer);
|
||||
for (PackedSwitchTarget target: targets) {
|
||||
target.writeTargetTo(writer);
|
||||
writer.write('\n');
|
||||
}
|
||||
writer.deindent(4);
|
||||
@ -75,7 +90,24 @@ public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchDa
|
||||
return true;
|
||||
}
|
||||
|
||||
public Iterator<LabelMethodItem> iterator() {
|
||||
return labels.iterator();
|
||||
private static abstract class PackedSwitchTarget {
|
||||
public abstract void writeTargetTo(IndentingWriter writer) throws IOException;
|
||||
}
|
||||
|
||||
private static class PackedSwitchLabelTarget extends PackedSwitchTarget {
|
||||
public LabelMethodItem Target;
|
||||
public void writeTargetTo(IndentingWriter writer) throws IOException {
|
||||
Target.writeTo(writer);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PackedSwitchOffsetTarget extends PackedSwitchTarget {
|
||||
public int Target;
|
||||
public void writeTargetTo(IndentingWriter writer) throws IOException {
|
||||
if (Target >= 0) {
|
||||
writer.write('+');
|
||||
}
|
||||
writer.printSignedIntAsDec(Target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,8 +40,7 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchDataPseudoInstruction>
|
||||
implements Iterable<LabelMethodItem> {
|
||||
public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchDataPseudoInstruction> {
|
||||
private final List<SparseSwitchTarget> targets;
|
||||
|
||||
public SparseSwitchMethodItem(MethodDefinition methodDefinition, CodeItem codeItem, int codeAddress,
|
||||
@ -52,16 +51,28 @@ public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchDa
|
||||
|
||||
targets = new ArrayList<SparseSwitchTarget>();
|
||||
Iterator<SparseSwitchDataPseudoInstruction.SparseSwitchTarget> iterator = instruction.iterateKeysAndTargets();
|
||||
while (iterator.hasNext()) {
|
||||
SparseSwitchDataPseudoInstruction.SparseSwitchTarget target = iterator.next();
|
||||
SparseSwitchTarget sparseSwitchTarget = new SparseSwitchTarget();
|
||||
sparseSwitchTarget.Key = target.key;
|
||||
if (baseCodeAddress != 0) {
|
||||
while (iterator.hasNext()) {
|
||||
SparseSwitchDataPseudoInstruction.SparseSwitchTarget target = iterator.next();
|
||||
SparseSwitchLabelTarget sparseSwitchLabelTarget = new SparseSwitchLabelTarget();
|
||||
sparseSwitchLabelTarget.Key = target.key;
|
||||
|
||||
LabelMethodItem label = new LabelMethodItem(baseCodeAddress + target.targetAddressOffset, "sswitch_");
|
||||
label = methodDefinition.getLabelCache().internLabel(label);
|
||||
sparseSwitchTarget.Target = label;
|
||||
LabelMethodItem label = new LabelMethodItem(baseCodeAddress + target.targetAddressOffset, "sswitch_");
|
||||
label = methodDefinition.getLabelCache().internLabel(label);
|
||||
sparseSwitchLabelTarget.Target = label;
|
||||
|
||||
targets.add(sparseSwitchTarget);
|
||||
targets.add(sparseSwitchLabelTarget);
|
||||
}
|
||||
} else {
|
||||
//if we couldn't determine a base address, just use relative offsets rather than labels
|
||||
while (iterator.hasNext()) {
|
||||
SparseSwitchDataPseudoInstruction.SparseSwitchTarget target = iterator.next();
|
||||
SparseSwitchOffsetTarget sparseSwitchOffsetTarget = new SparseSwitchOffsetTarget();
|
||||
sparseSwitchOffsetTarget.Key = target.key;
|
||||
|
||||
sparseSwitchOffsetTarget.Target = target.targetAddressOffset;
|
||||
targets.add(sparseSwitchOffsetTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +83,7 @@ public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchDa
|
||||
for (SparseSwitchTarget target: targets) {
|
||||
IntegerRenderer.writeTo(writer, target.Key);
|
||||
writer.write(" -> ");
|
||||
target.Target.writeTo(writer);
|
||||
target.writeTargetTo(writer);
|
||||
writer.write('\n');
|
||||
}
|
||||
writer.deindent(4);
|
||||
@ -80,26 +91,25 @@ public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchDa
|
||||
return true;
|
||||
}
|
||||
|
||||
public Iterator<LabelMethodItem> iterator() {
|
||||
return new Iterator<LabelMethodItem>() {
|
||||
private Iterator<SparseSwitchTarget> iterator = targets.iterator();
|
||||
|
||||
public boolean hasNext() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
public LabelMethodItem next() {
|
||||
return iterator.next().Target;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
iterator.remove();
|
||||
}
|
||||
};
|
||||
private static abstract class SparseSwitchTarget {
|
||||
public int Key;
|
||||
public abstract void writeTargetTo(IndentingWriter writer) throws IOException;
|
||||
}
|
||||
|
||||
private static class SparseSwitchTarget {
|
||||
public int Key;
|
||||
private static class SparseSwitchLabelTarget extends SparseSwitchTarget {
|
||||
public LabelMethodItem Target;
|
||||
public void writeTargetTo(IndentingWriter writer) throws IOException {
|
||||
Target.writeTo(writer);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SparseSwitchOffsetTarget extends SparseSwitchTarget {
|
||||
public int Target;
|
||||
public void writeTargetTo(IndentingWriter writer) throws IOException {
|
||||
if (Target >= 0) {
|
||||
writer.write('+');
|
||||
}
|
||||
writer.printSignedIntAsDec(Target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -239,8 +239,12 @@ public class MethodDefinition {
|
||||
int packedSwitchBaseAddress = this.packedSwitchMap.get(packedSwitchDataAddress, -1);
|
||||
|
||||
if (packedSwitchBaseAddress == -1) {
|
||||
throw new RuntimeException("Could not find the packed switch statement corresponding to the packed " +
|
||||
"switch data at address " + packedSwitchDataAddress);
|
||||
Instruction[] instructions = encodedMethod.codeItem.getInstructions();
|
||||
int index = instructionMap.get(packedSwitchDataAddress);
|
||||
|
||||
if (instructions[index].opcode == Opcode.NOP) {
|
||||
packedSwitchBaseAddress = this.packedSwitchMap.get(packedSwitchDataAddress+2, -1);
|
||||
}
|
||||
}
|
||||
|
||||
return packedSwitchBaseAddress;
|
||||
@ -250,8 +254,12 @@ public class MethodDefinition {
|
||||
int sparseSwitchBaseAddress = this.sparseSwitchMap.get(sparseSwitchDataAddress, -1);
|
||||
|
||||
if (sparseSwitchBaseAddress == -1) {
|
||||
throw new RuntimeException("Could not find the sparse switch statement corresponding to the sparse " +
|
||||
"switch data at address " + sparseSwitchDataAddress);
|
||||
Instruction[] instructions = encodedMethod.codeItem.getInstructions();
|
||||
int index = instructionMap.get(sparseSwitchDataAddress);
|
||||
|
||||
if (instructions[index].opcode == Opcode.NOP) {
|
||||
sparseSwitchBaseAddress = this.packedSwitchMap.get(sparseSwitchDataAddress+2, -1);
|
||||
}
|
||||
}
|
||||
|
||||
return sparseSwitchBaseAddress;
|
||||
|
Loading…
x
Reference in New Issue
Block a user