Refactoring baksmali so that the template attributes are passed in, instead of relying on reflection to get attributes from an object

git-svn-id: https://smali.googlecode.com/svn/trunk@366 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2009-08-06 05:03:52 +00:00
parent cc8c2cee0b
commit 7ab77bc90b
43 changed files with 713 additions and 721 deletions

View File

@ -31,27 +31,21 @@ package org.jf.baksmali.Adaptors;
import org.jf.dexlib.AnnotationItem;
import org.jf.baksmali.Adaptors.EncodedValue.AnnotationEncodedValueAdaptor;
import org.jf.baksmali.Adaptors.Reference.TypeReference;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
import java.util.List;
public class AnnotationAdaptor {
private AnnotationItem annotationItem;
private AnnotationEncodedValueAdaptor encodedAnnotationAdaptor;
public static StringTemplate makeTemplate(StringTemplateGroup stg, AnnotationItem annotationItem) {
StringTemplate template = stg.getInstanceOf("annotation");
public AnnotationAdaptor(AnnotationItem annotationItem) {
this.annotationItem = annotationItem;
this.encodedAnnotationAdaptor = new AnnotationEncodedValueAdaptor(annotationItem.getEncodedAnnotation());
}
AnnotationEncodedValueAdaptor aeva = new AnnotationEncodedValueAdaptor(annotationItem.getEncodedAnnotation());
public String getVisibility() {
return annotationItem.getVisibility().name().toLowerCase();
}
template.setAttribute("Visibility", annotationItem.getVisibility().name().toLowerCase());
template.setAttribute("AnnotationType", aeva.getAnnotationType());
template.setAttribute("Elements", aeva.getElements());
public TypeReference getAnnotationType() {
return encodedAnnotationAdaptor.getAnnotationType();
}
public List<AnnotationEncodedValueAdaptor.AnnotationElementAdaptor> getElements() {
return encodedAnnotationAdaptor.getElements();
return template;
}
}

View File

@ -28,17 +28,27 @@
package org.jf.baksmali.Adaptors;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
//a "spacer" between instructions
public class BlankMethodItem extends MethodItem {
public BlankMethodItem(int offset) {
private static StringTemplate template;
public BlankMethodItem(StringTemplateGroup stg, int offset) {
super(offset);
if (template == null) {
template = stg.getInstanceOf("Blank");
}
}
public String getTemplate() {
return "Blank";
}
public int getSortOrder() {
return Integer.MAX_VALUE;
}
@Override
public String toString() {
return template.toString();
}
}

View File

@ -30,43 +30,44 @@ package org.jf.baksmali.Adaptors;
import org.jf.dexlib.TypeIdItem;
import org.jf.baksmali.Adaptors.Reference.TypeReference;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class CatchMethodItem extends MethodItem {
private TypeIdItem exceptionType;
private int startAddress;
private int endAddress;
private int handlerAddress;
private final StringTemplateGroup stg;
private final TypeIdItem exceptionType;
private final int startAddress;
private final int endAddress;
private final int handlerAddress;
public CatchMethodItem(int offset, TypeIdItem exceptionType, int startAddress, int endAddress, int handlerAddress) {
public CatchMethodItem(int offset, StringTemplateGroup stg, TypeIdItem exceptionType, int startAddress,
int endAddress, int handlerAddress) {
super(offset);
this.stg = stg;
this.exceptionType = exceptionType;
this.startAddress = startAddress;
this.endAddress = endAddress;
this.handlerAddress = handlerAddress;
}
public String getTemplate() {
return "Catch";
}
public int getSortOrder() {
//sort after instruction and end_try label
return 102;
}
public TypeReference getExceptionType() {
return new TypeReference(exceptionType);
protected String getTemplateName() {
return "Catch";
}
public int getStartAddress() {
return startAddress;
@Override
public String toString() {
StringTemplate template = stg.getInstanceOf(getTemplateName());
if (exceptionType != null) {
template.setAttribute("ExceptionType", new TypeReference(exceptionType));
}
public int getEndAddress() {
return endAddress;
}
public int getHandlerAddress() {
return handlerAddress;
template.setAttribute("StartAddress", Integer.toHexString(startAddress));
template.setAttribute("EndAddress", Integer.toHexString(endAddress));
template.setAttribute("HandlerAddress", Integer.toHexString(handlerAddress));
return template.toString();
}
}

View File

@ -31,10 +31,13 @@ package org.jf.baksmali.Adaptors;
import org.jf.dexlib.EncodedValue.EncodedValue;
import org.jf.dexlib.*;
import org.jf.dexlib.Util.AccessFlags;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import java.util.*;
public class ClassDefinition {
private StringTemplateGroup stg;
private ClassDefItem classDefItem;
private ClassDataItem classDataItem;
@ -42,7 +45,8 @@ public class ClassDefinition {
private HashMap<Integer, AnnotationSetItem> fieldAnnotationsMap = new HashMap<Integer, AnnotationSetItem>();
private HashMap<Integer, AnnotationSetRefList> parameterAnnotationsMap = new HashMap<Integer, AnnotationSetRefList>();
public ClassDefinition(ClassDefItem classDefItem) {
public ClassDefinition(StringTemplateGroup stg, ClassDefItem classDefItem) {
this.stg = stg;
this.classDefItem = classDefItem;
this.classDataItem = classDefItem.getClassData();
buildAnnotationMaps();
@ -119,11 +123,20 @@ public class ClassDefinition {
return interfaces;
}
public List<FieldDefinition> getStaticFields() {
List<FieldDefinition> staticFields = new ArrayList<FieldDefinition>();
public String getHasStaticFields() {
if (classDataItem != null) {
ClassDataItem.EncodedField fields[] = classDataItem.getStaticFields();
if (fields != null && fields.length > 0) {
return "true";
}
}
return null;
}
public List<StringTemplate> getStaticFields() {
List<StringTemplate> staticFields = new ArrayList<StringTemplate>();
if (classDataItem != null) {
EncodedArrayItem encodedStaticInitializers = classDefItem.getStaticFieldInitializers();
EncodedValue[] staticInitializers;
@ -140,55 +153,86 @@ public class ClassDefinition {
encodedValue = staticInitializers[i];
}
AnnotationSetItem annotationSet = fieldAnnotationsMap.get(field.field.getIndex());
staticFields.add(new FieldDefinition(field, encodedValue, annotationSet));
staticFields.add(FieldDefinition.createTemplate(stg, field, encodedValue, annotationSet));
i++;
}
}
return staticFields;
}
public List<FieldDefinition> getInstanceFields() {
List<FieldDefinition> instanceFields = new ArrayList<FieldDefinition>();
public String getHasInstanceFields() {
if (classDataItem != null) {
ClassDataItem.EncodedField fields[] = classDataItem.getInstanceFields();
if (fields != null && fields.length > 0) {
return "true";
}
}
return null;
}
public List<StringTemplate> getInstanceFields() {
List<StringTemplate> instanceFields = new ArrayList<StringTemplate>();
if (classDataItem != null) {
for (ClassDataItem.EncodedField field: classDataItem.getInstanceFields()) {
AnnotationSetItem annotationSet = fieldAnnotationsMap.get(field.field.getIndex());
instanceFields.add(new FieldDefinition(field, annotationSet));
instanceFields.add(FieldDefinition.createTemplate(stg, field, annotationSet));
}
}
return instanceFields;
}
public List<MethodDefinition> getDirectMethods() {
List<MethodDefinition> directMethods = new ArrayList<MethodDefinition>();
public String getHasDirectMethods() {
if (classDataItem != null) {
ClassDataItem.EncodedMethod[] methods = classDataItem.getDirectMethods();
if (methods != null && methods.length > 0) {
return "true";
}
}
return null;
}
public List<StringTemplate> getDirectMethods() {
List<StringTemplate> directMethods = new ArrayList<StringTemplate>();
if (classDataItem != null) {
for (ClassDataItem.EncodedMethod method: classDataItem.getDirectMethods()) {
AnnotationSetItem annotationSet = methodAnnotationsMap.get(method.method.getIndex());
AnnotationSetRefList parameterAnnotationList = parameterAnnotationsMap.get(method.method.getIndex());
directMethods.add(new MethodDefinition(method, annotationSet, parameterAnnotationList));
directMethods.add(MethodDefinition.makeTemplate(stg, method, annotationSet, parameterAnnotationList));
}
}
return directMethods;
}
public List<MethodDefinition> getVirtualMethods() {
List<MethodDefinition> virtualMethods = new ArrayList<MethodDefinition>();
public String getHasVirtualMethods() {
if (classDataItem != null) {
ClassDataItem.EncodedMethod[] methods = classDataItem.getVirtualMethods();
if (methods != null && methods.length > 0) {
return "true";
}
}
return null;
}
public List<StringTemplate> getVirtualMethods() {
List<StringTemplate> virtualMethods = new ArrayList<StringTemplate>();
if (classDataItem != null) {
for (ClassDataItem.EncodedMethod method: classDataItem.getVirtualMethods()) {
AnnotationSetItem annotationSet = methodAnnotationsMap.get(method.method.getIndex());
AnnotationSetRefList parameterAnnotationList = parameterAnnotationsMap.get(method.method.getIndex());
virtualMethods.add(new MethodDefinition(method, annotationSet, parameterAnnotationList));
virtualMethods.add(MethodDefinition.makeTemplate(stg, method, annotationSet, parameterAnnotationList));
}
}
return virtualMethods;
}
public List<AnnotationAdaptor> getAnnotations() {
public List<StringTemplate> getAnnotations() {
AnnotationDirectoryItem annotationDirectory = classDefItem.getAnnotations();
if (annotationDirectory == null) {
return null;
@ -199,11 +243,11 @@ public class ClassDefinition {
return null;
}
List<AnnotationAdaptor> annotationAdaptors = new ArrayList<AnnotationAdaptor>();
List<StringTemplate> annotations = new ArrayList<StringTemplate>();
for (AnnotationItem annotationItem: annotationSet.getAnnotations()) {
annotationAdaptors.add(new AnnotationAdaptor(annotationItem));
annotations.add(AnnotationAdaptor.makeTemplate(stg, annotationItem));
}
return annotationAdaptors;
return annotations;
}
}

View File

@ -28,21 +28,33 @@
package org.jf.baksmali.Adaptors;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class DebugMethodItem extends MethodItem {
private final String template;
private final StringTemplateGroup stg;
private final String templateName;
private final int sortOrder;
public DebugMethodItem(int offset, String template, int sortOrder) {
public DebugMethodItem(int offset, StringTemplateGroup stg, String templateName, int sortOrder) {
super(offset);
this.template = template;
this.stg = stg;
this.templateName = templateName;
this.sortOrder = sortOrder;
}
public String getTemplate() {
return template;
}
public int getSortOrder() {
return sortOrder;
}
@Override
public String toString() {
StringTemplate template = stg.getInstanceOf(templateName);
setAttributes(template);
return template.toString();
}
protected void setAttributes(StringTemplate template)
{
}
}

View File

@ -28,11 +28,13 @@
package org.jf.baksmali.Adaptors;
import org.antlr.stringtemplate.StringTemplateGroup;
public class EndTryLabelMethodItem extends LabelMethodItem {
private int labelOffset;
public EndTryLabelMethodItem(int offset, int labelOffset) {
super(offset, "try_end_");
public EndTryLabelMethodItem(int offset, StringTemplateGroup stg, int labelOffset) {
super(offset, stg, "try_end_");
this.labelOffset = labelOffset;
}
@ -41,11 +43,7 @@ public class EndTryLabelMethodItem extends LabelMethodItem {
return 101;
}
public String getTemplate() {
return "EndTryLabel";
}
public int getLabelOffset() {
return labelOffset;
public String getLabelOffset() {
return Integer.toHexString(labelOffset);
}
}

View File

@ -31,77 +31,56 @@ package org.jf.baksmali.Adaptors;
import org.jf.baksmali.Adaptors.EncodedValue.EncodedValueAdaptor;
import org.jf.dexlib.ClassDataItem;
import org.jf.dexlib.EncodedValue.EncodedValue;
import org.jf.dexlib.FieldIdItem;
import org.jf.dexlib.AnnotationSetItem;
import org.jf.dexlib.AnnotationItem;
import org.jf.dexlib.Util.AccessFlags;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import java.util.ArrayList;
import java.util.List;
public class FieldDefinition {
private ClassDataItem.EncodedField encodedField;
private FieldIdItem fieldIdItem;
private EncodedValue initialValue;
private AnnotationSetItem annotationSet;
public static StringTemplate createTemplate(StringTemplateGroup stg, ClassDataItem.EncodedField encodedField,
EncodedValue initialValue, AnnotationSetItem annotationSet) {
StringTemplate template = stg.getInstanceOf("field");
public FieldDefinition(ClassDataItem.EncodedField encodedField, AnnotationSetItem annotationSet) {
this(encodedField, null, annotationSet);
template.setAttribute("AccessFlags", getAccessFlags(encodedField));
template.setAttribute("FieldName", encodedField.field.getFieldName().getStringValue());
template.setAttribute("FieldType", encodedField.field.getFieldType().getTypeDescriptor());
template.setAttribute("Annotations", getAnnotations(stg, annotationSet));
if (initialValue != null) {
template.setAttribute("InitialValue", EncodedValueAdaptor.make(initialValue));
}
public FieldDefinition(ClassDataItem.EncodedField encodedField, EncodedValue initialValue,
return template;
}
public static StringTemplate createTemplate(StringTemplateGroup stg, ClassDataItem.EncodedField encodedField,
AnnotationSetItem annotationSet) {
this.encodedField = encodedField;
this.fieldIdItem = encodedField.field;
this.initialValue = initialValue;
this.annotationSet = annotationSet;
return createTemplate(stg, encodedField, null, annotationSet);
}
private List<String> accessFlags = null;
public List<String> getAccessFlags() {
if (accessFlags == null) {
accessFlags = new ArrayList<String>();
private static List<String> getAccessFlags(ClassDataItem.EncodedField encodedField) {
List<String> accessFlags = new ArrayList<String>();
for (AccessFlags accessFlag: AccessFlags.getAccessFlagsForField(encodedField.accessFlags)) {
accessFlags.add(accessFlag.toString());
}
}
return accessFlags;
}
private String fieldName = null;
public String getFieldName() {
if (fieldName == null) {
fieldName = fieldIdItem.getFieldName().getStringValue();
}
return fieldName;
}
private String fieldType = null;
public String getFieldType() {
if (fieldType == null) {
fieldType = fieldIdItem.getFieldType().getTypeDescriptor();
}
return fieldType;
}
private EncodedValueAdaptor encodedValueAdaptor = null;
public EncodedValueAdaptor getInitialValue() {
if (encodedValueAdaptor == null && initialValue != null) {
encodedValueAdaptor = EncodedValueAdaptor.make(initialValue);
}
return encodedValueAdaptor;
}
public List<AnnotationAdaptor> getAnnotations() {
private static List<StringTemplate> getAnnotations(StringTemplateGroup stg, AnnotationSetItem annotationSet) {
if (annotationSet == null) {
return null;
}
List<AnnotationAdaptor> annotationAdaptors = new ArrayList<AnnotationAdaptor>();
List<StringTemplate> annotationAdaptors = new ArrayList<StringTemplate>();
for (AnnotationItem annotationItem: annotationSet.getAnnotations()) {
annotationAdaptors.add(new AnnotationAdaptor(annotationItem));
annotationAdaptors.add(AnnotationAdaptor.makeTemplate(stg, annotationItem));
}
return annotationAdaptors;
}

View File

@ -30,6 +30,8 @@ package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.ArrayDataPseudoInstruction;
import org.jf.dexlib.Util.ByteArray;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
import java.util.ArrayList;
import java.util.List;
@ -37,33 +39,27 @@ import java.util.Iterator;
import java.util.Arrays;
public class ArrayDataMethodItem extends InstructionFormatMethodItem<ArrayDataPseudoInstruction> {
public ArrayDataMethodItem(int offset, ArrayDataPseudoInstruction instruction) {
super(offset, instruction);
public ArrayDataMethodItem(int offset, StringTemplateGroup stg, ArrayDataPseudoInstruction instruction) {
super(offset, stg, instruction);
}
public int getElementWidth() {
return instruction.getElementWidth();
protected void setAttributes(StringTemplate template) {
template.setAttribute("ElementWidth", instruction.getElementWidth());
template.setAttribute("Values", getValues());
}
public Iterator<ByteArray> getValues() {
return new Iterator<ByteArray>() {
int position;
final Iterator<ArrayDataPseudoInstruction.ArrayElement> iterator = instruction.getElements();
private List<ByteArray> getValues() {
List<ByteArray> values = new ArrayList<ByteArray>();
Iterator<ArrayDataPseudoInstruction.ArrayElement> iterator = instruction.getElements();
public boolean hasNext() {
return iterator.hasNext();
}
public ByteArray next() {
while (iterator.hasNext()) {
ArrayDataPseudoInstruction.ArrayElement element = iterator.next();
byte[] array = new byte[element.elementWidth];
System.arraycopy(element.buffer, element.bufferIndex, array, 0, element.elementWidth);
return new ByteArray(array);
values.add(new ByteArray(array));
}
public void remove() {
}
};
return values;
}
public static class ByteArray

View File

@ -29,13 +29,15 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction10t;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction10tMethodItem extends InstructionFormatMethodItem<Instruction10t> {
public Instruction10tMethodItem(int offset, Instruction10t instruction) {
super(offset, instruction);
public Instruction10tMethodItem(int offset, StringTemplateGroup stg, Instruction10t instruction) {
super(offset, stg, instruction);
}
public String getTarget() {
return Integer.toHexString(getOffset() + instruction.getOffset());
protected void setAttributes(StringTemplate template) {
template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset()));
}
}

View File

@ -29,9 +29,14 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction10x;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction10xMethodItem extends InstructionFormatMethodItem<Instruction10x> {
public Instruction10xMethodItem(int offset, Instruction10x instruction) {
super(offset, instruction);
public Instruction10xMethodItem(int offset, StringTemplateGroup stg, Instruction10x instruction) {
super(offset, stg, instruction);
}
protected void setAttributes(StringTemplate template) {
}
}

View File

@ -29,17 +29,16 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction11n;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction11nMethodItem extends InstructionFormatMethodItem<Instruction11n> {
public Instruction11nMethodItem(int offset, Instruction11n instruction) {
super(offset, instruction);
public Instruction11nMethodItem(int offset, StringTemplateGroup stg, Instruction11n instruction) {
super(offset, stg, instruction);
}
public int getRegister() {
return instruction.getRegister();
}
public int getLiteral() {
return instruction.getLiteral();
protected void setAttributes(StringTemplate template) {
template.setAttribute("Register", instruction.getRegister());
template.setAttribute("Literal", instruction.getLiteral());
}
}

View File

@ -29,14 +29,16 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction11x;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction11xMethodItem extends InstructionFormatMethodItem<Instruction11x> {
public Instruction11xMethodItem(int offset, Instruction11x instruction) {
super(offset, instruction);
public Instruction11xMethodItem(int offset, StringTemplateGroup stg, Instruction11x instruction) {
super(offset, stg, instruction);
}
public int getRegister() {
return instruction.getRegister();
protected void setAttributes(StringTemplate template) {
template.setAttribute("Register", instruction.getRegister());
}
}

View File

@ -29,17 +29,16 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction12x;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction12xMethodItem extends InstructionFormatMethodItem<Instruction12x> {
public Instruction12xMethodItem(int offset, Instruction12x instruction) {
super(offset, instruction);
public Instruction12xMethodItem(int offset, StringTemplateGroup stg, Instruction12x instruction) {
super(offset, stg, instruction);
}
public int getRegisterA() {
return instruction.getRegisterA();
}
public int getRegisterB() {
return instruction.getRegisterB();
protected void setAttributes(StringTemplate template) {
template.setAttribute("RegisterA", instruction.getRegisterA());
template.setAttribute("RegisterB", instruction.getRegisterB());
}
}

View File

@ -29,13 +29,15 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction20t;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction20tMethodItem extends InstructionFormatMethodItem<Instruction20t> {
public Instruction20tMethodItem(int offset, Instruction20t instruction) {
super(offset, instruction);
public Instruction20tMethodItem(int offset, StringTemplateGroup stg, Instruction20t instruction) {
super(offset, stg, instruction);
}
public String getTarget() {
return Integer.toHexString(getOffset() + instruction.getOffset());
protected void setAttributes(StringTemplate template) {
template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset()));
}
}

View File

@ -29,13 +29,17 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction21c;
import org.jf.baksmali.Adaptors.Reference.Reference;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction21cMethodItem extends ReferenceInstructionFormatMethodItem<Instruction21c> {
public Instruction21cMethodItem(int offset, Instruction21c instruction) {
super(offset, instruction);
public class Instruction21cMethodItem extends InstructionFormatMethodItem<Instruction21c> {
public Instruction21cMethodItem(int offset, StringTemplateGroup stg, Instruction21c instruction) {
super(offset, stg, instruction);
}
public int getRegister() {
return instruction.getRegister();
protected void setAttributes(StringTemplate template) {
template.setAttribute("Reference", Reference.makeReference(instruction.getReferencedItem()));
template.setAttribute("Register", instruction.getRegister());
}
}

View File

@ -29,17 +29,16 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction21h;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction21hMethodItem extends InstructionFormatMethodItem<Instruction21h> {
public Instruction21hMethodItem(int offset, Instruction21h instruction) {
super(offset, instruction);
public Instruction21hMethodItem(int offset, StringTemplateGroup stg, Instruction21h instruction) {
super(offset, stg, instruction);
}
public int getRegister() {
return instruction.getRegister();
}
public int getLiteral() {
return instruction.getLiteral();
protected void setAttributes(StringTemplate template) {
template.setAttribute("Register", instruction.getRegister());
template.setAttribute("Literal", instruction.getLiteral());
}
}

View File

@ -29,17 +29,16 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction21s;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction21sMethodItem extends InstructionFormatMethodItem<Instruction21s> {
public Instruction21sMethodItem(int offset, Instruction21s instruction) {
super(offset, instruction);
public Instruction21sMethodItem(int offset, StringTemplateGroup stg, Instruction21s instruction) {
super(offset, stg, instruction);
}
public int getRegister() {
return instruction.getRegister();
}
public int getLiteral() {
return instruction.getLiteral();
protected void setAttributes(StringTemplate template) {
template.setAttribute("Register", instruction.getRegister());
template.setAttribute("Literal", instruction.getLiteral());
}
}

View File

@ -29,17 +29,16 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction21t;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction21tMethodItem extends InstructionFormatMethodItem<Instruction21t> {
public Instruction21tMethodItem(int offset, Instruction21t instruction) {
super(offset, instruction);
public Instruction21tMethodItem(int offset, StringTemplateGroup stg, Instruction21t instruction) {
super(offset, stg,instruction);
}
public int getRegister() {
return instruction.getRegister();
}
public String getTarget() {
return Integer.toHexString(getOffset() + instruction.getOffset());
protected void setAttributes(StringTemplate template) {
template.setAttribute("Register", instruction.getRegister());
template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset()));
}
}

View File

@ -29,21 +29,17 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction22b;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction22bMethodItem extends InstructionFormatMethodItem<Instruction22b> {
public Instruction22bMethodItem(int offset, Instruction22b instruction) {
super(offset, instruction);
public Instruction22bMethodItem(int offset, StringTemplateGroup stg, Instruction22b instruction) {
super(offset, stg, instruction);
}
public int getRegisterA() {
return instruction.getRegisterA();
}
public int getRegisterB() {
return instruction.getRegisterB();
}
public int getLiteral() {
return instruction.getLiteral();
protected void setAttributes(StringTemplate template) {
template.setAttribute("RegisterA", instruction.getRegisterA());
template.setAttribute("RegisterB", instruction.getRegisterB());
template.setAttribute("Literal", instruction.getLiteral());
}
}

View File

@ -29,17 +29,18 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction22c;
import org.jf.baksmali.Adaptors.Reference.Reference;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction22cMethodItem extends ReferenceInstructionFormatMethodItem<Instruction22c> {
public Instruction22cMethodItem(int offset, Instruction22c instruction) {
super(offset, instruction);
public class Instruction22cMethodItem extends InstructionFormatMethodItem<Instruction22c> {
public Instruction22cMethodItem(int offset, StringTemplateGroup stg, Instruction22c instruction) {
super(offset, stg, instruction);
}
public int getRegisterA() {
return instruction.getRegisterA();
}
public int getRegisterB() {
return instruction.getRegisterB();
protected void setAttributes(StringTemplate template) {
template.setAttribute("Reference", Reference.makeReference(instruction.getReferencedItem()));
template.setAttribute("RegisterA", instruction.getRegisterA());
template.setAttribute("RegisterB", instruction.getRegisterB());
}
}

View File

@ -29,21 +29,17 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction22s;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction22sMethodItem extends InstructionFormatMethodItem<Instruction22s> {
public Instruction22sMethodItem(int offset, Instruction22s instruction) {
super(offset, instruction);
public Instruction22sMethodItem(int offset, StringTemplateGroup stg, Instruction22s instruction) {
super(offset, stg, instruction);
}
public int getRegisterA() {
return instruction.getRegisterA();
}
public int getRegisterB() {
return instruction.getRegisterB();
}
public int getLiteral() {
return instruction.getLiteral();
protected void setAttributes(StringTemplate template) {
template.setAttribute("RegisterA", instruction.getRegisterA());
template.setAttribute("RegisterB", instruction.getRegisterB());
template.setAttribute("Literal", instruction.getLiteral());
}
}

View File

@ -29,21 +29,17 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction22t;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction22tMethodItem extends InstructionFormatMethodItem<Instruction22t> {
public Instruction22tMethodItem(int offset, Instruction22t instruction) {
super(offset, instruction);
public Instruction22tMethodItem(int offset, StringTemplateGroup stg, Instruction22t instruction) {
super(offset, stg, instruction);
}
public int getRegisterA() {
return instruction.getRegisterA();
}
public int getRegisterB() {
return instruction.getRegisterB();
}
public String getTarget() {
return Integer.toHexString(getOffset() + instruction.getOffset());
protected void setAttributes(StringTemplate template) {
template.setAttribute("RegisterA", instruction.getRegisterA());
template.setAttribute("RegisterB", instruction.getRegisterB());
template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset()));
}
}

View File

@ -29,17 +29,16 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction22x;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction22xMethodItem extends InstructionFormatMethodItem<Instruction22x> {
public Instruction22xMethodItem(int offset, Instruction22x instruction) {
super(offset, instruction);
public Instruction22xMethodItem(int offset, StringTemplateGroup stg, Instruction22x instruction) {
super(offset, stg, instruction);
}
public int getRegisterA() {
return instruction.getRegisterA();
}
public int getRegisterB() {
return instruction.getRegisterB();
protected void setAttributes(StringTemplate template) {
template.setAttribute("RegisterA", instruction.getRegisterA());
template.setAttribute("RegisterB", instruction.getRegisterB());
}
}

View File

@ -29,21 +29,17 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction23x;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction23xMethodItem extends InstructionFormatMethodItem<Instruction23x> {
public Instruction23xMethodItem(int offset, Instruction23x instruction) {
super(offset, instruction);
public Instruction23xMethodItem(int offset, StringTemplateGroup stg, Instruction23x instruction) {
super(offset, stg, instruction);
}
public int getRegisterA() {
return instruction.getRegisterA();
}
public int getRegisterB() {
return instruction.getRegisterB();
}
public int getRegisterC() {
return instruction.getRegisterC();
protected void setAttributes(StringTemplate template) {
template.setAttribute("RegisterA", instruction.getRegisterA());
template.setAttribute("RegisterB", instruction.getRegisterB());
template.setAttribute("RegisterC", instruction.getRegisterC());
}
}

View File

@ -29,13 +29,15 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction30t;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction30tMethodItem extends InstructionFormatMethodItem<Instruction30t> {
public Instruction30tMethodItem(int offset, Instruction30t instruction) {
super(offset, instruction);
public Instruction30tMethodItem(int offset, StringTemplateGroup stg, Instruction30t instruction) {
super(offset, stg, instruction);
}
public String getTarget() {
return Integer.toHexString(getOffset() + instruction.getOffset());
protected void setAttributes(StringTemplate template) {
template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset()));
}
}

View File

@ -29,13 +29,17 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction31c;
import org.jf.baksmali.Adaptors.Reference.Reference;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
public class Instruction31cMethodItem extends ReferenceInstructionFormatMethodItem<Instruction31c> {
public Instruction31cMethodItem(int offset, Instruction31c instruction) {
super(offset, instruction);
public class Instruction31cMethodItem extends InstructionFormatMethodItem<Instruction31c> {
public Instruction31cMethodItem(int offset, StringTemplateGroup stg, Instruction31c instruction) {
super(offset, stg, instruction);
}
public int getRegister() {
return instruction.getRegister();
protected void setAttributes(StringTemplate template) {
template.setAttribute("Reference", Reference.makeReference(instruction.getReferencedItem()));
template.setAttribute("Register", instruction.getRegister());
}
}

View File

@ -29,17 +29,16 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction31i;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction31iMethodItem extends InstructionFormatMethodItem<Instruction31i> {
public Instruction31iMethodItem(int offset, Instruction31i instruction) {
super(offset, instruction);
public Instruction31iMethodItem(int offset, StringTemplateGroup stg, Instruction31i instruction) {
super(offset, stg, instruction);
}
public int getRegister() {
return instruction.getRegister();
}
public int getLiteral() {
return instruction.getLiteral();
protected void setAttributes(StringTemplate template) {
template.setAttribute("Register", instruction.getRegister());
template.setAttribute("Literal", instruction.getLiteral());
}
}

View File

@ -29,17 +29,16 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction31t;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction31tMethodItem extends InstructionFormatMethodItem<Instruction31t> {
public Instruction31tMethodItem(int offset, Instruction31t instruction) {
super(offset, instruction);
public Instruction31tMethodItem(int offset, StringTemplateGroup stg, Instruction31t instruction) {
super(offset, stg, instruction);
}
public int getRegister() {
return instruction.getRegister();
}
public String getTarget() {
return Integer.toHexString(getOffset() + instruction.getOffset());
protected void setAttributes(StringTemplate template) {
template.setAttribute("Register", instruction.getRegister());
template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset()));
}
}

View File

@ -29,17 +29,16 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction32x;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction32xMethodItem extends InstructionFormatMethodItem<Instruction32x> {
public Instruction32xMethodItem(int offset, Instruction32x instruction) {
super(offset, instruction);
public Instruction32xMethodItem(int offset, StringTemplateGroup stg, Instruction32x instruction) {
super(offset, stg, instruction);
}
public int getRegisterA() {
return instruction.getRegisterA();
}
public int getRegisterB() {
return instruction.getRegisterB();
protected void setAttributes(StringTemplate template) {
template.setAttribute("RegisterA", instruction.getRegisterA());
template.setAttribute("RegisterB", instruction.getRegisterB());
}
}

View File

@ -29,13 +29,21 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction35c;
import org.jf.baksmali.Adaptors.Reference.Reference;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction35cMethodItem extends ReferenceInstructionFormatMethodItem<Instruction35c> {
public Instruction35cMethodItem(int offset, Instruction35c instruction) {
super(offset, instruction);
public class Instruction35cMethodItem extends InstructionFormatMethodItem<Instruction35c> {
public Instruction35cMethodItem(int offset, StringTemplateGroup stg, Instruction35c instruction) {
super(offset, stg, instruction);
}
public int[] getRegisters() {
protected void setAttributes(StringTemplate template) {
template.setAttribute("Reference", Reference.makeReference(instruction.getReferencedItem()));
template.setAttribute("Registers", getRegisters());
}
private int[] getRegisters() {
switch (instruction.getRegCount()) {
case 1:
return new int[] {instruction.getRegisterD()};

View File

@ -29,17 +29,18 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction3rc;
import org.jf.baksmali.Adaptors.Reference.Reference;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction3rcMethodItem extends ReferenceInstructionFormatMethodItem<Instruction3rc> {
public Instruction3rcMethodItem(int offset, Instruction3rc instruction) {
super(offset, instruction);
public class Instruction3rcMethodItem extends InstructionFormatMethodItem<Instruction3rc> {
public Instruction3rcMethodItem(int offset, StringTemplateGroup stg, Instruction3rc instruction) {
super(offset, stg, instruction);
}
public int getStartRegister() {
return instruction.getStartRegister();
}
public int getLastRegister() {
return instruction.getStartRegister() + instruction.getRegCount() - 1;
protected void setAttributes(StringTemplate template) {
template.setAttribute("Reference", Reference.makeReference(instruction.getReferencedItem()));
template.setAttribute("StartRegister", instruction.getStartRegister());
template.setAttribute("LastRegister", instruction.getStartRegister() + instruction.getRegCount() - 1);
}
}

View File

@ -29,17 +29,16 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.Instruction51l;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class Instruction51lMethodItem extends InstructionFormatMethodItem<Instruction51l> {
public Instruction51lMethodItem(int offset, Instruction51l instruction) {
super(offset, instruction);
public Instruction51lMethodItem(int offset, StringTemplateGroup stg, Instruction51l instruction) {
super(offset, stg, instruction);
}
public int getRegister() {
return instruction.getRegister();
}
public long getLiteral() {
return instruction.getLiteral();
protected void setAttributes(StringTemplate template) {
template.setAttribute("Register", instruction.getRegister());
template.setAttribute("Literal", instruction.getLiteral());
}
}

View File

@ -31,12 +31,16 @@ package org.jf.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.MethodItem;
import org.jf.baksmali.Adaptors.Reference.Reference;
import org.jf.dexlib.Code.Instruction;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
public abstract class InstructionFormatMethodItem<T extends Instruction> extends MethodItem {
protected T instruction;
private final StringTemplateGroup stg;
protected final T instruction;
public InstructionFormatMethodItem(int offset, T instruction) {
public InstructionFormatMethodItem(int offset, StringTemplateGroup stg, T instruction) {
super(offset);
this.stg = stg;
this.instruction = instruction;
}
@ -52,4 +56,14 @@ public abstract class InstructionFormatMethodItem<T extends Instruction> extends
public String getTemplate() {
return instruction.getFormat().name();
}
@Override
public String toString() {
StringTemplate template = stg.getInstanceOf(instruction.getFormat().name());
template.setAttribute("Opcode", instruction.opcode.name);
setAttributes(template);
return template.toString();
}
protected abstract void setAttributes(StringTemplate template);
}

View File

@ -30,37 +30,36 @@ package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.PackedSwitchDataPseudoInstruction;
import org.jf.dexlib.Code.Format.SparseSwitchDataPseudoInstruction;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
public class PackedSwitchMethodItem extends InstructionFormatMethodItem<PackedSwitchDataPseudoInstruction> {
private int baseAddress;
public PackedSwitchMethodItem(int offset, PackedSwitchDataPseudoInstruction instruction, int baseAddress) {
super(offset, instruction);
public PackedSwitchMethodItem(int offset, StringTemplateGroup stg, PackedSwitchDataPseudoInstruction instruction,
int baseAddress) {
super(offset, stg, instruction);
this.baseAddress = baseAddress;
}
public int getFirstKey() {
return instruction.getFirstKey();
protected void setAttributes(StringTemplate template) {
template.setAttribute("FirstKey", instruction.getFirstKey());
template.setAttribute("Targets", getTargets());
}
public Iterator<String> getTargets() {
return new Iterator<String>() {
private List<String> getTargets() {
List<String> targets = new ArrayList<String>();
Iterator<PackedSwitchDataPseudoInstruction.PackedSwitchTarget> iterator = instruction.getTargets();
public boolean hasNext() {
return iterator.hasNext();
}
public String next() {
while (iterator.hasNext()) {
PackedSwitchDataPseudoInstruction.PackedSwitchTarget target = iterator.next();
return Integer.toHexString(target.target + baseAddress);
targets.add(Integer.toHexString(target.target + baseAddress));
}
public void remove() {
}
};
return targets;
}
}

View File

@ -1,44 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Adaptors.Format;
import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.baksmali.Adaptors.Reference.Reference;
public abstract class ReferenceInstructionFormatMethodItem<T extends InstructionWithReference>
extends InstructionFormatMethodItem<T> {
public ReferenceInstructionFormatMethodItem(int offset, T instruction) {
super(offset, instruction);
}
public Reference getReference() {
return Reference.makeReference(instruction.getReferencedItem());
}
}

View File

@ -29,40 +29,44 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.dexlib.Code.Format.SparseSwitchDataPseudoInstruction;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
public class SparseSwitchMethodItem extends InstructionFormatMethodItem<SparseSwitchDataPseudoInstruction> {
private int baseAddress;
public SparseSwitchMethodItem(int offset, SparseSwitchDataPseudoInstruction instruction, int baseAddress) {
super(offset, instruction);
public SparseSwitchMethodItem(int offset, StringTemplateGroup stg, SparseSwitchDataPseudoInstruction instruction,
int baseAddress) {
super(offset, stg, instruction);
this.baseAddress = baseAddress;
}
protected void setAttributes(StringTemplate template) {
template.setAttribute("Targets", getTargets());
}
private static class SparseSwitchTarget {
public int Value;
public String Target;
}
public Iterator<SparseSwitchTarget> getTargets() {
return new Iterator<SparseSwitchTarget>() {
private List<SparseSwitchTarget> getTargets() {
List<SparseSwitchTarget> targets = new ArrayList<SparseSwitchTarget>();
Iterator<SparseSwitchDataPseudoInstruction.SparseSwitchTarget> iterator = instruction.getTargets();
public boolean hasNext() {
return iterator.hasNext();
}
public SparseSwitchTarget next() {
while (iterator.hasNext()) {
SparseSwitchDataPseudoInstruction.SparseSwitchTarget target = iterator.next();
SparseSwitchTarget sparseSwitchTarget = new SparseSwitchTarget();
sparseSwitchTarget.Value = target.value;
sparseSwitchTarget.Target = Integer.toHexString(target.target + baseAddress);
return sparseSwitchTarget;
targets.add(sparseSwitchTarget);
}
public void remove() {
}
};
return targets;
}
}

View File

@ -28,11 +28,16 @@
package org.jf.baksmali.Adaptors;
public class LabelMethodItem extends MethodItem {
private String labelPrefix;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public LabelMethodItem(int offset, String labelPrefix) {
public class LabelMethodItem extends MethodItem {
private final StringTemplateGroup stg;
private final String labelPrefix;
public LabelMethodItem(int offset, StringTemplateGroup stg, String labelPrefix) {
super(offset);
this.stg = stg;
this.labelPrefix = labelPrefix;
}
@ -51,14 +56,6 @@ public class LabelMethodItem extends MethodItem {
return result;
}
public String getPrefix() {
return labelPrefix;
}
public String getTemplate() {
return "Label";
}
public int hashCode() {
//force it to call equals when two labels are at the same address
return getOffset();
@ -70,4 +67,16 @@ public class LabelMethodItem extends MethodItem {
}
return this.compareTo((MethodItem)o) == 0;
}
@Override
public String toString() {
StringTemplate template = stg.getInstanceOf("Label");
template.setAttribute("Prefix", labelPrefix);
template.setAttribute("HexOffset", getLabelOffset());
return template.toString();
}
public String getLabelOffset() {
return getHexOffset();
}
}

View File

@ -30,19 +30,29 @@ package org.jf.baksmali.Adaptors;
import org.jf.dexlib.TypeIdItem;
import org.jf.dexlib.StringIdItem;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
public class LocalDebugMethodItem extends DebugMethodItem {
public final int Register;
public final String Name;
public final String Type;
public final String Signature;
private final int register;
private final String name;
private final String type;
private final String signature;
public LocalDebugMethodItem(int offset, String template, int sortOrder, int register, StringIdItem name,
TypeIdItem type, StringIdItem signature) {
super(offset, template, sortOrder);
this.Register = register;
this.Name = name==null?null:name.getStringValue();
this.Type = type==null?null:type.getTypeDescriptor();
this.Signature = signature==null?null:signature.getStringValue();
public LocalDebugMethodItem(int offset, StringTemplateGroup stg, String templateName, int sortOrder, int register,
StringIdItem name, TypeIdItem type, StringIdItem signature) {
super(offset, stg, templateName, sortOrder);
this.register = register;
this.name = name==null?null:name.getStringValue();
this.type = type==null?null:type.getTypeDescriptor();
this.signature = signature==null?null:signature.getStringValue();
}
@Override
protected void setAttributes(StringTemplate template) {
template.setAttribute("Register", Integer.toString(register));
template.setAttribute("Name", name);
template.setAttribute("Type", type);
template.setAttribute("Signature", signature);
}
}

View File

@ -36,83 +36,44 @@ import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.InstructionIterator;
import org.jf.dexlib.Util.AccessFlags;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
import java.util.*;
public class MethodDefinition {
private ClassDataItem.EncodedMethod encodedMethod;
private MethodIdItem methodIdItem;
private CodeItem codeItem;
private AnnotationSetItem annotationSet;
private AnnotationSetRefList parameterAnnotations;
public MethodDefinition(ClassDataItem.EncodedMethod encodedMethod, AnnotationSetItem annotationSet,
public static StringTemplate makeTemplate(StringTemplateGroup stg, ClassDataItem.EncodedMethod encodedMethod,
AnnotationSetItem annotationSet,
AnnotationSetRefList parameterAnnotations) {
this.encodedMethod = encodedMethod;
this.methodIdItem = encodedMethod.method;
this.codeItem = encodedMethod.codeItem;
this.annotationSet = annotationSet;
this.parameterAnnotations = parameterAnnotations;
CodeItem codeItem = encodedMethod.codeItem;
StringTemplate template = stg.getInstanceOf("method");
template.setAttribute("AccessFlags", getAccessFlags(encodedMethod));
template.setAttribute("MethodName", encodedMethod.method.getMethodName().getStringValue());
template.setAttribute("Prototype", encodedMethod.method.getPrototype().getPrototypeString());
template.setAttribute("HasCode", codeItem != null);
template.setAttribute("RegisterCount", codeItem==null?"0":Integer.toString(codeItem.getRegisterCount()));
template.setAttribute("Parameters", getParameters(stg, codeItem, parameterAnnotations));
template.setAttribute("Annotations", getAnnotations(stg, annotationSet));
template.setAttribute("MethodItems", getMethodItems(encodedMethod.method.getDexFile(), stg, codeItem));
return template;
}
public String getMethodName() {
return methodIdItem.getMethodName().getStringValue();
}
private List<String> accessFlags = null;
public List<String> getAccessFlags() {
if (accessFlags == null) {
accessFlags = new ArrayList<String>();
private static List<String> getAccessFlags(ClassDataItem.EncodedMethod encodedMethod) {
List<String> accessFlags = new ArrayList<String>();
for (AccessFlags accessFlag: AccessFlags.getAccessFlagsForMethod(encodedMethod.accessFlags)) {
accessFlags.add(accessFlag.toString());
}
}
return accessFlags;
}
private String prototype = null;
public String getPrototype() {
if (prototype == null) {
prototype = methodIdItem.getPrototype().getPrototypeString();
}
return prototype;
}
private Boolean hasCode = null;
public boolean getHasCode() {
if (hasCode == null) {
hasCode = (codeItem != null);
}
return hasCode;
}
private String registerCount = null;
public String getRegisterCount() {
if (registerCount == null) {
if (codeItem == null) {
registerCount = "0";
} else {
registerCount = Integer.toString(codeItem.getRegisterCount());
}
}
return registerCount;
}
public List<AnnotationAdaptor> getAnnotations() {
if (annotationSet == null) {
return null;
}
List<AnnotationAdaptor> annotationAdaptors = new ArrayList<AnnotationAdaptor>();
for (AnnotationItem annotationItem: annotationSet.getAnnotations()) {
annotationAdaptors.add(new AnnotationAdaptor(annotationItem));
}
return annotationAdaptors;
}
public List<ParameterAdaptor> getParameters() {
private static List<StringTemplate> getParameters(StringTemplateGroup stg, CodeItem codeItem,
AnnotationSetRefList parameterAnnotations) {
DebugInfoItem debugInfoItem = null;
if (codeItem != null) {
debugInfoItem = codeItem.getDebugInfo();
@ -144,7 +105,7 @@ public class MethodDefinition {
}
}
List<ParameterAdaptor> parameterAdaptors = new ArrayList<ParameterAdaptor>();
List<StringTemplate> parameters = new ArrayList<StringTemplate>();
for (int i=0; i<parameterCount; i++) {
AnnotationSetItem annotationSet = null;
if (i < annotations.size()) {
@ -156,45 +117,47 @@ public class MethodDefinition {
parameterName = parameterNames.get(i);
}
parameterAdaptors.add(new ParameterAdaptor(parameterName, annotationSet));
parameters.add(ParameterAdaptor.makeTemplate(stg, parameterName, annotationSet));
}
return parameterAdaptors;
return parameters;
}
public StringIdItem[] getParameterNames() {
if (codeItem == null) {
private static List<StringTemplate> getAnnotations(StringTemplateGroup stg, AnnotationSetItem annotationSet) {
if (annotationSet == null) {
return null;
}
DebugInfoItem debugInfoItem = codeItem.getDebugInfo();
if (debugInfoItem == null) {
return null;
List<StringTemplate> annotationAdaptors = new ArrayList<StringTemplate>();
for (AnnotationItem annotationItem: annotationSet.getAnnotations()) {
annotationAdaptors.add(AnnotationAdaptor.makeTemplate(stg, annotationItem));
}
return annotationAdaptors;
}
return debugInfoItem.getParameterNames();
}
private static List<MethodItem> getMethodItems(DexFile dexFile, StringTemplateGroup stg, CodeItem codeItem) {
List<MethodItem> methodItems = new ArrayList<MethodItem>();
private List<MethodItem> methodItems = null;
public List<MethodItem> getMethodItems() {
if (methodItems == null) {
MethodItemList methodItemList = new MethodItemList();
MethodItemList methodItemList = new MethodItemList(dexFile, stg, codeItem);
methodItemList.generateMethodItemList();
methodItems = new ArrayList<MethodItem>();
methodItems.addAll(methodItemList.labels);
methodItems.addAll(methodItemList.instructions);
methodItems.addAll(methodItemList.blanks);
methodItems.addAll(methodItemList.catches);
methodItems.addAll(methodItemList.debugItems);
Collections.sort(methodItems);
}
return methodItems;
}
private class MethodItemList {
private static class MethodItemList {
private final DexFile dexFile;
private final StringTemplateGroup stg;
private final CodeItem codeItem;
public HashSet<LabelMethodItem> labels = new HashSet<LabelMethodItem>();
public List<MethodItem> instructions = new ArrayList<MethodItem>();
public List<BlankMethodItem> blanks = new ArrayList<BlankMethodItem>();
@ -204,6 +167,11 @@ public class MethodDefinition {
private HashMap<Integer, Integer> packedSwitchMap = new HashMap<Integer, Integer>();
private HashMap<Integer, Integer> sparseSwitchMap = new HashMap<Integer, Integer>();
public MethodItemList(DexFile dexFile, StringTemplateGroup stg, CodeItem codeItem) {
this.dexFile = dexFile;
this.stg = stg;
this.codeItem = codeItem;
}
public void generateMethodItemList() {
if (codeItem == null) {
@ -217,11 +185,11 @@ public class MethodDefinition {
public void ProcessNormalInstruction(Opcode opcode, int index) {
if (opcode == Opcode.PACKED_SWITCH) {
Instruction31t ins = (Instruction31t)opcode.format.Factory.makeInstruction(
methodIdItem.getDexFile(), opcode, encodedInstructions, index);
dexFile, opcode, encodedInstructions, index);
packedSwitchMap.put(index/2 + ins.getOffset(), index/2);
} else if (opcode == Opcode.SPARSE_SWITCH) {
Instruction31t ins = (Instruction31t)opcode.format.Factory.makeInstruction(
methodIdItem.getDexFile(), opcode, encodedInstructions, index);
dexFile, opcode, encodedInstructions, index);
sparseSwitchMap.put(index/2 + ins.getOffset(), index/2);
}
}
@ -235,16 +203,17 @@ public class MethodDefinition {
public void ProcessSparseSwitchInstruction(int index, int targetCount, int instructionLength) {
}
public void ProcessFillArrayDataInstruction(int index, int elementWidth, int elementCount, int instructionLength) {
public void ProcessFillArrayDataInstruction(int index, int elementWidth, int elementCount,
int instructionLength) {
}
});
InstructionIterator.IterateInstructions(methodIdItem.getDexFile(), encodedInstructions,
InstructionIterator.IterateInstructions(dexFile, encodedInstructions,
new InstructionIterator.ProcessInstructionDelegate() {
public void ProcessInstruction(int index, Instruction instruction) {
int offset = index/2;
addMethodItemsForInstruction(offset, instruction);
blanks.add(new BlankMethodItem(offset));
blanks.add(new BlankMethodItem(stg, offset));
}
});
@ -258,91 +227,94 @@ public class MethodDefinition {
private void addMethodItemsForInstruction(int offset, Instruction instruction) {
switch (instruction.getFormat()) {
case Format10t:
instructions.add(new Instruction10tMethodItem(offset, (Instruction10t)instruction));
labels.add(new LabelMethodItem(offset + ((Instruction10t)instruction).getOffset(), "goto_"));
instructions.add(new Instruction10tMethodItem(offset, stg,(Instruction10t)instruction));
labels.add(new LabelMethodItem(offset + ((Instruction10t)instruction).getOffset(), stg, "goto_"));
return;
case Format10x:
instructions.add(new Instruction10xMethodItem(offset, (Instruction10x)instruction));
instructions.add(new Instruction10xMethodItem(offset, stg, (Instruction10x)instruction));
return;
case Format11n:
instructions.add(new Instruction11nMethodItem(offset, (Instruction11n)instruction));
instructions.add(new Instruction11nMethodItem(offset, stg, (Instruction11n)instruction));
return;
case Format11x:
instructions.add(new Instruction11xMethodItem(offset, (Instruction11x)instruction));
instructions.add(new Instruction11xMethodItem(offset, stg, (Instruction11x)instruction));
return;
case Format12x:
instructions.add(new Instruction12xMethodItem(offset, (Instruction12x)instruction));
instructions.add(new Instruction12xMethodItem(offset, stg, (Instruction12x)instruction));
return;
case Format20t:
instructions.add(new Instruction20tMethodItem(offset, (Instruction20t)instruction));
labels.add(new LabelMethodItem(offset + ((Instruction20t)instruction).getOffset(), "goto_"));
instructions.add(new Instruction20tMethodItem(offset, stg, (Instruction20t)instruction));
labels.add(new LabelMethodItem(offset + ((Instruction20t)instruction).getOffset(), stg, "goto_"));
return;
case Format21c:
instructions.add(new Instruction21cMethodItem(offset, (Instruction21c)instruction));
instructions.add(new Instruction21cMethodItem(offset, stg, (Instruction21c)instruction));
return;
case Format21h:
instructions.add(new Instruction21hMethodItem(offset, (Instruction21h)instruction));
instructions.add(new Instruction21hMethodItem(offset, stg, (Instruction21h)instruction));
return;
case Format21s:
instructions.add(new Instruction21sMethodItem(offset, (Instruction21s)instruction));
instructions.add(new Instruction21sMethodItem(offset, stg, (Instruction21s)instruction));
return;
case Format21t:
instructions.add(new Instruction21tMethodItem(offset, (Instruction21t)instruction));
labels.add(new LabelMethodItem(offset + ((Instruction21t)instruction).getOffset(), "cond_"));
instructions.add(new Instruction21tMethodItem(offset, stg, (Instruction21t)instruction));
labels.add(new LabelMethodItem(offset + ((Instruction21t)instruction).getOffset(), stg, "cond_"));
return;
case Format22b:
instructions.add(new Instruction22bMethodItem(offset, (Instruction22b)instruction));
instructions.add(new Instruction22bMethodItem(offset, stg, (Instruction22b)instruction));
return;
case Format22c:
instructions.add(new Instruction22cMethodItem(offset, (Instruction22c)instruction));
instructions.add(new Instruction22cMethodItem(offset, stg, (Instruction22c)instruction));
return;
case Format22s:
instructions.add(new Instruction22sMethodItem(offset, (Instruction22s)instruction));
instructions.add(new Instruction22sMethodItem(offset, stg, (Instruction22s)instruction));
return;
case Format22t:
instructions.add(new Instruction22tMethodItem(offset, (Instruction22t)instruction));
labels.add(new LabelMethodItem(offset + ((Instruction22t)instruction).getOffset(), "cond_"));
instructions.add(new Instruction22tMethodItem(offset, stg, (Instruction22t)instruction));
labels.add(new LabelMethodItem(offset + ((Instruction22t)instruction).getOffset(), stg, "cond_"));
return;
case Format22x:
instructions.add(new Instruction22xMethodItem(offset, (Instruction22x)instruction));
instructions.add(new Instruction22xMethodItem(offset, stg, (Instruction22x)instruction));
return;
case Format23x:
instructions.add(new Instruction23xMethodItem(offset, (Instruction23x)instruction));
instructions.add(new Instruction23xMethodItem(offset, stg, (Instruction23x)instruction));
return;
case Format30t:
instructions.add(new Instruction30tMethodItem(offset, (Instruction30t)instruction));
labels.add(new LabelMethodItem(offset + ((Instruction30t)instruction).getOffset(), "goto_"));
instructions.add(new Instruction30tMethodItem(offset, stg, (Instruction30t)instruction));
labels.add(new LabelMethodItem(offset + ((Instruction30t)instruction).getOffset(), stg, "goto_"));
return;
case Format31c:
instructions.add(new Instruction31cMethodItem(offset, (Instruction31c)instruction));
instructions.add(new Instruction31cMethodItem(offset, stg, (Instruction31c)instruction));
return;
case Format31i:
instructions.add(new Instruction31iMethodItem(offset, (Instruction31i)instruction));
instructions.add(new Instruction31iMethodItem(offset, stg, (Instruction31i)instruction));
return;
case Format31t:
instructions.add(new Instruction31tMethodItem(offset, (Instruction31t)instruction));
instructions.add(new Instruction31tMethodItem(offset, stg, (Instruction31t)instruction));
if (instruction.opcode == Opcode.FILL_ARRAY_DATA) {
labels.add(new LabelMethodItem(offset + ((Instruction31t)instruction).getOffset(), "array_"));
labels.add(new LabelMethodItem(offset + ((Instruction31t)instruction).getOffset(), stg,
"array_"));
} else if (instruction.opcode == Opcode.PACKED_SWITCH) {
labels.add(new LabelMethodItem(offset + ((Instruction31t)instruction).getOffset(), "pswitch_data_"));
labels.add(new LabelMethodItem(offset + ((Instruction31t)instruction).getOffset(), stg,
"pswitch_data_"));
} else if (instruction.opcode == Opcode.SPARSE_SWITCH) {
labels.add(new LabelMethodItem(offset + ((Instruction31t)instruction).getOffset(), "sswitch_data_"));
labels.add(new LabelMethodItem(offset + ((Instruction31t)instruction).getOffset(), stg,
"sswitch_data_"));
}
return;
case Format32x:
instructions.add(new Instruction32xMethodItem(offset, (Instruction32x)instruction));
instructions.add(new Instruction32xMethodItem(offset, stg, (Instruction32x)instruction));
return;
case Format35c:
instructions.add(new Instruction35cMethodItem(offset, (Instruction35c)instruction));
instructions.add(new Instruction35cMethodItem(offset, stg, (Instruction35c)instruction));
return;
case Format3rc:
instructions.add(new Instruction3rcMethodItem(offset, (Instruction3rc)instruction));
instructions.add(new Instruction3rcMethodItem(offset, stg, (Instruction3rc)instruction));
return;
case Format51l:
instructions.add(new Instruction51lMethodItem(offset, (Instruction51l)instruction));
instructions.add(new Instruction51lMethodItem(offset, stg, (Instruction51l)instruction));
return;
case ArrayData:
instructions.add(new ArrayDataMethodItem(offset, (ArrayDataPseudoInstruction)instruction));
instructions.add(new ArrayDataMethodItem(offset, stg, (ArrayDataPseudoInstruction)instruction));
return;
case PackedSwitchData:
{
@ -352,14 +324,14 @@ public class MethodDefinition {
PackedSwitchDataPseudoInstruction packedSwitchInstruction =
(PackedSwitchDataPseudoInstruction)instruction;
instructions.add(new PackedSwitchMethodItem(offset,
instructions.add(new PackedSwitchMethodItem(offset, stg,
packedSwitchInstruction, baseAddress));
Iterator<PackedSwitchDataPseudoInstruction.PackedSwitchTarget> iterator =
packedSwitchInstruction.getTargets();
while (iterator.hasNext()) {
PackedSwitchDataPseudoInstruction.PackedSwitchTarget target = iterator.next();
labels.add(new LabelMethodItem(baseAddress + target.target, "pswitch_"));
labels.add(new LabelMethodItem(baseAddress + target.target, stg, "pswitch_"));
}
}
return;
@ -372,14 +344,14 @@ public class MethodDefinition {
SparseSwitchDataPseudoInstruction sparseSwitchInstruction =
(SparseSwitchDataPseudoInstruction)instruction;
instructions.add(new SparseSwitchMethodItem(offset,
instructions.add(new SparseSwitchMethodItem(offset, stg,
sparseSwitchInstruction, baseAddress));
Iterator<SparseSwitchDataPseudoInstruction.SparseSwitchTarget> iterator =
sparseSwitchInstruction.getTargets();
while (iterator.hasNext()) {
SparseSwitchDataPseudoInstruction.SparseSwitchTarget target = iterator.next();
labels.add(new LabelMethodItem(baseAddress + target.target, "sswitch_"));
labels.add(new LabelMethodItem(baseAddress + target.target, stg, "sswitch_"));
}
}
}
@ -400,7 +372,7 @@ public class MethodDefinition {
* label to be associated with the last covered instruction, so we need to get
* the offset for that instruction
*/
int index = Collections.binarySearch(instructions, new BlankMethodItem(endAddress));
int index = Collections.binarySearch(instructions, new BlankMethodItem(stg, endAddress));
if (index < 0) {
index = (index * -1) - 1;
}
@ -426,19 +398,19 @@ public class MethodDefinition {
//add the catch all handler if it exists
int catchAllAddress = tryItem.encodedCatchHandler.catchAllHandlerAddress;
if (catchAllAddress != -1) {
CatchMethodItem catchMethodItem = new CatchMethodItem(lastInstructionOffset, null, startAddress,
endAddress, catchAllAddress) {
public String getTemplate() {
CatchMethodItem catchMethodItem = new CatchMethodItem(lastInstructionOffset, stg, null,
startAddress, endAddress, catchAllAddress) {
public String getTemplateName() {
return "CatchAll";
}
};
catches.add(catchMethodItem);
labels.add(new LabelMethodItem(startAddress, "try_start_"));
labels.add(new LabelMethodItem(startAddress, stg, "try_start_"));
//use the offset from the last covered instruction, but make the label
//name refer to the address of the next instruction
labels.add(new EndTryLabelMethodItem(lastInstructionOffset, endAddress));
labels.add(new LabelMethodItem(catchAllAddress, "handler_"));
labels.add(new EndTryLabelMethodItem(lastInstructionOffset, stg, endAddress));
labels.add(new LabelMethodItem(catchAllAddress, stg, "handler_"));
}
@ -446,15 +418,15 @@ public class MethodDefinition {
//TODO: find adjacent handlers for the same type and combine them
for (CodeItem.EncodedTypeAddrPair handler: tryItem.encodedCatchHandler.handlers) {
//use the offset from the last covered instruction
CatchMethodItem catchMethodItem = new CatchMethodItem(lastInstructionOffset,
CatchMethodItem catchMethodItem = new CatchMethodItem(lastInstructionOffset, stg,
handler.exceptionType, startAddress, endAddress, handler.handlerAddress);
catches.add(catchMethodItem);
labels.add(new LabelMethodItem(startAddress, "try_start_"));
labels.add(new LabelMethodItem(startAddress, stg, "try_start_"));
//use the offset from the last covered instruction, but make the label
//name refer to the address of the next instruction
labels.add(new EndTryLabelMethodItem(lastInstructionOffset, endAddress));
labels.add(new LabelMethodItem(handler.handlerAddress, "handler_"));
labels.add(new EndTryLabelMethodItem(lastInstructionOffset, stg, endAddress));
labels.add(new LabelMethodItem(handler.handlerAddress, stg, "handler_"));
}
}
}
@ -470,56 +442,58 @@ public class MethodDefinition {
@Override
public void ProcessStartLocal(int codeAddress, int length, int registerNum, StringIdItem name,
TypeIdItem type) {
debugItems.add(new LocalDebugMethodItem(codeAddress, "StartLocal", -1, registerNum, name,
type, null));
debugItems.add(new LocalDebugMethodItem(codeAddress, stg, "StartLocal", -1, registerNum,
name, type, null));
}
@Override
public void ProcessStartLocalExtended(int codeAddress, int length, int registerNum,
StringIdItem name, TypeIdItem type,
StringIdItem signature) {
debugItems.add(new LocalDebugMethodItem(codeAddress, "StartLocal", -1, registerNum, name,
type, signature));
debugItems.add(new LocalDebugMethodItem(codeAddress, stg, "StartLocal", -1, registerNum,
name, type, signature));
}
@Override
public void ProcessEndLocal(int codeAddress, int length, int registerNum, StringIdItem name,
TypeIdItem type, StringIdItem signature) {
debugItems.add(new LocalDebugMethodItem(codeAddress, "EndLocal", -1, registerNum, name,
debugItems.add(new LocalDebugMethodItem(codeAddress, stg, "EndLocal", -1, registerNum, name,
type, signature));
}
@Override
public void ProcessRestartLocal(int codeAddress, int length, int registerNum, StringIdItem name,
TypeIdItem type, StringIdItem signature) {
debugItems.add(new LocalDebugMethodItem(codeAddress, "RestartLocal", -1, registerNum, name,
type, signature));
debugItems.add(new LocalDebugMethodItem(codeAddress, stg, "RestartLocal", -1, registerNum,
name, type, signature));
}
@Override
public void ProcessSetPrologueEnd(int codeAddress) {
debugItems.add(new DebugMethodItem(codeAddress, "EndPrologue", -4));
debugItems.add(new DebugMethodItem(codeAddress, stg, "EndPrologue", -4));
}
@Override
public void ProcessSetEpilogueBegin(int codeAddress) {
debugItems.add(new DebugMethodItem(codeAddress, "StartEpilogue", -4));
debugItems.add(new DebugMethodItem(codeAddress, stg, "StartEpilogue", -4));
}
@Override
public void ProcessSetFile(int codeAddress, int length, final StringIdItem name) {
debugItems.add(new DebugMethodItem(codeAddress, "SetFile", -3) {
public String getFileName() {
return name.getStringValue();
debugItems.add(new DebugMethodItem(codeAddress, stg, "SetFile", -3) {
@Override
protected void setAttributes(StringTemplate template) {
template.setAttribute("FileName", name.getStringValue());
}
});
}
@Override
public void ProcessLineEmit(int codeAddress, final int line) {
debugItems.add(new DebugMethodItem(codeAddress, "Line", -2) {
public int getLine() {
return line;
debugItems.add(new DebugMethodItem(codeAddress, stg, "Line", -2) {
@Override
protected void setAttributes(StringTemplate template) {
template.setAttribute("Line", line);
}
});
}

View File

@ -35,7 +35,6 @@ public abstract class MethodItem implements Comparable<MethodItem> {
this.offset = offset;
}
public int getOffset() {
return offset;
}
@ -44,8 +43,6 @@ public abstract class MethodItem implements Comparable<MethodItem> {
return Integer.toHexString(offset);
}
//return the name of the template that should be used to render this item
public abstract String getTemplate();
//return an arbitrary integer that determines how this item will be sorted with
//others at the same offset
public abstract int getSortOrder();

View File

@ -30,31 +30,31 @@ package org.jf.baksmali.Adaptors;
import org.jf.dexlib.AnnotationSetItem;
import org.jf.dexlib.AnnotationItem;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import java.util.List;
import java.util.ArrayList;
public class ParameterAdaptor {
private String parameterName;
private AnnotationSetItem parameterAnnotations;
public static StringTemplate makeTemplate(StringTemplateGroup stg, String parameterName,
AnnotationSetItem parameterAnnotations) {
StringTemplate template = stg.getInstanceOf("Parameter");
public ParameterAdaptor(String parameterName, AnnotationSetItem parameterAnnotations) {
this.parameterName = parameterName;
this.parameterAnnotations = parameterAnnotations;
template.setAttribute("ParameterName", parameterName);
template.setAttribute("Annotations", getAnnotations(stg, parameterAnnotations));
return template;
}
public String getParameterName() {
return parameterName;
}
public List<AnnotationAdaptor> getAnnotations() {
private static List<StringTemplate> getAnnotations(StringTemplateGroup stg,
AnnotationSetItem parameterAnnotations) {
if (parameterAnnotations == null) {
return null;
}
List<AnnotationAdaptor> annotations = new ArrayList<AnnotationAdaptor>();
List<StringTemplate> annotations = new ArrayList<StringTemplate>();
for (AnnotationItem annotationItem: parameterAnnotations.getAnnotations()) {
annotations.add(new AnnotationAdaptor(annotationItem));
annotations.add(AnnotationAdaptor.makeTemplate(stg, annotationItem));
}
return annotations;
}

View File

@ -97,7 +97,7 @@ public class baksmali {
//create and initialize the top level string template
StringTemplate smaliFileST = templates.getInstanceOf("smaliFile");
smaliFileST.setAttribute("classDef", new ClassDefinition(classDefItem));
smaliFileST.setAttribute("classDef", new ClassDefinition(templates, classDefItem));
//generate the disassembly
String output = smaliFileST.toString();

View File

@ -22,35 +22,35 @@ smaliFile(classDef) ::=
# annotations
<classDef.Annotations: annotation(it); separator="\n\n">
<classDef.Annotations; separator="\n\n">
<endif>
<if(classDef.StaticFields)>
<if(classDef.HasStaticFields)>
# static fields
<classDef.StaticFields: field(it); separator="\n">
<classDef.StaticFields; separator="\n">
<endif>
<if(classDef.InstanceFields)>
<if(classDef.HasInstanceFields)>
# instance fields
<classDef.InstanceFields: field(it); separator="\n">
<classDef.InstanceFields; separator="\n">
<endif>
<if(classDef.DirectMethods)>
<if(classDef.HasDirectMethods)>
# direct methods
<classDef.DirectMethods: method(it); separator="\n\n">
<classDef.DirectMethods; separator="\n\n">
<endif>
<if(classDef.VirtualMethods)>
<if(classDef.HasVirtualMethods)>
# virtual methods
<classDef.VirtualMethods: method(it); separator="\n\n">
<classDef.VirtualMethods; separator="\n\n">
<endif>
>>
@ -64,13 +64,13 @@ implement(interface) ::=
>>
annotation(annotationAdaptor) ::=
annotation(Visibility, AnnotationType, Elements) ::=
<<
.annotation <annotationAdaptor.Visibility> <Reference(annotationAdaptor.AnnotationType)>
<if(annotationAdaptor.Elements)>
<annotationAdaptor.Elements: AnnotationElement(it); separator="\n">
.annotation <Visibility> <Reference(AnnotationType)>
<if(Elements)>
<Elements: AnnotationElement(it); separator="\n">
<endif>
<if(annotationAdaptor.Elements)>
<if(Elements)>
<endif>
@ -79,46 +79,41 @@ annotation(annotationAdaptor) ::=
field(fieldDef) ::=
field(AccessFlags, FieldName, FieldType, Annotations, InitialValue) ::=
<<
.field <fieldDef.AccessFlags: {<it> }><fieldDef.FieldName>:<fieldDef.FieldType><if(fieldDef.InitialValue)> = <fieldDef.InitialValue: EncodedValue(it)><endif>
<if(fieldDef.Annotations)>
<fieldDef.Annotations: annotation(it); separator="\n\n">
.field <AccessFlags: {<it> }><FieldName>:<FieldType><if(InitialValue)> = <InitialValue: EncodedValue(it)><endif>
<if(Annotations)>
<Annotations; separator="\n\n">
.end field
<endif>
>>
method(methodDef) ::=
method(AccessFlags, MethodName, Prototype, HasCode, RegisterCount, Parameters, Annotations, MethodItems) ::=
<<
.method <methodDef.AccessFlags: {<it> }><methodDef.MethodName><methodDef.Prototype>
<if(methodDef.hasCode)>
.registers <methodDef.RegisterCount>
<if(methodDef.Parameters)>
<methodDef.Parameters: Parameter(it); separator="\n">
.method <AccessFlags: {<it> }><MethodName><Prototype>
<if(HasCode)>
.registers <RegisterCount>
<if(Parameters)>
<Parameters; separator="\n">
<endif>
<if(methodDef.Annotations)>
<methodDef.Annotations: annotation(it); separator="\n\n">
<if(Annotations)>
<Annotations; separator="\n\n">
<endif>
<methodDef.MethodItems: MethodItem(it); separator="\n">
<elseif(methodDef.Annotations)>
<methodDef.Annotations: annotation(it); separator="\n\n">
<MethodItems; separator="\n">
<elseif(Annotations)>
<Annotations; separator="\n\n">
<endif>
.end method
>>
MethodItem(MethodItem) ::=
Parameter(ParameterName, Annotations) ::=
<<
<MethodItem: (MethodItem.Template)(MethodItem)>
>>
.parameter<if(ParameterName)> "<ParameterName>"<endif><if(Annotations)>
Parameter(Parameter) ::=
<<
.parameter<if(Parameter.ParameterName)> "<Parameter.ParameterName>"<endif><if(Parameter.Annotations)>
<Parameter.Annotations: annotation(it); separator="\n\n">
<Annotations; separator="\n\n">
.end parameter
<endif>
>>
@ -139,161 +134,156 @@ v<num; format="decimal">
Format10t(Instruction) ::=
Format10t(Opcode, Target) ::=
<<
<Instruction.Opcode> goto_<Instruction.Target>:
<Opcode> goto_<Target>:
>>
Format10x(Instruction) ::=
Format10x(Opcode) ::=
<<
<Instruction.Opcode>
<Opcode>
>>
Format11n(Instruction) ::=
Format11n(Opcode, Register, Literal) ::=
<<
<Instruction.Opcode> <Register(Instruction.Register)>, <Instruction.Literal>
<Opcode> <Register(Register)>, <Literal>
>>
Format11x(Instruction) ::=
Format11x(Opcode, Register) ::=
<<
<Instruction.Opcode> <Register(Instruction.Register)>
<Opcode> <Register(Register)>
>>
Format12x(Instruction) ::=
Format12x(Opcode, RegisterA, RegisterB) ::=
<<
<Instruction.Opcode> <Register(Instruction.RegisterA)>, <Register(Instruction.RegisterB)>
<Opcode> <Register(RegisterA)>, <Register(RegisterB)>
>>
Format20t(Instruction) ::=
Format20t(Opcode, Target) ::=
<<
<Instruction.Opcode> goto_<Instruction.Target>:
<Opcode> goto_<Target>:
>>
Format21c(Instruction) ::=
Format21c(Opcode, Register, Reference) ::=
<<
<Instruction.Opcode> <Register(Instruction.Register)>, <Reference(Instruction.Reference)>
<Opcode> <Register(Register)>, <Reference(Reference)>
>>
Format21h(Instruction) ::=
Format21h(Opcode, Register, Literal) ::=
<<
<Instruction.Opcode> <Register(Instruction.Register)>, <Instruction.Literal>
<Opcode> <Register(Register)>, <Literal>
>>
Format21s(Instruction) ::=
Format21s(Opcode, Register, Literal) ::=
<<
<Instruction.Opcode> <Register(Instruction.Register)>, <Instruction.Literal>
<Opcode> <Register(Register)>, <Literal>
>>
Format21t(Instruction) ::=
Format21t(Opcode, Register, Target) ::=
<<
<Instruction.Opcode> <Register(Instruction.Register)>, cond_<Instruction.Target>:
<Opcode> <Register(Register)>, cond_<Target>:
>>
Format22b(Instruction) ::=
Format22b(Opcode, RegisterA, RegisterB, Literal) ::=
<<
<Instruction.Opcode> <Register(Instruction.RegisterA)>, <Register(Instruction.RegisterB)>, <Instruction.Literal>
<Opcode> <Register(RegisterA)>, <Register(RegisterB)>, <Literal>
>>
Format22c(Instruction) ::=
Format22c(Opcode, RegisterA, RegisterB, Reference) ::=
<<
<Instruction.Opcode> <Register(Instruction.RegisterA)>, <Register(Instruction.RegisterB)>, <Reference(Instruction.Reference)>
<Opcode> <Register(RegisterA)>, <Register(RegisterB)>, <Reference(Reference)>
>>
Format22s(Instruction) ::=
Format22s(Opcode, RegisterA, RegisterB, Literal) ::=
<<
<Instruction.Opcode> <Register(Instruction.RegisterA)>, <Register(Instruction.RegisterB)>, <Instruction.Literal>
<Opcode> <Register(RegisterA)>, <Register(RegisterB)>, <Literal>
>>
Format22t(Instruction) ::=
Format22t(Opcode, RegisterA, RegisterB, Target) ::=
<<
<Instruction.Opcode> <Register(Instruction.RegisterA)>, <Register(Instruction.RegisterB)>, cond_<Instruction.Target>:
<Opcode> <Register(RegisterA)>, <Register(RegisterB)>, cond_<Target>:
>>
Format22x(Instruction) ::=
Format22x(Opcode, RegisterA, RegisterB) ::=
<<
<Instruction.Opcode> <Register(Instruction.RegisterA)>, <Register(Instruction.RegisterB)>
<Opcode> <Register(RegisterA)>, <Register(RegisterB)>
>>
Format23x(Instruction) ::=
Format23x(Opcode, RegisterA, RegisterB, RegisterC) ::=
<<
<Instruction.Opcode> <Register(Instruction.RegisterA)>, <Register(Instruction.RegisterB)>, <Register(Instruction.RegisterC)>
<Opcode> <Register(RegisterA)>, <Register(RegisterB)>, <Register(RegisterC)>
>>
Format30t(Instruction) ::=
Format30t(Opcode, Target) ::=
<<
<Instruction.Opcode> goto_<Instruction.Target>:
<Opcode> goto_<Target>:
>>
Format31c(Instruction) ::=
Format31c(Opcode, Register, Reference) ::=
<<
<Instruction.Opcode> <Register(Instruction.Register)>, <Reference(Instruction.Reference)>
<Opcode> <Register(Register)>, <Reference(Reference)>
>>
Format31i(Instruction) ::=
Format31i(Opcode, Register, Literal) ::=
<<
<Instruction.Opcode> <Register(Instruction.Register)>, <Instruction.Literal>
<Opcode> <Register(Register)>, <Literal>
>>
Format31t(Instruction) ::=
Format31t(Opcode, Register, Target) ::=
<<
<Instruction.Opcode> <Register(Instruction.Register)>, <Format31tLabelMap.(Instruction.Opcode)><Instruction.Target>:
<Opcode> <Register(Register)>, <Format31tLabelMap.(Opcode)><Target>:
>>
Format32x(Instruction) ::=
Format32x(Opcode, RegisterA, RegisterB) ::=
<<
<Instruction.Opcode> <Register(Instruction.RegisterA)>, <Register(Instruction.RegisterB)>
<Opcode> <Register(RegisterA)>, <Register(RegisterB)>
>>
Format35c(Instruction) ::=
Format35c(Opcode, Registers, Reference) ::=
<<
<Instruction.Opcode> {<Instruction.Registers: Register(it); separator=", ">}, <Reference(Instruction.Reference)>
<Opcode> {<Registers: Register(it); separator=", ">}, <Reference(Reference)>
>>
Format3rc(Instruction) ::=
Format3rc(Opcode, StartRegister, LastRegister, Reference) ::=
<<
<Instruction.Opcode> {<Register(Instruction.StartRegister)> .. <Register(Instruction.LastRegister)>}, <Reference(Instruction.Reference)>
<Opcode> {<Register(StartRegister)> .. <Register(LastRegister)>}, <Reference(Reference)>
>>
Format51l(Instruction) ::=
Format51l(Opcode, Register, Literal) ::=
<<
<Instruction.Opcode> <Register(Instruction.Register)>, <Instruction.Literal>
<Opcode> <Register(Register)>, <Literal>
>>
ArrayData(Instruction) ::=
ArrayData(Opcode, ElementWidth, Values) ::=
<<
.array-data <Instruction.ElementWidth>
.array-data <ElementWidth>
<Instruction.Values: {<it.ByteArray; format="unsigned",separator=" ">}; separator="\n">
.end array-data
>>
PackedSwitchData(Instruction) ::=
PackedSwitchData(Opcode, FirstKey, Targets) ::=
<<
.packed-switch <Instruction.FirstKey>
<Instruction.Targets: {pswitch_<it>:}; separator="\n">
.packed-switch <FirstKey>
<Targets: {pswitch_<it>:}; separator="\n">
.end packed-switch
>>
SparseSwitchData(Instruction) ::=
SparseSwitchData(Opcode, Targets) ::=
<<
.sparse-switch
<Instruction.Targets:{<it.Value> -> sswitch_<it.Target>:}; separator="\n">
<Targets:{<it.Value> -> sswitch_<it.Target>:}; separator="\n">
.end sparse-switch
>>
Label(Label) ::=
Label(Prefix, HexOffset) ::=
<<
<Label.Prefix><Label.HexOffset>:
>>
EndTryLabel(Label) ::=
<<
<Label.Prefix><Label.LabelOffset; format="barehex">:
<Prefix><HexOffset>:
>>
Line(Line) ::=
<<
.line <Line.Line; format="decimal">
.line <Line; format="decimal">
>>
EndPrologue(Prologue) ::=
@ -306,24 +296,24 @@ StartEpilogue(Epilogue) ::=
.epilogue
>>
StartLocal(StartLocal) ::=
StartLocal(Register, Name, Type, Signature) ::=
<<
.local <Register(StartLocal.Register)>, <StartLocal.Name>:<StartLocal.Type><if(StartLocal.Signature)>,"<StartLocal.Signature>"<endif>
.local <Register(Register)>, <Name>:<Type><if(Signature)>,"<Signature>"<endif>
>>
EndLocal(EndLocal) ::=
EndLocal(Register, Name, Type, Signature) ::=
<<
.end local <Register(EndLocal.Register)> <if(EndLocal.Name)>#<EndLocal.Name>:<EndLocal.Type>,<if(EndLocal.Signature)>, "<EndLocal.Signature>"<endif><endif>
.end local <Register(Register)> <if(Name)>#<Name>:<Type>,<if(Signature)>, "<Signature>"<endif><endif>
>>
RestartLocal(RestartLocal) ::=
RestartLocal(Register, Name, Type, Signature) ::=
<<
.restart local <Register(RestartLocal.Register)> <if(RestartLocal.Name)>#<RestartLocal.Name>:<RestartLocal.Type>,<if(RestartLocal.Signature)>, "<RestartLocal.Signature>"<endif><endif>
.restart local <Register(Register)> <if(Name)>#<Name>:<Type>,<if(Signature)>, "<Signature>"<endif><endif>
>>
SetFile(SetFile) ::=
SetFile(FileName) ::=
<<
.source "<SetFile.FileName>"
.source "<FileName>"
>>
Blank(Blank) ::=
@ -331,14 +321,14 @@ Blank(Blank) ::=
>>
Catch(Catch) ::=
Catch(ExceptionType, StartAddress, EndAddress, HandlerAddress) ::=
<<
.catch <Reference(Catch.ExceptionType)> {try_start_<Catch.StartAddress; format="barehex">: .. try_end_<Catch.EndAddress; format="barehex">:} handler_<Catch.HandlerAddress; format="barehex">:
.catch <Reference(ExceptionType)> {try_start_<StartAddress>: .. try_end_<EndAddress>:} handler_<HandlerAddress>:
>>
CatchAll(Catch) ::=
CatchAll(StartAddress, EndAddress, HandlerAddress) ::=
<<
.catchall {try_start_<Catch.StartAddress; format="barehex">: .. try_end_<Catch.EndAddress; format="barehex">:} handler_<Catch.HandlerAddress; format="barehex">:
.catchall {try_start_<StartAddress>: .. try_end_<EndAddress>:} handler_<HandlerAddress>:
>>