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,
|
public static InstructionMethodItem makeInstructionFormatMethodItem(MethodDefinition methodDefinition,
|
||||||
CodeItem codeItem,
|
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,
|
Instruction instruction,
|
||||||
boolean isLastInstruction) {
|
boolean isLastInstruction) {
|
||||||
if (instruction instanceof OffsetInstruction) {
|
if (instruction instanceof OffsetInstruction) {
|
||||||
@ -53,13 +81,13 @@ public class InstructionMethodItemFactory {
|
|||||||
|
|
||||||
switch (instruction.getFormat()) {
|
switch (instruction.getFormat()) {
|
||||||
case ArrayData:
|
case ArrayData:
|
||||||
return new ArrayDataMethodItem(codeItem, codeAddress, dead,
|
return new ArrayDataMethodItem(codeItem, codeAddress, isDead,
|
||||||
(ArrayDataPseudoInstruction)instruction);
|
(ArrayDataPseudoInstruction)instruction);
|
||||||
case PackedSwitchData:
|
case PackedSwitchData:
|
||||||
return new PackedSwitchMethodItem(methodDefinition, codeItem, codeAddress, dead,
|
return new PackedSwitchMethodItem(methodDefinition, codeItem, codeAddress, isDead,
|
||||||
(PackedSwitchDataPseudoInstruction)instruction);
|
(PackedSwitchDataPseudoInstruction)instruction);
|
||||||
case SparseSwitchData:
|
case SparseSwitchData:
|
||||||
return new SparseSwitchMethodItem(methodDefinition, codeItem, codeAddress, dead,
|
return new SparseSwitchMethodItem(methodDefinition, codeItem, codeAddress, isDead,
|
||||||
(SparseSwitchDataPseudoInstruction)instruction);
|
(SparseSwitchDataPseudoInstruction)instruction);
|
||||||
case UnresolvedNullReference:
|
case UnresolvedNullReference:
|
||||||
return new UnresolvedNullReferenceMethodItem(codeItem, codeAddress,
|
return new UnresolvedNullReferenceMethodItem(codeItem, codeAddress,
|
||||||
|
@ -49,7 +49,7 @@ import java.util.*;
|
|||||||
|
|
||||||
public class MethodDefinition {
|
public class MethodDefinition {
|
||||||
private final ClassDataItem.EncodedMethod encodedMethod;
|
private final ClassDataItem.EncodedMethod encodedMethod;
|
||||||
private final MethodAnalyzer methodAnalyzer;
|
private MethodAnalyzer methodAnalyzer;
|
||||||
|
|
||||||
private final LabelCache labelCache = new LabelCache();
|
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.
|
//TODO: what about try/catch blocks inside the dead code? those will need to be commented out too. ugh.
|
||||||
|
|
||||||
if (encodedMethod.codeItem != null) {
|
if (encodedMethod.codeItem != null) {
|
||||||
methodAnalyzer = new MethodAnalyzer(encodedMethod, baksmali.deodex);
|
Instruction[] instructions = encodedMethod.codeItem.getInstructions();
|
||||||
List<AnalyzedInstruction> instructions = methodAnalyzer.getInstructions();
|
|
||||||
|
|
||||||
packedSwitchMap = new SparseIntArray(1);
|
packedSwitchMap = new SparseIntArray(1);
|
||||||
sparseSwitchMap = new SparseIntArray(1);
|
sparseSwitchMap = new SparseIntArray(1);
|
||||||
instructionMap = new SparseIntArray(instructions.size());
|
instructionMap = new SparseIntArray(instructions.length);
|
||||||
|
|
||||||
int currentCodeAddress = 0;
|
int currentCodeAddress = 0;
|
||||||
for (int i=0; i<instructions.size(); i++) {
|
for (int i=0; i<instructions.length; i++) {
|
||||||
AnalyzedInstruction instruction = instructions.get(i);
|
Instruction instruction = instructions[i];
|
||||||
if (instruction.getInstruction().opcode == Opcode.PACKED_SWITCH) {
|
if (instruction.opcode == Opcode.PACKED_SWITCH) {
|
||||||
packedSwitchMap.append(
|
packedSwitchMap.append(
|
||||||
currentCodeAddress +
|
currentCodeAddress +
|
||||||
((OffsetInstruction)instruction.getInstruction()).getTargetAddressOffset(),
|
((OffsetInstruction)instruction).getTargetAddressOffset(),
|
||||||
currentCodeAddress);
|
currentCodeAddress);
|
||||||
} else if (instruction.getInstruction().opcode == Opcode.SPARSE_SWITCH) {
|
} else if (instruction.opcode == Opcode.SPARSE_SWITCH) {
|
||||||
sparseSwitchMap.append(
|
sparseSwitchMap.append(
|
||||||
currentCodeAddress +
|
currentCodeAddress +
|
||||||
((OffsetInstruction)instruction.getInstruction()).getTargetAddressOffset(),
|
((OffsetInstruction)instruction).getTargetAddressOffset(),
|
||||||
currentCodeAddress);
|
currentCodeAddress);
|
||||||
}
|
}
|
||||||
instructionMap.append(currentCodeAddress, i);
|
instructionMap.append(currentCodeAddress, i);
|
||||||
currentCodeAddress += instruction.getInstruction().getSize(currentCodeAddress);
|
currentCodeAddress += instruction.getSize(currentCodeAddress);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
packedSwitchMap = null;
|
packedSwitchMap = null;
|
||||||
@ -281,31 +280,96 @@ public class MethodDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<MethodItem> getMethodItems() {
|
private List<MethodItem> getMethodItems() {
|
||||||
List<MethodItem> methodItems = new ArrayList<MethodItem>();
|
ArrayList<MethodItem> methodItems = new ArrayList<MethodItem>();
|
||||||
|
|
||||||
if (encodedMethod.codeItem == null) {
|
if (encodedMethod.codeItem == null) {
|
||||||
return methodItems;
|
return methodItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baksmali.registerInfo != 0 || baksmali.deodex || baksmali.verify) {
|
if (baksmali.registerInfo != 0 || baksmali.deodex || baksmali.verify) {
|
||||||
methodAnalyzer.analyze();
|
addAnalyzedInstructionMethodItems(methodItems);
|
||||||
|
} else {
|
||||||
|
addInstructionMethodItems(methodItems);
|
||||||
|
}
|
||||||
|
|
||||||
ValidationException validationException = methodAnalyzer.getValidationException();
|
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();
|
||||||
|
if (validationException != null) {
|
||||||
|
methodItems.add(new CommentMethodItem(
|
||||||
|
String.format("ValidationException: %s" ,validationException.getMessage()),
|
||||||
|
validationException.getCodeAddress(), Integer.MIN_VALUE));
|
||||||
|
} else if (baksmali.verify) {
|
||||||
|
methodAnalyzer.verify();
|
||||||
|
|
||||||
|
validationException = methodAnalyzer.getValidationException();
|
||||||
if (validationException != null) {
|
if (validationException != null) {
|
||||||
methodItems.add(new CommentMethodItem(
|
methodItems.add(new CommentMethodItem(
|
||||||
String.format("ValidationException: %s" ,validationException.getMessage()),
|
String.format("ValidationException: %s" ,validationException.getMessage()),
|
||||||
validationException.getCodeAddress(), Integer.MIN_VALUE));
|
validationException.getCodeAddress(), Integer.MIN_VALUE));
|
||||||
} else if (baksmali.verify) {
|
|
||||||
methodAnalyzer.verify();
|
|
||||||
|
|
||||||
validationException = methodAnalyzer.getValidationException();
|
|
||||||
if (validationException != null) {
|
|
||||||
methodItems.add(new CommentMethodItem(
|
|
||||||
String.format("ValidationException: %s" ,validationException.getMessage()),
|
|
||||||
validationException.getCodeAddress(), Integer.MIN_VALUE));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<AnalyzedInstruction> instructions = methodAnalyzer.getInstructions();
|
List<AnalyzedInstruction> instructions = methodAnalyzer.getInstructions();
|
||||||
|
|
||||||
AnalyzedInstruction lastInstruction = null;
|
AnalyzedInstruction lastInstruction = null;
|
||||||
@ -325,8 +389,8 @@ public class MethodDefinition {
|
|||||||
for (int i=0; i<instructions.size(); i++) {
|
for (int i=0; i<instructions.size(); i++) {
|
||||||
AnalyzedInstruction instruction = instructions.get(i);
|
AnalyzedInstruction instruction = instructions.get(i);
|
||||||
|
|
||||||
MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this,
|
MethodItem methodItem = InstructionMethodItemFactory.makeAnalyzedInstructionFormatMethodItem(this,
|
||||||
encodedMethod.codeItem, currentCodeAddress, instruction.isDead(), instruction.getInstruction(),
|
encodedMethod.codeItem, currentCodeAddress, instruction.isDead(), instruction.getInstruction(),
|
||||||
instruction == lastInstruction);
|
instruction == lastInstruction);
|
||||||
|
|
||||||
if (instruction.isDead() && !instruction.getInstruction().getFormat().variableSizeFormat) {
|
if (instruction.isDead() && !instruction.getInstruction().getFormat().variableSizeFormat) {
|
||||||
@ -350,9 +414,9 @@ public class MethodDefinition {
|
|||||||
|
|
||||||
if (instruction.getInstruction().getFormat() == Format.UnresolvedNullReference) {
|
if (instruction.getInstruction().getFormat() == Format.UnresolvedNullReference) {
|
||||||
methodItems.add(new CommentedOutMethodItem(
|
methodItems.add(new CommentedOutMethodItem(
|
||||||
InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, encodedMethod.codeItem,
|
InstructionMethodItemFactory.makeAnalyzedInstructionFormatMethodItem(this,
|
||||||
currentCodeAddress, instruction.isDead(), instruction.getOriginalInstruction(),
|
encodedMethod.codeItem, currentCodeAddress, instruction.isDead(),
|
||||||
false)));
|
instruction.getOriginalInstruction(), false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != instructions.size() - 1) {
|
if (i != instructions.size() - 1) {
|
||||||
@ -386,26 +450,6 @@ public class MethodDefinition {
|
|||||||
|
|
||||||
currentCodeAddress += instruction.getInstruction().getSize(currentCodeAddress);
|
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) {
|
private void addTries(List<MethodItem> methodItems) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user