mirror of
https://github.com/revanced/smali.git
synced 2025-05-05 00:54:25 +02:00
Split the logic for generating the instruction method items depending on whether we need to use the MethodAnalyzer or not
git-svn-id: https://smali.googlecode.com/svn/trunk@736 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
41265daa5a
commit
f7344d33d0
@ -43,7 +43,35 @@ public class InstructionMethodItemFactory {
|
||||
|
||||
public static InstructionMethodItem makeInstructionFormatMethodItem(MethodDefinition methodDefinition,
|
||||
CodeItem codeItem,
|
||||
int codeAddress, boolean dead,
|
||||
int codeAddress,
|
||||
Instruction instruction) {
|
||||
if (instruction instanceof OffsetInstruction) {
|
||||
return new OffsetInstructionFormatMethodItem(methodDefinition.getLabelCache(), codeItem, codeAddress,
|
||||
instruction);
|
||||
}
|
||||
|
||||
switch (instruction.getFormat()) {
|
||||
case ArrayData:
|
||||
return new ArrayDataMethodItem(codeItem, codeAddress, false,
|
||||
(ArrayDataPseudoInstruction)instruction);
|
||||
case PackedSwitchData:
|
||||
return new PackedSwitchMethodItem(methodDefinition, codeItem, codeAddress, false,
|
||||
(PackedSwitchDataPseudoInstruction)instruction);
|
||||
case SparseSwitchData:
|
||||
return new SparseSwitchMethodItem(methodDefinition, codeItem, codeAddress, false,
|
||||
(SparseSwitchDataPseudoInstruction)instruction);
|
||||
case UnresolvedNullReference:
|
||||
assert false;
|
||||
throw new RuntimeException("UnresolvedNullReference not supported, use " +
|
||||
"makeAnalyzedInstructionFormatMethodItem instead");
|
||||
default:
|
||||
return new InstructionMethodItem(codeItem, codeAddress, instruction);
|
||||
}
|
||||
}
|
||||
|
||||
public static InstructionMethodItem makeAnalyzedInstructionFormatMethodItem(MethodDefinition methodDefinition,
|
||||
CodeItem codeItem, int codeAddress,
|
||||
boolean isDead,
|
||||
Instruction instruction,
|
||||
boolean isLastInstruction) {
|
||||
if (instruction instanceof OffsetInstruction) {
|
||||
@ -53,13 +81,13 @@ public class InstructionMethodItemFactory {
|
||||
|
||||
switch (instruction.getFormat()) {
|
||||
case ArrayData:
|
||||
return new ArrayDataMethodItem(codeItem, codeAddress, dead,
|
||||
return new ArrayDataMethodItem(codeItem, codeAddress, isDead,
|
||||
(ArrayDataPseudoInstruction)instruction);
|
||||
case PackedSwitchData:
|
||||
return new PackedSwitchMethodItem(methodDefinition, codeItem, codeAddress, dead,
|
||||
return new PackedSwitchMethodItem(methodDefinition, codeItem, codeAddress, isDead,
|
||||
(PackedSwitchDataPseudoInstruction)instruction);
|
||||
case SparseSwitchData:
|
||||
return new SparseSwitchMethodItem(methodDefinition, codeItem, codeAddress, dead,
|
||||
return new SparseSwitchMethodItem(methodDefinition, codeItem, codeAddress, isDead,
|
||||
(SparseSwitchDataPseudoInstruction)instruction);
|
||||
case UnresolvedNullReference:
|
||||
return new UnresolvedNullReferenceMethodItem(codeItem, codeAddress,
|
||||
|
@ -49,7 +49,7 @@ import java.util.*;
|
||||
|
||||
public class MethodDefinition {
|
||||
private final ClassDataItem.EncodedMethod encodedMethod;
|
||||
private final MethodAnalyzer methodAnalyzer;
|
||||
private MethodAnalyzer methodAnalyzer;
|
||||
|
||||
private final LabelCache labelCache = new LabelCache();
|
||||
|
||||
@ -66,29 +66,28 @@ public class MethodDefinition {
|
||||
//TODO: what about try/catch blocks inside the dead code? those will need to be commented out too. ugh.
|
||||
|
||||
if (encodedMethod.codeItem != null) {
|
||||
methodAnalyzer = new MethodAnalyzer(encodedMethod, baksmali.deodex);
|
||||
List<AnalyzedInstruction> instructions = methodAnalyzer.getInstructions();
|
||||
Instruction[] instructions = encodedMethod.codeItem.getInstructions();
|
||||
|
||||
packedSwitchMap = new SparseIntArray(1);
|
||||
sparseSwitchMap = new SparseIntArray(1);
|
||||
instructionMap = new SparseIntArray(instructions.size());
|
||||
instructionMap = new SparseIntArray(instructions.length);
|
||||
|
||||
int currentCodeAddress = 0;
|
||||
for (int i=0; i<instructions.size(); i++) {
|
||||
AnalyzedInstruction instruction = instructions.get(i);
|
||||
if (instruction.getInstruction().opcode == Opcode.PACKED_SWITCH) {
|
||||
for (int i=0; i<instructions.length; i++) {
|
||||
Instruction instruction = instructions[i];
|
||||
if (instruction.opcode == Opcode.PACKED_SWITCH) {
|
||||
packedSwitchMap.append(
|
||||
currentCodeAddress +
|
||||
((OffsetInstruction)instruction.getInstruction()).getTargetAddressOffset(),
|
||||
((OffsetInstruction)instruction).getTargetAddressOffset(),
|
||||
currentCodeAddress);
|
||||
} else if (instruction.getInstruction().opcode == Opcode.SPARSE_SWITCH) {
|
||||
} else if (instruction.opcode == Opcode.SPARSE_SWITCH) {
|
||||
sparseSwitchMap.append(
|
||||
currentCodeAddress +
|
||||
((OffsetInstruction)instruction.getInstruction()).getTargetAddressOffset(),
|
||||
((OffsetInstruction)instruction).getTargetAddressOffset(),
|
||||
currentCodeAddress);
|
||||
}
|
||||
instructionMap.append(currentCodeAddress, i);
|
||||
currentCodeAddress += instruction.getInstruction().getSize(currentCodeAddress);
|
||||
currentCodeAddress += instruction.getSize(currentCodeAddress);
|
||||
}
|
||||
} else {
|
||||
packedSwitchMap = null;
|
||||
@ -281,13 +280,78 @@ public class MethodDefinition {
|
||||
}
|
||||
|
||||
private List<MethodItem> getMethodItems() {
|
||||
List<MethodItem> methodItems = new ArrayList<MethodItem>();
|
||||
ArrayList<MethodItem> methodItems = new ArrayList<MethodItem>();
|
||||
|
||||
if (encodedMethod.codeItem == null) {
|
||||
return methodItems;
|
||||
}
|
||||
|
||||
if (baksmali.registerInfo != 0 || baksmali.deodex || baksmali.verify) {
|
||||
addAnalyzedInstructionMethodItems(methodItems);
|
||||
} else {
|
||||
addInstructionMethodItems(methodItems);
|
||||
}
|
||||
|
||||
addTries(methodItems);
|
||||
addDebugInfo(methodItems);
|
||||
|
||||
if (baksmali.useSequentialLabels) {
|
||||
setLabelSequentialNumbers();
|
||||
}
|
||||
|
||||
for (LabelMethodItem labelMethodItem: labelCache.getLabels()) {
|
||||
if (labelMethodItem.isCommentedOut()) {
|
||||
methodItems.add(new CommentedOutMethodItem(labelMethodItem));
|
||||
} else {
|
||||
methodItems.add(labelMethodItem);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(methodItems);
|
||||
|
||||
return methodItems;
|
||||
}
|
||||
|
||||
private void addInstructionMethodItems(List<MethodItem> methodItems) {
|
||||
Instruction[] instructions = encodedMethod.codeItem.getInstructions();
|
||||
|
||||
int currentCodeAddress = 0;
|
||||
for (int i=0; i<instructions.length; i++) {
|
||||
Instruction instruction = instructions[i];
|
||||
|
||||
MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this,
|
||||
encodedMethod.codeItem, currentCodeAddress, instruction);
|
||||
|
||||
methodItems.add(methodItem);
|
||||
|
||||
if (i != instructions.length - 1) {
|
||||
methodItems.add(new BlankMethodItem(currentCodeAddress));
|
||||
}
|
||||
|
||||
if (baksmali.addCodeOffsets) {
|
||||
methodItems.add(new MethodItem(currentCodeAddress) {
|
||||
|
||||
@Override
|
||||
public double getSortOrder() {
|
||||
return -1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeTo(IndentingWriter writer) throws IOException {
|
||||
writer.write("#@");
|
||||
writer.printLongAsHex(codeAddress & 0xFFFFFFFF);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
currentCodeAddress += instruction.getSize(currentCodeAddress);
|
||||
}
|
||||
}
|
||||
|
||||
private void addAnalyzedInstructionMethodItems(List<MethodItem> methodItems) {
|
||||
methodAnalyzer = new MethodAnalyzer(encodedMethod, baksmali.deodex);
|
||||
|
||||
methodAnalyzer.analyze();
|
||||
|
||||
ValidationException validationException = methodAnalyzer.getValidationException();
|
||||
@ -305,7 +369,7 @@ public class MethodDefinition {
|
||||
validationException.getCodeAddress(), Integer.MIN_VALUE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<AnalyzedInstruction> instructions = methodAnalyzer.getInstructions();
|
||||
|
||||
AnalyzedInstruction lastInstruction = null;
|
||||
@ -325,7 +389,7 @@ public class MethodDefinition {
|
||||
for (int i=0; i<instructions.size(); i++) {
|
||||
AnalyzedInstruction instruction = instructions.get(i);
|
||||
|
||||
MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this,
|
||||
MethodItem methodItem = InstructionMethodItemFactory.makeAnalyzedInstructionFormatMethodItem(this,
|
||||
encodedMethod.codeItem, currentCodeAddress, instruction.isDead(), instruction.getInstruction(),
|
||||
instruction == lastInstruction);
|
||||
|
||||
@ -350,9 +414,9 @@ public class MethodDefinition {
|
||||
|
||||
if (instruction.getInstruction().getFormat() == Format.UnresolvedNullReference) {
|
||||
methodItems.add(new CommentedOutMethodItem(
|
||||
InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, encodedMethod.codeItem,
|
||||
currentCodeAddress, instruction.isDead(), instruction.getOriginalInstruction(),
|
||||
false)));
|
||||
InstructionMethodItemFactory.makeAnalyzedInstructionFormatMethodItem(this,
|
||||
encodedMethod.codeItem, currentCodeAddress, instruction.isDead(),
|
||||
instruction.getOriginalInstruction(), false)));
|
||||
}
|
||||
|
||||
if (i != instructions.size() - 1) {
|
||||
@ -386,26 +450,6 @@ public class MethodDefinition {
|
||||
|
||||
currentCodeAddress += instruction.getInstruction().getSize(currentCodeAddress);
|
||||
}
|
||||
|
||||
addTries(methodItems);
|
||||
addDebugInfo(methodItems);
|
||||
|
||||
if (baksmali.useSequentialLabels) {
|
||||
setLabelSequentialNumbers();
|
||||
}
|
||||
|
||||
|
||||
for (LabelMethodItem labelMethodItem: labelCache.getLabels()) {
|
||||
if (labelMethodItem.isCommentedOut()) {
|
||||
methodItems.add(new CommentedOutMethodItem(labelMethodItem));
|
||||
} else {
|
||||
methodItems.add(labelMethodItem);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(methodItems);
|
||||
|
||||
return methodItems;
|
||||
}
|
||||
|
||||
private void addTries(List<MethodItem> methodItems) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user