mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 04:10:13 +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.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchDataPseudoInstruction>
|
public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchDataPseudoInstruction> {
|
||||||
implements Iterable<LabelMethodItem> {
|
private final List<PackedSwitchTarget> targets;
|
||||||
private final List<LabelMethodItem> labels;
|
|
||||||
|
|
||||||
public PackedSwitchMethodItem(MethodDefinition methodDefinition, CodeItem codeItem, int codeAddress,
|
public PackedSwitchMethodItem(MethodDefinition methodDefinition, CodeItem codeItem, int codeAddress,
|
||||||
PackedSwitchDataPseudoInstruction instruction) {
|
PackedSwitchDataPseudoInstruction instruction) {
|
||||||
@ -50,13 +49,29 @@ public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchDa
|
|||||||
|
|
||||||
int baseCodeAddress = methodDefinition.getPackedSwitchBaseAddress(codeAddress);
|
int baseCodeAddress = methodDefinition.getPackedSwitchBaseAddress(codeAddress);
|
||||||
|
|
||||||
labels = new ArrayList<LabelMethodItem>();
|
targets = new ArrayList<PackedSwitchTarget>();
|
||||||
Iterator<PackedSwitchDataPseudoInstruction.PackedSwitchTarget> iterator = instruction.iterateKeysAndTargets();
|
Iterator<PackedSwitchDataPseudoInstruction.PackedSwitchTarget> iterator = instruction.iterateKeysAndTargets();
|
||||||
while (iterator.hasNext()) {
|
|
||||||
PackedSwitchDataPseudoInstruction.PackedSwitchTarget target = iterator.next();
|
if (baseCodeAddress >= 0) {
|
||||||
LabelMethodItem label = new LabelMethodItem(baseCodeAddress + target.targetAddressOffset, "pswitch_");
|
while (iterator.hasNext()) {
|
||||||
label = methodDefinition.getLabelCache().internLabel(label);
|
PackedSwitchDataPseudoInstruction.PackedSwitchTarget target = iterator.next();
|
||||||
labels.add(label);
|
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());
|
IntegerRenderer.writeTo(writer, instruction.getFirstKey());
|
||||||
writer.indent(4);
|
writer.indent(4);
|
||||||
writer.write('\n');
|
writer.write('\n');
|
||||||
for (LabelMethodItem label: labels) {
|
for (PackedSwitchTarget target: targets) {
|
||||||
label.writeTo(writer);
|
target.writeTargetTo(writer);
|
||||||
writer.write('\n');
|
writer.write('\n');
|
||||||
}
|
}
|
||||||
writer.deindent(4);
|
writer.deindent(4);
|
||||||
@ -75,7 +90,24 @@ public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchDa
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterator<LabelMethodItem> iterator() {
|
private static abstract class PackedSwitchTarget {
|
||||||
return labels.iterator();
|
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.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchDataPseudoInstruction>
|
public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchDataPseudoInstruction> {
|
||||||
implements Iterable<LabelMethodItem> {
|
|
||||||
private final List<SparseSwitchTarget> targets;
|
private final List<SparseSwitchTarget> targets;
|
||||||
|
|
||||||
public SparseSwitchMethodItem(MethodDefinition methodDefinition, CodeItem codeItem, int codeAddress,
|
public SparseSwitchMethodItem(MethodDefinition methodDefinition, CodeItem codeItem, int codeAddress,
|
||||||
@ -52,16 +51,28 @@ public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchDa
|
|||||||
|
|
||||||
targets = new ArrayList<SparseSwitchTarget>();
|
targets = new ArrayList<SparseSwitchTarget>();
|
||||||
Iterator<SparseSwitchDataPseudoInstruction.SparseSwitchTarget> iterator = instruction.iterateKeysAndTargets();
|
Iterator<SparseSwitchDataPseudoInstruction.SparseSwitchTarget> iterator = instruction.iterateKeysAndTargets();
|
||||||
while (iterator.hasNext()) {
|
if (baseCodeAddress != 0) {
|
||||||
SparseSwitchDataPseudoInstruction.SparseSwitchTarget target = iterator.next();
|
while (iterator.hasNext()) {
|
||||||
SparseSwitchTarget sparseSwitchTarget = new SparseSwitchTarget();
|
SparseSwitchDataPseudoInstruction.SparseSwitchTarget target = iterator.next();
|
||||||
sparseSwitchTarget.Key = target.key;
|
SparseSwitchLabelTarget sparseSwitchLabelTarget = new SparseSwitchLabelTarget();
|
||||||
|
sparseSwitchLabelTarget.Key = target.key;
|
||||||
|
|
||||||
LabelMethodItem label = new LabelMethodItem(baseCodeAddress + target.targetAddressOffset, "sswitch_");
|
LabelMethodItem label = new LabelMethodItem(baseCodeAddress + target.targetAddressOffset, "sswitch_");
|
||||||
label = methodDefinition.getLabelCache().internLabel(label);
|
label = methodDefinition.getLabelCache().internLabel(label);
|
||||||
sparseSwitchTarget.Target = 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) {
|
for (SparseSwitchTarget target: targets) {
|
||||||
IntegerRenderer.writeTo(writer, target.Key);
|
IntegerRenderer.writeTo(writer, target.Key);
|
||||||
writer.write(" -> ");
|
writer.write(" -> ");
|
||||||
target.Target.writeTo(writer);
|
target.writeTargetTo(writer);
|
||||||
writer.write('\n');
|
writer.write('\n');
|
||||||
}
|
}
|
||||||
writer.deindent(4);
|
writer.deindent(4);
|
||||||
@ -80,26 +91,25 @@ public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchDa
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterator<LabelMethodItem> iterator() {
|
private static abstract class SparseSwitchTarget {
|
||||||
return new Iterator<LabelMethodItem>() {
|
public int Key;
|
||||||
private Iterator<SparseSwitchTarget> iterator = targets.iterator();
|
public abstract void writeTargetTo(IndentingWriter writer) throws IOException;
|
||||||
|
|
||||||
public boolean hasNext() {
|
|
||||||
return iterator.hasNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
public LabelMethodItem next() {
|
|
||||||
return iterator.next().Target;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove() {
|
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SparseSwitchTarget {
|
private static class SparseSwitchLabelTarget extends SparseSwitchTarget {
|
||||||
public int Key;
|
|
||||||
public LabelMethodItem Target;
|
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);
|
int packedSwitchBaseAddress = this.packedSwitchMap.get(packedSwitchDataAddress, -1);
|
||||||
|
|
||||||
if (packedSwitchBaseAddress == -1) {
|
if (packedSwitchBaseAddress == -1) {
|
||||||
throw new RuntimeException("Could not find the packed switch statement corresponding to the packed " +
|
Instruction[] instructions = encodedMethod.codeItem.getInstructions();
|
||||||
"switch data at address " + packedSwitchDataAddress);
|
int index = instructionMap.get(packedSwitchDataAddress);
|
||||||
|
|
||||||
|
if (instructions[index].opcode == Opcode.NOP) {
|
||||||
|
packedSwitchBaseAddress = this.packedSwitchMap.get(packedSwitchDataAddress+2, -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return packedSwitchBaseAddress;
|
return packedSwitchBaseAddress;
|
||||||
@ -250,8 +254,12 @@ public class MethodDefinition {
|
|||||||
int sparseSwitchBaseAddress = this.sparseSwitchMap.get(sparseSwitchDataAddress, -1);
|
int sparseSwitchBaseAddress = this.sparseSwitchMap.get(sparseSwitchDataAddress, -1);
|
||||||
|
|
||||||
if (sparseSwitchBaseAddress == -1) {
|
if (sparseSwitchBaseAddress == -1) {
|
||||||
throw new RuntimeException("Could not find the sparse switch statement corresponding to the sparse " +
|
Instruction[] instructions = encodedMethod.codeItem.getInstructions();
|
||||||
"switch data at address " + sparseSwitchDataAddress);
|
int index = instructionMap.get(sparseSwitchDataAddress);
|
||||||
|
|
||||||
|
if (instructions[index].opcode == Opcode.NOP) {
|
||||||
|
sparseSwitchBaseAddress = this.packedSwitchMap.get(sparseSwitchDataAddress+2, -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sparseSwitchBaseAddress;
|
return sparseSwitchBaseAddress;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user