Refactor the way the baksmali options are handled

This commit is contained in:
Ben Gruver 2013-04-07 22:36:17 -07:00
parent 71a580878f
commit 93aa50139c
15 changed files with 161 additions and 97 deletions

View File

@ -28,8 +28,11 @@
package org.jf.baksmali.Adaptors; package org.jf.baksmali.Adaptors;
import org.jf.baksmali.baksmaliOptions;
import org.jf.util.IndentingWriter; import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException; import java.io.IOException;
public class CatchMethodItem extends MethodItem { public class CatchMethodItem extends MethodItem {
@ -39,21 +42,22 @@ public class CatchMethodItem extends MethodItem {
private final LabelMethodItem tryEndLabel; private final LabelMethodItem tryEndLabel;
private final LabelMethodItem handlerLabel; private final LabelMethodItem handlerLabel;
public CatchMethodItem(MethodDefinition.LabelCache labelCache, int codeAddress, String exceptionType, public CatchMethodItem(@Nonnull baksmaliOptions options, @Nonnull MethodDefinition.LabelCache labelCache,
int startAddress, int endAddress, int handlerAddress) { int codeAddress, @Nullable String exceptionType, int startAddress, int endAddress,
int handlerAddress) {
super(codeAddress); super(codeAddress);
this.exceptionType = exceptionType; this.exceptionType = exceptionType;
tryStartLabel = labelCache.internLabel(new LabelMethodItem(startAddress, "try_start_")); tryStartLabel = labelCache.internLabel(new LabelMethodItem(options, startAddress, "try_start_"));
//use the address from the last covered instruction, but make the label //use the address from the last covered instruction, but make the label
//name refer to the address of the next instruction //name refer to the address of the next instruction
tryEndLabel = labelCache.internLabel(new EndTryLabelMethodItem(codeAddress, endAddress)); tryEndLabel = labelCache.internLabel(new EndTryLabelMethodItem(options, codeAddress, endAddress));
if (exceptionType == null) { if (exceptionType == null) {
handlerLabel = labelCache.internLabel(new LabelMethodItem(handlerAddress, "catchall_")); handlerLabel = labelCache.internLabel(new LabelMethodItem(options, handlerAddress, "catchall_"));
} else { } else {
handlerLabel = labelCache.internLabel(new LabelMethodItem(handlerAddress, "catch_")); handlerLabel = labelCache.internLabel(new LabelMethodItem(options, handlerAddress, "catch_"));
} }
} }

View File

@ -29,6 +29,7 @@
package org.jf.baksmali.Adaptors; package org.jf.baksmali.Adaptors;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.jf.baksmali.baksmaliOptions;
import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.iface.*; import org.jf.dexlib2.iface.*;
import org.jf.dexlib2.iface.instruction.Instruction; import org.jf.dexlib2.iface.instruction.Instruction;
@ -46,12 +47,14 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
public class ClassDefinition { public class ClassDefinition {
@Nonnull public final baksmaliOptions options;
@Nonnull public final ClassDef classDef; @Nonnull public final ClassDef classDef;
@Nonnull private final HashSet<String> fieldsSetInStaticConstructor; @Nonnull private final HashSet<String> fieldsSetInStaticConstructor;
protected boolean validationErrors; protected boolean validationErrors;
public ClassDefinition(ClassDef classDef) { public ClassDefinition(@Nonnull baksmaliOptions options, @Nonnull ClassDef classDef) {
this.options = options;
this.classDef = classDef; this.classDef = classDef;
fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor(); fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor();
} }

View File

@ -28,11 +28,15 @@
package org.jf.baksmali.Adaptors; package org.jf.baksmali.Adaptors;
import org.jf.baksmali.baksmaliOptions;
import javax.annotation.Nonnull;
public class EndTryLabelMethodItem extends LabelMethodItem { public class EndTryLabelMethodItem extends LabelMethodItem {
private int endTryAddress; private int endTryAddress;
public EndTryLabelMethodItem(int codeAddress, int endTryAddress) { public EndTryLabelMethodItem(@Nonnull baksmaliOptions options, int codeAddress, int endTryAddress) {
super(codeAddress, "try_end_"); super(options, codeAddress, "try_end_");
this.endTryAddress = endTryAddress; this.endTryAddress = endTryAddress;
} }

View File

@ -43,7 +43,8 @@ public class InstructionMethodItemFactory {
MethodDefinition methodDef, int codeAddress, Instruction instruction) { MethodDefinition methodDef, int codeAddress, Instruction instruction) {
if (instruction instanceof OffsetInstruction) { if (instruction instanceof OffsetInstruction) {
return new OffsetInstructionFormatMethodItem(methodDef, codeAddress, (OffsetInstruction)instruction); return new OffsetInstructionFormatMethodItem(methodDef.classDef.options, methodDef, codeAddress,
(OffsetInstruction)instruction);
} }
switch (instruction.getOpcode().format) { switch (instruction.getOpcode().format) {

View File

@ -30,20 +30,22 @@ package org.jf.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.LabelMethodItem; import org.jf.baksmali.Adaptors.LabelMethodItem;
import org.jf.baksmali.Adaptors.MethodDefinition; import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.baksmali.baksmaliOptions;
import org.jf.dexlib2.Opcode; import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.iface.instruction.OffsetInstruction; import org.jf.dexlib2.iface.instruction.OffsetInstruction;
import org.jf.util.IndentingWriter; import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
public class OffsetInstructionFormatMethodItem extends InstructionMethodItem<OffsetInstruction> { public class OffsetInstructionFormatMethodItem extends InstructionMethodItem<OffsetInstruction> {
protected LabelMethodItem label; protected LabelMethodItem label;
public OffsetInstructionFormatMethodItem(MethodDefinition methodDef, int codeAddress, public OffsetInstructionFormatMethodItem(@Nonnull baksmaliOptions options, @Nonnull MethodDefinition methodDef,
OffsetInstruction instruction) { int codeAddress, OffsetInstruction instruction) {
super(methodDef, codeAddress, instruction); super(methodDef, codeAddress, instruction);
label = new LabelMethodItem(codeAddress + instruction.getCodeOffset(), getLabelPrefix()); label = new LabelMethodItem(options, codeAddress + instruction.getCodeOffset(), getLabelPrefix());
label = methodDef.getLabelCache().internLabel(label); label = methodDef.getLabelCache().internLabel(label);
} }

View File

@ -60,7 +60,8 @@ public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchPa
first = false; first = false;
} }
LabelMethodItem label = methodDef.getLabelCache().internLabel( LabelMethodItem label = methodDef.getLabelCache().internLabel(
new LabelMethodItem(baseCodeAddress + switchElement.getOffset(), "pswitch_")); new LabelMethodItem(methodDef.classDef.options, baseCodeAddress + switchElement.getOffset(),
"pswitch_"));
targets.add(new PackedSwitchLabelTarget(label)); targets.add(new PackedSwitchLabelTarget(label));
} }
} else { } else {

View File

@ -51,7 +51,8 @@ public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchPa
if (baseCodeAddress >= 0) { if (baseCodeAddress >= 0) {
for (SwitchElement switchElement: instruction.getSwitchElements()) { for (SwitchElement switchElement: instruction.getSwitchElements()) {
LabelMethodItem label = methodDef.getLabelCache().internLabel( LabelMethodItem label = methodDef.getLabelCache().internLabel(
new LabelMethodItem(baseCodeAddress + switchElement.getOffset(), "sswitch_")); new LabelMethodItem( methodDef.classDef.options, baseCodeAddress + switchElement.getOffset(),
"sswitch_"));
targets.add(new SparseSwitchLabelTarget(switchElement.getKey(), label)); targets.add(new SparseSwitchLabelTarget(switchElement.getKey(), label));
} }
} else { } else {

View File

@ -28,17 +28,20 @@
package org.jf.baksmali.Adaptors; package org.jf.baksmali.Adaptors;
import org.jf.baksmali.baksmaliOptions;
import org.jf.util.IndentingWriter; import org.jf.util.IndentingWriter;
import org.jf.baksmali.baksmali;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
public class LabelMethodItem extends MethodItem { public class LabelMethodItem extends MethodItem {
private final baksmaliOptions options;
private final String labelPrefix; private final String labelPrefix;
private int labelSequence; private int labelSequence;
public LabelMethodItem(int codeAddress, String labelPrefix) { public LabelMethodItem(@Nonnull baksmaliOptions options, int codeAddress, @Nonnull String labelPrefix) {
super(codeAddress); super(codeAddress);
this.options = options;
this.labelPrefix = labelPrefix; this.labelPrefix = labelPrefix;
} }
@ -73,7 +76,7 @@ public class LabelMethodItem extends MethodItem {
public boolean writeTo(IndentingWriter writer) throws IOException { public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write(':'); writer.write(':');
writer.write(labelPrefix); writer.write(labelPrefix);
if (baksmali.useSequentialLabels) { if (options.useSequentialLabels) {
writer.printUnsignedLongAsHex(labelSequence); writer.printUnsignedLongAsHex(labelSequence);
} else { } else {
writer.printUnsignedLongAsHex(this.getLabelAddress()); writer.printUnsignedLongAsHex(this.getLabelAddress());

View File

@ -31,7 +31,6 @@ package org.jf.baksmali.Adaptors;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.jf.baksmali.Adaptors.Debug.DebugMethodItem; import org.jf.baksmali.Adaptors.Debug.DebugMethodItem;
import org.jf.baksmali.Adaptors.Format.InstructionMethodItemFactory; import org.jf.baksmali.Adaptors.Format.InstructionMethodItemFactory;
import org.jf.baksmali.baksmali;
import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.Format; import org.jf.dexlib2.Format;
import org.jf.dexlib2.Opcode; import org.jf.dexlib2.Opcode;
@ -157,7 +156,7 @@ public class MethodDefinition {
writer.write('\n'); writer.write('\n');
writer.indent(4); writer.indent(4);
if (baksmali.useLocalsDirective) { if (classDef.options.useLocalsDirective) {
writer.write(".locals "); writer.write(".locals ");
writer.printSignedIntAsDec(methodImpl.getRegisterCount() - parameterRegisterCount); writer.printSignedIntAsDec(methodImpl.getRegisterCount() - parameterRegisterCount);
} else { } else {
@ -168,7 +167,8 @@ public class MethodDefinition {
writeParameters(writer, method, methodParameters); writeParameters(writer, method, methodParameters);
if (registerFormatter == null) { if (registerFormatter == null) {
registerFormatter = new RegisterFormatter(methodImpl.getRegisterCount(), parameterRegisterCount); registerFormatter = new RegisterFormatter(classDef.options, methodImpl.getRegisterCount(),
parameterRegisterCount);
} }
AnnotationFormatter.writeTo(writer, method.getAnnotations()); AnnotationFormatter.writeTo(writer, method.getAnnotations());
@ -268,18 +268,18 @@ public class MethodDefinition {
private List<MethodItem> getMethodItems() { private List<MethodItem> getMethodItems() {
ArrayList<MethodItem> methodItems = new ArrayList<MethodItem>(); ArrayList<MethodItem> methodItems = new ArrayList<MethodItem>();
if ((baksmali.registerInfo != 0) || (baksmali.deodex && needsAnalyzed())) { if ((classDef.options.registerInfo != 0) || (classDef.options.deodex && needsAnalyzed())) {
addAnalyzedInstructionMethodItems(methodItems); addAnalyzedInstructionMethodItems(methodItems);
} else { } else {
addInstructionMethodItems(methodItems); addInstructionMethodItems(methodItems);
} }
addTries(methodItems); addTries(methodItems);
if (baksmali.outputDebugInfo) { if (classDef.options.outputDebugInfo) {
addDebugInfo(methodItems); addDebugInfo(methodItems);
} }
if (baksmali.useSequentialLabels) { if (classDef.options.useSequentialLabels) {
setLabelSequentialNumbers(); setLabelSequentialNumbers();
} }
@ -315,7 +315,7 @@ public class MethodDefinition {
methodItems.add(new BlankMethodItem(currentCodeAddress)); methodItems.add(new BlankMethodItem(currentCodeAddress));
} }
if (baksmali.addCodeOffsets) { if (classDef.options.addCodeOffsets) {
methodItems.add(new MethodItem(currentCodeAddress) { methodItems.add(new MethodItem(currentCodeAddress) {
@Override @Override
@ -332,7 +332,7 @@ public class MethodDefinition {
}); });
} }
if (!baksmali.noAccessorComments && (instruction instanceof ReferenceInstruction)) { if (!classDef.options.noAccessorComments && (instruction instanceof ReferenceInstruction)) {
Opcode opcode = instruction.getOpcode(); Opcode opcode = instruction.getOpcode();
if (opcode.referenceType == ReferenceType.METHOD) { if (opcode.referenceType == ReferenceType.METHOD) {
@ -341,7 +341,7 @@ public class MethodDefinition {
if (SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) { if (SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) {
SyntheticAccessorResolver.AccessedMember accessedMember = SyntheticAccessorResolver.AccessedMember accessedMember =
baksmali.syntheticAccessorResolver.getAccessedMember(methodReference); classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference);
if (accessedMember != null) { if (accessedMember != null) {
methodItems.add(new SyntheticAccessCommentMethodItem(accessedMember, currentCodeAddress)); methodItems.add(new SyntheticAccessCommentMethodItem(accessedMember, currentCodeAddress));
} }
@ -354,7 +354,8 @@ public class MethodDefinition {
} }
private void addAnalyzedInstructionMethodItems(List<MethodItem> methodItems) { private void addAnalyzedInstructionMethodItems(List<MethodItem> methodItems) {
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(baksmali.classPath, method, baksmali.inlineResolver); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classDef.options.classPath, method,
classDef.options.inlineResolver);
AnalysisException analysisException = methodAnalyzer.getAnalysisException(); AnalysisException analysisException = methodAnalyzer.getAnalysisException();
if (analysisException != null) { if (analysisException != null) {
@ -384,7 +385,7 @@ public class MethodDefinition {
methodItems.add(new BlankMethodItem(currentCodeAddress)); methodItems.add(new BlankMethodItem(currentCodeAddress));
} }
if (baksmali.addCodeOffsets) { if (classDef.options.addCodeOffsets) {
methodItems.add(new MethodItem(currentCodeAddress) { methodItems.add(new MethodItem(currentCodeAddress) {
@Override @Override
@ -401,9 +402,10 @@ public class MethodDefinition {
}); });
} }
if (baksmali.registerInfo != 0 && !instruction.getInstruction().getOpcode().format.isPayloadFormat) { if (classDef.options.registerInfo != 0 &&
!instruction.getInstruction().getOpcode().format.isPayloadFormat) {
methodItems.add( methodItems.add(
new PreInstructionRegisterInfoMethodItem( new PreInstructionRegisterInfoMethodItem(classDef.options.registerInfo,
methodAnalyzer, registerFormatter, instruction, currentCodeAddress)); methodAnalyzer, registerFormatter, instruction, currentCodeAddress));
methodItems.add( methodItems.add(
@ -455,7 +457,7 @@ public class MethodDefinition {
} }
//use the address from the last covered instruction //use the address from the last covered instruction
CatchMethodItem catchMethodItem = new CatchMethodItem(labelCache, lastCoveredAddress, CatchMethodItem catchMethodItem = new CatchMethodItem(classDef.options, labelCache, lastCoveredAddress,
handler.getExceptionType(), startAddress, endAddress, handlerAddress); handler.getExceptionType(), startAddress, endAddress, handlerAddress);
methodItems.add(catchMethodItem); methodItems.add(catchMethodItem);
} }

View File

@ -28,8 +28,7 @@
package org.jf.baksmali.Adaptors; package org.jf.baksmali.Adaptors;
import org.jf.baksmali.baksmali; import org.jf.baksmali.baksmaliOptions;
import org.jf.baksmali.main;
import org.jf.dexlib2.analysis.AnalyzedInstruction; import org.jf.dexlib2.analysis.AnalyzedInstruction;
import org.jf.dexlib2.analysis.RegisterType; import org.jf.dexlib2.analysis.RegisterType;
import org.jf.util.IndentingWriter; import org.jf.util.IndentingWriter;
@ -57,16 +56,16 @@ public class PostInstructionRegisterInfoMethodItem extends MethodItem {
@Override @Override
public boolean writeTo(IndentingWriter writer) throws IOException { public boolean writeTo(IndentingWriter writer) throws IOException {
int registerInfo = baksmali.registerInfo; int registerInfo = registerFormatter.options.registerInfo;
int registerCount = analyzedInstruction.getRegisterCount(); int registerCount = analyzedInstruction.getRegisterCount();
BitSet registers = new BitSet(registerCount); BitSet registers = new BitSet(registerCount);
if ((registerInfo & main.ALL) != 0) { if ((registerInfo & baksmaliOptions.ALL) != 0) {
registers.set(0, registerCount); registers.set(0, registerCount);
} else { } else {
if ((registerInfo & main.ALLPOST) != 0) { if ((registerInfo & baksmaliOptions.ALLPOST) != 0) {
registers.set(0, registerCount); registers.set(0, registerCount);
} else if ((registerInfo & main.DEST) != 0) { } else if ((registerInfo & baksmaliOptions.DEST) != 0) {
addDestRegs(registers, registerCount); addDestRegs(registers, registerCount);
} }
} }

View File

@ -28,8 +28,7 @@
package org.jf.baksmali.Adaptors; package org.jf.baksmali.Adaptors;
import org.jf.baksmali.baksmali; import org.jf.baksmali.baksmaliOptions;
import org.jf.baksmali.main;
import org.jf.dexlib2.analysis.AnalyzedInstruction; import org.jf.dexlib2.analysis.AnalyzedInstruction;
import org.jf.dexlib2.analysis.MethodAnalyzer; import org.jf.dexlib2.analysis.MethodAnalyzer;
import org.jf.dexlib2.analysis.RegisterType; import org.jf.dexlib2.analysis.RegisterType;
@ -41,15 +40,18 @@ import java.io.IOException;
import java.util.BitSet; import java.util.BitSet;
public class PreInstructionRegisterInfoMethodItem extends MethodItem { public class PreInstructionRegisterInfoMethodItem extends MethodItem {
private final int registerInfo;
@Nonnull private final MethodAnalyzer methodAnalyzer; @Nonnull private final MethodAnalyzer methodAnalyzer;
@Nonnull private final RegisterFormatter registerFormatter; @Nonnull private final RegisterFormatter registerFormatter;
@Nonnull private final AnalyzedInstruction analyzedInstruction; @Nonnull private final AnalyzedInstruction analyzedInstruction;
public PreInstructionRegisterInfoMethodItem(@Nonnull MethodAnalyzer methodAnalyzer, public PreInstructionRegisterInfoMethodItem(int registerInfo,
@Nonnull MethodAnalyzer methodAnalyzer,
@Nonnull RegisterFormatter registerFormatter, @Nonnull RegisterFormatter registerFormatter,
@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull AnalyzedInstruction analyzedInstruction,
int codeAddress) { int codeAddress) {
super(codeAddress); super(codeAddress);
this.registerInfo = registerInfo;
this.methodAnalyzer = methodAnalyzer; this.methodAnalyzer = methodAnalyzer;
this.registerFormatter = registerFormatter; this.registerFormatter = registerFormatter;
this.analyzedInstruction = analyzedInstruction; this.analyzedInstruction = analyzedInstruction;
@ -62,22 +64,21 @@ public class PreInstructionRegisterInfoMethodItem extends MethodItem {
@Override @Override
public boolean writeTo(IndentingWriter writer) throws IOException { public boolean writeTo(IndentingWriter writer) throws IOException {
int registerInfo = baksmali.registerInfo;
int registerCount = analyzedInstruction.getRegisterCount(); int registerCount = analyzedInstruction.getRegisterCount();
BitSet registers = new BitSet(registerCount); BitSet registers = new BitSet(registerCount);
if ((registerInfo & main.ALL) != 0) { if ((registerInfo & baksmaliOptions.ALL) != 0) {
registers.set(0, registerCount); registers.set(0, registerCount);
} else { } else {
if ((registerInfo & main.ALLPRE) != 0) { if ((registerInfo & baksmaliOptions.ALLPRE) != 0) {
registers.set(0, registerCount); registers.set(0, registerCount);
} else { } else {
if ((registerInfo & main.ARGS) != 0) { if ((registerInfo & baksmaliOptions.ARGS) != 0) {
addArgsRegs(registers); addArgsRegs(registers);
} }
if ((registerInfo & main.MERGE) != 0) { if ((registerInfo & baksmaliOptions.MERGE) != 0) {
addMergeRegs(registers, registerCount); addMergeRegs(registers, registerCount);
} else if ((registerInfo & main.FULLMERGE) != 0 && } else if ((registerInfo & baksmaliOptions.FULLMERGE) != 0 &&
(analyzedInstruction.isBeginningInstruction())) { (analyzedInstruction.isBeginningInstruction())) {
addParamRegs(registers, registerCount); addParamRegs(registers, registerCount);
} }
@ -85,7 +86,7 @@ public class PreInstructionRegisterInfoMethodItem extends MethodItem {
} }
boolean printedSomething = false; boolean printedSomething = false;
if ((registerInfo & main.FULLMERGE) != 0) { if ((registerInfo & baksmaliOptions.FULLMERGE) != 0) {
printedSomething = writeFullMergeRegs(writer, registers, registerCount); printedSomething = writeFullMergeRegs(writer, registers, registerCount);
} }

View File

@ -28,19 +28,22 @@
package org.jf.baksmali.Adaptors; package org.jf.baksmali.Adaptors;
import org.jf.baksmali.baksmali; import org.jf.baksmali.baksmaliOptions;
import org.jf.util.IndentingWriter; import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
/** /**
* This class contains the logic used for formatting registers * This class contains the logic used for formatting registers
*/ */
public class RegisterFormatter { public class RegisterFormatter {
@Nonnull public final baksmaliOptions options;
public final int registerCount; public final int registerCount;
public final int parameterRegisterCount; public final int parameterRegisterCount;
public RegisterFormatter(int registerCount, int parameterRegisterCount) { public RegisterFormatter(@Nonnull baksmaliOptions options, int registerCount, int parameterRegisterCount) {
this.options = options;
this.registerCount = registerCount; this.registerCount = registerCount;
this.parameterRegisterCount = parameterRegisterCount; this.parameterRegisterCount = parameterRegisterCount;
} }
@ -55,7 +58,7 @@ public class RegisterFormatter {
* @param lastRegister the last register in the range * @param lastRegister the last register in the range
*/ */
public void writeRegisterRange(IndentingWriter writer, int startRegister, int lastRegister) throws IOException { public void writeRegisterRange(IndentingWriter writer, int startRegister, int lastRegister) throws IOException {
if (!baksmali.noParameterRegisters) { if (!options.noParameterRegisters) {
assert startRegister <= lastRegister; assert startRegister <= lastRegister;
if (startRegister >= registerCount - parameterRegisterCount) { if (startRegister >= registerCount - parameterRegisterCount) {
@ -83,7 +86,7 @@ public class RegisterFormatter {
* @param register the register number * @param register the register number
*/ */
public void writeTo(IndentingWriter writer, int register) throws IOException { public void writeTo(IndentingWriter writer, int register) throws IOException {
if (!baksmali.noParameterRegisters) { if (!options.noParameterRegisters) {
if (register >= registerCount - parameterRegisterCount) { if (register >= registerCount - parameterRegisterCount) {
writer.write('p'); writer.write('p');
writer.printSignedIntAsDec((register - (registerCount - parameterRegisterCount))); writer.printSignedIntAsDec((register - (registerCount - parameterRegisterCount)));

View File

@ -33,7 +33,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import org.jf.baksmali.Adaptors.ClassDefinition; import org.jf.baksmali.Adaptors.ClassDefinition;
import org.jf.dexlib2.analysis.ClassPath; import org.jf.dexlib2.analysis.ClassPath;
import org.jf.dexlib2.analysis.InlineMethodResolver;
import org.jf.dexlib2.iface.ClassDef; import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.DexFile; import org.jf.dexlib2.iface.DexFile;
import org.jf.dexlib2.util.SyntheticAccessorResolver; import org.jf.dexlib2.util.SyntheticAccessorResolver;
@ -46,20 +45,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class baksmali { public class baksmali {
public static boolean noParameterRegisters = false;
public static boolean useLocalsDirective = false;
public static boolean useSequentialLabels = false;
public static boolean outputDebugInfo = true;
public static boolean addCodeOffsets = false;
public static boolean noAccessorComments = false;
public static boolean deodex = false;
public static InlineMethodResolver inlineResolver = null;
public static int registerInfo = 0;
public static String bootClassPath;
public static ClassPath classPath = null;
public static SyntheticAccessorResolver syntheticAccessorResolver = null;
public static void disassembleDexFile(String dexFilePath, DexFile dexFile, boolean deodex, String outputDirectory, public static void disassembleDexFile(String dexFilePath, DexFile dexFile, boolean deodex, String outputDirectory,
String[] classPathDirs, String bootClassPath, String extraBootClassPath, String[] classPathDirs, String bootClassPath, String extraBootClassPath,
boolean noParameterRegisters, boolean useLocalsDirective, boolean noParameterRegisters, boolean useLocalsDirective,
@ -67,15 +52,17 @@ public class baksmali {
boolean noAccessorComments, int registerInfo, boolean ignoreErrors, boolean noAccessorComments, int registerInfo, boolean ignoreErrors,
String inlineTable, boolean checkPackagePrivateAccess) String inlineTable, boolean checkPackagePrivateAccess)
{ {
baksmali.noParameterRegisters = noParameterRegisters; baksmaliOptions options = new baksmaliOptions();
baksmali.useLocalsDirective = useLocalsDirective;
baksmali.useSequentialLabels = useSequentialLabels; options.noParameterRegisters = noParameterRegisters;
baksmali.outputDebugInfo = outputDebugInfo; options.useLocalsDirective = useLocalsDirective;
baksmali.addCodeOffsets = addCodeOffsets; options.useSequentialLabels = useSequentialLabels;
baksmali.noAccessorComments = noAccessorComments; options.outputDebugInfo = outputDebugInfo;
baksmali.deodex = deodex; options.addCodeOffsets = addCodeOffsets;
baksmali.registerInfo = registerInfo; options.noAccessorComments = noAccessorComments;
baksmali.bootClassPath = bootClassPath; options.deodex = deodex;
options.registerInfo = registerInfo;
options.bootClassPath = bootClassPath;
if (registerInfo != 0 || deodex) { if (registerInfo != 0 || deodex) {
try { try {
@ -92,7 +79,7 @@ public class baksmali {
bootClassPaths = Splitter.on(':').split(bootClassPath); bootClassPaths = Splitter.on(':').split(bootClassPath);
} }
classPath = ClassPath.fromClassPath(Arrays.asList(classPathDirs), options.classPath = ClassPath.fromClassPath(Arrays.asList(classPathDirs),
Iterables.concat(bootClassPaths, extraBootClassPaths), dexFile); Iterables.concat(bootClassPaths, extraBootClassPaths), dexFile);
// TODO: uncomment // TODO: uncomment
@ -127,7 +114,7 @@ public class baksmali {
classDefs = ImmutableList.copyOf(classDefs); classDefs = ImmutableList.copyOf(classDefs);
if (!noAccessorComments) { if (!noAccessorComments) {
syntheticAccessorResolver = new SyntheticAccessorResolver(classDefs); options.syntheticAccessorResolver = new SyntheticAccessorResolver(classDefs);
} }
ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDirectoryFile, ".smali"); ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDirectoryFile, ".smali");
@ -153,7 +140,7 @@ public class baksmali {
File smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor); File smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor);
//create and initialize the top level string template //create and initialize the top level string template
ClassDefinition classDefinition = new ClassDefinition(classDef); ClassDefinition classDefinition = new ClassDefinition(options, classDef);
//write the disassembly //write the disassembly
Writer writer = null; Writer writer = null;

View File

@ -0,0 +1,61 @@
/*
* Copyright 2013, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali;
import org.jf.dexlib2.analysis.ClassPath;
import org.jf.dexlib2.analysis.InlineMethodResolver;
import org.jf.dexlib2.util.SyntheticAccessorResolver;
public class baksmaliOptions {
// register info values
public static final int ALL = 1;
public static final int ALLPRE = 2;
public static final int ALLPOST = 4;
public static final int ARGS = 8;
public static final int DEST = 16;
public static final int MERGE = 32;
public static final int FULLMERGE = 64;
public boolean noParameterRegisters = false;
public boolean useLocalsDirective = false;
public boolean useSequentialLabels = false;
public boolean outputDebugInfo = true;
public boolean addCodeOffsets = false;
public boolean noAccessorComments = false;
public boolean deodex = false;
public InlineMethodResolver inlineResolver = null;
public int registerInfo = 0;
public String bootClassPath;
public ClassPath classPath = null;
public SyntheticAccessorResolver syntheticAccessorResolver = null;
}

View File

@ -51,14 +51,6 @@ public class main {
private static final Options debugOptions; private static final Options debugOptions;
private static final Options options; private static final Options options;
public static final int ALL = 1;
public static final int ALLPRE = 2;
public static final int ALLPOST = 4;
public static final int ARGS = 8;
public static final int DEST = 16;
public static final int MERGE = 32;
public static final int FULLMERGE = 64;
static { static {
options = new Options(); options = new Options();
basicOptions = new Options(); basicOptions = new Options();
@ -170,31 +162,31 @@ public class main {
String[] values = commandLine.getOptionValues('r'); String[] values = commandLine.getOptionValues('r');
if (values == null || values.length == 0) { if (values == null || values.length == 0) {
registerInfo = ARGS | DEST; registerInfo = baksmaliOptions.ARGS | baksmaliOptions.DEST;
} else { } else {
for (String value: values) { for (String value: values) {
if (value.equalsIgnoreCase("ALL")) { if (value.equalsIgnoreCase("ALL")) {
registerInfo |= ALL; registerInfo |= baksmaliOptions.ALL;
} else if (value.equalsIgnoreCase("ALLPRE")) { } else if (value.equalsIgnoreCase("ALLPRE")) {
registerInfo |= ALLPRE; registerInfo |= baksmaliOptions.ALLPRE;
} else if (value.equalsIgnoreCase("ALLPOST")) { } else if (value.equalsIgnoreCase("ALLPOST")) {
registerInfo |= ALLPOST; registerInfo |= baksmaliOptions.ALLPOST;
} else if (value.equalsIgnoreCase("ARGS")) { } else if (value.equalsIgnoreCase("ARGS")) {
registerInfo |= ARGS; registerInfo |= baksmaliOptions.ARGS;
} else if (value.equalsIgnoreCase("DEST")) { } else if (value.equalsIgnoreCase("DEST")) {
registerInfo |= DEST; registerInfo |= baksmaliOptions.DEST;
} else if (value.equalsIgnoreCase("MERGE")) { } else if (value.equalsIgnoreCase("MERGE")) {
registerInfo |= MERGE; registerInfo |= baksmaliOptions.MERGE;
} else if (value.equalsIgnoreCase("FULLMERGE")) { } else if (value.equalsIgnoreCase("FULLMERGE")) {
registerInfo |= FULLMERGE; registerInfo |= baksmaliOptions.FULLMERGE;
} else { } else {
usage(); usage();
return; return;
} }
} }
if ((registerInfo & FULLMERGE) != 0) { if ((registerInfo & baksmaliOptions.FULLMERGE) != 0) {
registerInfo &= ~MERGE; registerInfo &= ~baksmaliOptions.MERGE;
} }
} }
break; break;