From f7344d33d01953eee129f3cfa2b9655eb65bfe2f Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Sat, 12 Jun 2010 15:55:36 +0000 Subject: [PATCH] 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 --- .../Format/InstructionMethodItemFactory.java | 36 ++++- .../baksmali/Adaptors/MethodDefinition.java | 140 ++++++++++++------ 2 files changed, 124 insertions(+), 52 deletions(-) diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItemFactory.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItemFactory.java index ecc3c11d..73bcab8d 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItemFactory.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItemFactory.java @@ -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, diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java index 10e063a2..ecdca0c2 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java @@ -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 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 getMethodItems() { - List methodItems = new ArrayList(); + ArrayList methodItems = new ArrayList(); if (encodedMethod.codeItem == null) { return methodItems; } 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 methodItems) { + Instruction[] instructions = encodedMethod.codeItem.getInstructions(); + + int currentCodeAddress = 0; + for (int i=0; i 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) { 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) { - methodItems.add(new CommentMethodItem( - String.format("ValidationException: %s" ,validationException.getMessage()), - validationException.getCodeAddress(), Integer.MIN_VALUE)); - } } } + List instructions = methodAnalyzer.getInstructions(); AnalyzedInstruction lastInstruction = null; @@ -325,8 +389,8 @@ public class MethodDefinition { for (int i=0; i methodItems) {