mirror of
https://github.com/revanced/smali.git
synced 2025-05-05 17:14:25 +02:00
- refactored/simplified the label code
- changed the handler_ label prefix to catch_ and catchall_ - added support for the new -i/--indexed-labels option, which numbers the labels incrementally for each method by type, rather than using the bytecode offset git-svn-id: https://smali.googlecode.com/svn/trunk@493 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
8555ce95d5
commit
e2684fa219
@ -36,18 +36,42 @@ import org.antlr.stringtemplate.StringTemplate;
|
||||
public class CatchMethodItem extends MethodItem {
|
||||
private final StringTemplateGroup stg;
|
||||
private final TypeIdItem exceptionType;
|
||||
private final int startAddress;
|
||||
private final int endAddress;
|
||||
private final int handlerAddress;
|
||||
|
||||
public CatchMethodItem(int offset, StringTemplateGroup stg, TypeIdItem exceptionType, int startAddress,
|
||||
int endAddress, int handlerAddress) {
|
||||
private final LabelMethodItem tryStartLabel;
|
||||
private final LabelMethodItem tryEndLabel;
|
||||
private final LabelMethodItem handlerLabel;
|
||||
|
||||
public CatchMethodItem(MethodDefinition.LabelCache labelCache, 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;
|
||||
|
||||
tryStartLabel = labelCache.internLabel(new LabelMethodItem(startAddress, stg, "try_start_"));
|
||||
tryStartLabel.setUncommented();
|
||||
//use the offset from the last covered instruction, but make the label
|
||||
//name refer to the address of the next instruction
|
||||
tryEndLabel = labelCache.internLabel(new EndTryLabelMethodItem(offset, stg, endAddress));
|
||||
tryEndLabel.setUncommented();
|
||||
|
||||
if (exceptionType == null) {
|
||||
handlerLabel = labelCache.internLabel(new LabelMethodItem(handlerAddress, stg, "catchall_"));
|
||||
} else {
|
||||
handlerLabel = labelCache.internLabel(new LabelMethodItem(handlerAddress, stg, "catch_"));
|
||||
}
|
||||
handlerLabel.setUncommented();
|
||||
}
|
||||
|
||||
public LabelMethodItem getTryStartLabel() {
|
||||
return tryStartLabel;
|
||||
}
|
||||
|
||||
public LabelMethodItem getTryEndLabel() {
|
||||
return tryEndLabel;
|
||||
}
|
||||
|
||||
public LabelMethodItem getHandlerLabel() {
|
||||
return handlerLabel;
|
||||
}
|
||||
|
||||
public int getSortOrder() {
|
||||
@ -65,9 +89,9 @@ public class CatchMethodItem extends MethodItem {
|
||||
if (exceptionType != null) {
|
||||
template.setAttribute("ExceptionType", TypeReference.makeTemplate(stg, exceptionType));
|
||||
}
|
||||
template.setAttribute("StartAddress", Integer.toHexString(startAddress));
|
||||
template.setAttribute("EndAddress", Integer.toHexString(endAddress));
|
||||
template.setAttribute("HandlerAddress", Integer.toHexString(handlerAddress));
|
||||
template.setAttribute("StartLabel", tryStartLabel);
|
||||
template.setAttribute("EndLabel", tryEndLabel);
|
||||
template.setAttribute("HandlerLabel", handlerLabel);
|
||||
return template.toString();
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public class EndTryLabelMethodItem extends LabelMethodItem {
|
||||
private int labelOffset;
|
||||
|
||||
public EndTryLabelMethodItem(int offset, StringTemplateGroup stg, int labelOffset) {
|
||||
super(offset, stg, "try_end_", false);
|
||||
super(offset, stg, "try_end_");
|
||||
this.labelOffset = labelOffset;
|
||||
}
|
||||
|
||||
|
@ -28,18 +28,18 @@
|
||||
|
||||
package org.jf.baksmali.Adaptors.Format;
|
||||
|
||||
import org.antlr.stringtemplate.StringTemplate;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
import org.jf.dexlib.Code.Format.Instruction10t;
|
||||
import org.jf.dexlib.CodeItem;
|
||||
import org.jf.baksmali.Adaptors.MethodDefinition;
|
||||
|
||||
public class Instruction10tMethodItem extends InstructionFormatMethodItem<Instruction10t> {
|
||||
public Instruction10tMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg,
|
||||
Instruction10t instruction) {
|
||||
super(codeItem, offset, stg, instruction);
|
||||
public class Instruction10tMethodItem extends OffsetInstructionFormatMethodItem<Instruction10t> {
|
||||
public Instruction10tMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset,
|
||||
StringTemplateGroup stg, Instruction10t instruction) {
|
||||
super(labelCache, codeItem, offset, stg, instruction);
|
||||
}
|
||||
|
||||
protected void setAttributes(StringTemplate template) {
|
||||
template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset()));
|
||||
protected String getLabelPrefix() {
|
||||
return "goto_";
|
||||
}
|
||||
}
|
||||
|
@ -28,18 +28,18 @@
|
||||
|
||||
package org.jf.baksmali.Adaptors.Format;
|
||||
|
||||
import org.antlr.stringtemplate.StringTemplate;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
import org.jf.dexlib.Code.Format.Instruction20t;
|
||||
import org.jf.dexlib.CodeItem;
|
||||
import org.jf.baksmali.Adaptors.MethodDefinition;
|
||||
|
||||
public class Instruction20tMethodItem extends InstructionFormatMethodItem<Instruction20t> {
|
||||
public Instruction20tMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg,
|
||||
Instruction20t instruction) {
|
||||
super(codeItem, offset, stg, instruction);
|
||||
public class Instruction20tMethodItem extends OffsetInstructionFormatMethodItem<Instruction20t> {
|
||||
public Instruction20tMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset,
|
||||
StringTemplateGroup stg, Instruction20t instruction) {
|
||||
super(labelCache, codeItem, offset, stg, instruction);
|
||||
}
|
||||
|
||||
protected void setAttributes(StringTemplate template) {
|
||||
template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset()));
|
||||
protected String getLabelPrefix() {
|
||||
return "goto_";
|
||||
}
|
||||
}
|
||||
|
@ -32,15 +32,20 @@ import org.antlr.stringtemplate.StringTemplate;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
import org.jf.dexlib.Code.Format.Instruction21t;
|
||||
import org.jf.dexlib.CodeItem;
|
||||
import org.jf.baksmali.Adaptors.MethodDefinition;
|
||||
|
||||
public class Instruction21tMethodItem extends InstructionFormatMethodItem<Instruction21t> {
|
||||
public Instruction21tMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg,
|
||||
Instruction21t instruction) {
|
||||
super(codeItem, offset, stg, instruction);
|
||||
public class Instruction21tMethodItem extends OffsetInstructionFormatMethodItem<Instruction21t> {
|
||||
public Instruction21tMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset,
|
||||
StringTemplateGroup stg, Instruction21t instruction) {
|
||||
super(labelCache, codeItem, offset, stg, instruction);
|
||||
}
|
||||
|
||||
protected void setAttributes(StringTemplate template) {
|
||||
super.setAttributes(template);
|
||||
template.setAttribute("Register", formatRegister(instruction.getRegister()));
|
||||
template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset()));
|
||||
}
|
||||
|
||||
protected String getLabelPrefix() {
|
||||
return "cond_";
|
||||
}
|
||||
}
|
||||
|
@ -32,16 +32,21 @@ import org.antlr.stringtemplate.StringTemplate;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
import org.jf.dexlib.Code.Format.Instruction22t;
|
||||
import org.jf.dexlib.CodeItem;
|
||||
import org.jf.baksmali.Adaptors.MethodDefinition;
|
||||
|
||||
public class Instruction22tMethodItem extends InstructionFormatMethodItem<Instruction22t> {
|
||||
public Instruction22tMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg,
|
||||
Instruction22t instruction) {
|
||||
super(codeItem, offset, stg, instruction);
|
||||
public class Instruction22tMethodItem extends OffsetInstructionFormatMethodItem<Instruction22t> {
|
||||
public Instruction22tMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset,
|
||||
StringTemplateGroup stg, Instruction22t instruction) {
|
||||
super(labelCache, codeItem, offset, stg, instruction);
|
||||
}
|
||||
|
||||
protected void setAttributes(StringTemplate template) {
|
||||
super.setAttributes(template);
|
||||
template.setAttribute("RegisterA", formatRegister(instruction.getRegisterA()));
|
||||
template.setAttribute("RegisterB", formatRegister(instruction.getRegisterB()));
|
||||
template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset()));
|
||||
}
|
||||
|
||||
protected String getLabelPrefix() {
|
||||
return "cond_";
|
||||
}
|
||||
}
|
||||
|
@ -28,18 +28,18 @@
|
||||
|
||||
package org.jf.baksmali.Adaptors.Format;
|
||||
|
||||
import org.antlr.stringtemplate.StringTemplate;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
import org.jf.dexlib.Code.Format.Instruction30t;
|
||||
import org.jf.dexlib.CodeItem;
|
||||
import org.jf.baksmali.Adaptors.MethodDefinition;
|
||||
|
||||
public class Instruction30tMethodItem extends InstructionFormatMethodItem<Instruction30t> {
|
||||
public Instruction30tMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg,
|
||||
Instruction30t instruction) {
|
||||
super(codeItem, offset, stg, instruction);
|
||||
public class Instruction30tMethodItem extends OffsetInstructionFormatMethodItem<Instruction30t> {
|
||||
public Instruction30tMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset,
|
||||
StringTemplateGroup stg, Instruction30t instruction) {
|
||||
super(labelCache, codeItem, offset, stg, instruction);
|
||||
}
|
||||
|
||||
protected void setAttributes(StringTemplate template) {
|
||||
template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset()));
|
||||
protected String getLabelPrefix() {
|
||||
return "goto_";
|
||||
}
|
||||
}
|
||||
|
@ -31,16 +31,28 @@ package org.jf.baksmali.Adaptors.Format;
|
||||
import org.antlr.stringtemplate.StringTemplate;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
import org.jf.dexlib.Code.Format.Instruction31t;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.CodeItem;
|
||||
import org.jf.baksmali.Adaptors.MethodDefinition;
|
||||
|
||||
public class Instruction31tMethodItem extends InstructionFormatMethodItem<Instruction31t> {
|
||||
public Instruction31tMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg,
|
||||
Instruction31t instruction) {
|
||||
super(codeItem, offset, stg, instruction);
|
||||
public class Instruction31tMethodItem extends OffsetInstructionFormatMethodItem<Instruction31t> {
|
||||
public Instruction31tMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset,
|
||||
StringTemplateGroup stg, Instruction31t instruction) {
|
||||
super(labelCache, codeItem, offset, stg, instruction);
|
||||
}
|
||||
|
||||
protected void setAttributes(StringTemplate template) {
|
||||
super.setAttributes(template);
|
||||
template.setAttribute("Register", formatRegister(instruction.getRegister()));
|
||||
template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset()));
|
||||
}
|
||||
|
||||
protected String getLabelPrefix() {
|
||||
if (instruction.opcode == Opcode.FILL_ARRAY_DATA) {
|
||||
return "array_";
|
||||
}
|
||||
if (instruction.opcode == Opcode.PACKED_SWITCH) {
|
||||
return "pswitch_data_";
|
||||
}
|
||||
return "sswitch_data_";
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* [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.CodeItem;
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.OffsetInstruction;
|
||||
import org.jf.baksmali.Adaptors.LabelMethodItem;
|
||||
import org.jf.baksmali.Adaptors.MethodDefinition;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
import org.antlr.stringtemplate.StringTemplate;
|
||||
|
||||
public abstract class OffsetInstructionFormatMethodItem<T extends Instruction & OffsetInstruction>
|
||||
extends InstructionFormatMethodItem<T> {
|
||||
protected LabelMethodItem label;
|
||||
|
||||
public OffsetInstructionFormatMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset,
|
||||
StringTemplateGroup stg, T instruction) {
|
||||
super(codeItem, offset, stg, instruction);
|
||||
|
||||
label = new LabelMethodItem(offset + instruction.getOffset(), stg, getLabelPrefix());
|
||||
label = labelCache.internLabel(label);
|
||||
}
|
||||
|
||||
protected abstract String getLabelPrefix();
|
||||
|
||||
protected void setAttributes(StringTemplate template) {
|
||||
template.setAttribute("TargetLabel", label);
|
||||
}
|
||||
|
||||
public LabelMethodItem getLabel() {
|
||||
return label;
|
||||
}
|
||||
}
|
@ -32,34 +32,37 @@ import org.antlr.stringtemplate.StringTemplate;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
import org.jf.dexlib.Code.Format.PackedSwitchDataPseudoInstruction;
|
||||
import org.jf.dexlib.CodeItem;
|
||||
import org.jf.baksmali.Adaptors.LabelMethodItem;
|
||||
import org.jf.baksmali.Adaptors.MethodDefinition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class PackedSwitchMethodItem extends InstructionFormatMethodItem<PackedSwitchDataPseudoInstruction> {
|
||||
private int baseAddress;
|
||||
public class PackedSwitchMethodItem extends InstructionFormatMethodItem<PackedSwitchDataPseudoInstruction>
|
||||
implements Iterable<LabelMethodItem> {
|
||||
private List<LabelMethodItem> labels = new ArrayList<LabelMethodItem>();
|
||||
|
||||
public PackedSwitchMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg,
|
||||
PackedSwitchDataPseudoInstruction instruction, int baseAddress) {
|
||||
public PackedSwitchMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset,
|
||||
StringTemplateGroup stg, PackedSwitchDataPseudoInstruction instruction,
|
||||
int baseAddress) {
|
||||
super(codeItem, offset, stg, instruction);
|
||||
this.baseAddress = baseAddress;
|
||||
}
|
||||
|
||||
protected void setAttributes(StringTemplate template) {
|
||||
template.setAttribute("FirstKey", instruction.getFirstKey());
|
||||
template.setAttribute("Targets", getTargets());
|
||||
}
|
||||
|
||||
private List<String> getTargets() {
|
||||
List<String> targets = new ArrayList<String>();
|
||||
|
||||
Iterator<PackedSwitchDataPseudoInstruction.PackedSwitchTarget> iterator = instruction.getTargets();
|
||||
while (iterator.hasNext()) {
|
||||
PackedSwitchDataPseudoInstruction.PackedSwitchTarget target = iterator.next();
|
||||
targets.add(Integer.toHexString(target.target + baseAddress));
|
||||
LabelMethodItem label = new LabelMethodItem(baseAddress + target.target, stg, "pswitch_");
|
||||
label = labelCache.internLabel(label);
|
||||
labels.add(label);
|
||||
}
|
||||
}
|
||||
|
||||
return targets;
|
||||
protected void setAttributes(StringTemplate template) {
|
||||
template.setAttribute("FirstKey", instruction.getFirstKey());
|
||||
template.setAttribute("Targets", labels);
|
||||
}
|
||||
|
||||
public Iterator<LabelMethodItem> iterator() {
|
||||
return labels.iterator();
|
||||
}
|
||||
}
|
||||
|
@ -32,42 +32,60 @@ import org.antlr.stringtemplate.StringTemplate;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
import org.jf.dexlib.Code.Format.SparseSwitchDataPseudoInstruction;
|
||||
import org.jf.dexlib.CodeItem;
|
||||
import org.jf.baksmali.Adaptors.LabelMethodItem;
|
||||
import org.jf.baksmali.Adaptors.MethodDefinition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class SparseSwitchMethodItem extends InstructionFormatMethodItem<SparseSwitchDataPseudoInstruction> {
|
||||
private int baseAddress;
|
||||
public class SparseSwitchMethodItem extends InstructionFormatMethodItem<SparseSwitchDataPseudoInstruction>
|
||||
implements Iterable<LabelMethodItem> {
|
||||
private List<SparseSwitchTarget> targets = new ArrayList<SparseSwitchTarget>();
|
||||
|
||||
public SparseSwitchMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg,
|
||||
SparseSwitchDataPseudoInstruction instruction, int baseAddress) {
|
||||
public SparseSwitchMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset,
|
||||
StringTemplateGroup stg, SparseSwitchDataPseudoInstruction instruction,
|
||||
int baseAddress) {
|
||||
super(codeItem, 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;
|
||||
}
|
||||
|
||||
private List<SparseSwitchTarget> getTargets() {
|
||||
List<SparseSwitchTarget> targets = new ArrayList<SparseSwitchTarget>();
|
||||
|
||||
Iterator<SparseSwitchDataPseudoInstruction.SparseSwitchTarget> iterator = instruction.getTargets();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
SparseSwitchDataPseudoInstruction.SparseSwitchTarget target = iterator.next();
|
||||
SparseSwitchTarget sparseSwitchTarget = new SparseSwitchTarget();
|
||||
sparseSwitchTarget.Value = target.value;
|
||||
sparseSwitchTarget.Target = Integer.toHexString(target.target + baseAddress);
|
||||
|
||||
LabelMethodItem label = new LabelMethodItem(baseAddress + target.target, stg, "sswitch_");
|
||||
label = labelCache.internLabel(label);
|
||||
sparseSwitchTarget.Target = label;
|
||||
|
||||
targets.add(sparseSwitchTarget);
|
||||
}
|
||||
}
|
||||
|
||||
return targets;
|
||||
protected void setAttributes(StringTemplate template) {
|
||||
template.setAttribute("Targets", targets);
|
||||
}
|
||||
|
||||
public Iterator<LabelMethodItem> iterator() {
|
||||
return new Iterator<LabelMethodItem>() {
|
||||
private Iterator<SparseSwitchTarget> iterator = targets.iterator();
|
||||
|
||||
public boolean hasNext() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
public LabelMethodItem next() {
|
||||
return iterator.next().Target;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
iterator.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class SparseSwitchTarget {
|
||||
public int Value;
|
||||
public LabelMethodItem Target;
|
||||
}
|
||||
}
|
||||
|
@ -30,17 +30,18 @@ package org.jf.baksmali.Adaptors;
|
||||
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
import org.antlr.stringtemplate.StringTemplate;
|
||||
import org.jf.baksmali.baksmali;
|
||||
|
||||
public class LabelMethodItem extends MethodItem {
|
||||
private final StringTemplateGroup stg;
|
||||
private final String labelPrefix;
|
||||
private boolean isCommentedOut = false;
|
||||
private int labelIndex;
|
||||
private boolean isCommentedOut = true;
|
||||
|
||||
public LabelMethodItem(int offset, StringTemplateGroup stg, String labelPrefix, boolean isCommentedOut) {
|
||||
public LabelMethodItem(int offset, StringTemplateGroup stg, String labelPrefix) {
|
||||
super(offset);
|
||||
this.stg = stg;
|
||||
this.labelPrefix = labelPrefix;
|
||||
this.isCommentedOut = isCommentedOut;
|
||||
}
|
||||
|
||||
public int getSortOrder() {
|
||||
@ -51,8 +52,8 @@ public class LabelMethodItem extends MethodItem {
|
||||
return isCommentedOut;
|
||||
}
|
||||
|
||||
public void setCommentedOut(boolean isCommentedOut) {
|
||||
this.isCommentedOut = isCommentedOut;
|
||||
public void setUncommented() {
|
||||
this.isCommentedOut = false;
|
||||
}
|
||||
|
||||
public int compareTo(MethodItem methodItem) {
|
||||
@ -81,13 +82,28 @@ public class LabelMethodItem extends MethodItem {
|
||||
@Override
|
||||
public String toString() {
|
||||
StringTemplate template = stg.getInstanceOf("Label");
|
||||
template.setAttribute("CommentedOut", this.isCommentedOut);
|
||||
template.setAttribute("Prefix", labelPrefix);
|
||||
template.setAttribute("HexOffset", getLabelOffset());
|
||||
if (baksmali.useIndexedLabels) {
|
||||
template.setAttribute("Suffix", Integer.toHexString(labelIndex));
|
||||
} else {
|
||||
template.setAttribute("Suffix", getLabelOffset());
|
||||
}
|
||||
return template.toString();
|
||||
}
|
||||
|
||||
public String getLabelPrefix() {
|
||||
return labelPrefix;
|
||||
}
|
||||
|
||||
public String getLabelOffset() {
|
||||
return getHexOffset();
|
||||
}
|
||||
|
||||
public int getLabelIndex() {
|
||||
return labelIndex;
|
||||
}
|
||||
|
||||
public void setLabelIndex(int labelIndex) {
|
||||
this.labelIndex = labelIndex;
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import org.jf.dexlib.Code.Format.*;
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.InstructionIterator;
|
||||
import org.jf.dexlib.Code.OffsetInstruction;
|
||||
import org.jf.dexlib.Util.AccessFlags;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
import org.antlr.stringtemplate.StringTemplate;
|
||||
@ -159,7 +160,14 @@ public class MethodDefinition {
|
||||
MethodItemList methodItemList = new MethodItemList(dexFile, stg, codeItem);
|
||||
methodItemList.generateMethodItemList();
|
||||
|
||||
methodItems.addAll(methodItemList.labels.values());
|
||||
for (LabelMethodItem labelMethodItem: methodItemList.labels.getLabels()) {
|
||||
if (labelMethodItem.isCommentedOut()) {
|
||||
methodItems.add(new CommentedOutMethodItem(stg, labelMethodItem));
|
||||
} else {
|
||||
methodItems.add(labelMethodItem);
|
||||
}
|
||||
}
|
||||
|
||||
methodItems.addAll(methodItemList.instructions);
|
||||
methodItems.addAll(methodItemList.blanks);
|
||||
methodItems.addAll(methodItemList.catches);
|
||||
@ -175,7 +183,8 @@ public class MethodDefinition {
|
||||
private final StringTemplateGroup stg;
|
||||
private final CodeItem codeItem;
|
||||
|
||||
public HashMap<LabelMethodItem, LabelMethodItem> labels = new HashMap<LabelMethodItem, LabelMethodItem>();
|
||||
public LabelCache labels = new LabelCache();
|
||||
|
||||
public List<MethodItem> instructions = new ArrayList<MethodItem>();
|
||||
public List<BlankMethodItem> blanks = new ArrayList<BlankMethodItem>();
|
||||
public List<CatchMethodItem> catches = new ArrayList<CatchMethodItem>();
|
||||
@ -264,8 +273,24 @@ public class MethodDefinition {
|
||||
addTries();
|
||||
|
||||
addDebugInfo();
|
||||
|
||||
if (baksmali.useIndexedLabels) {
|
||||
setLabelIndexes();
|
||||
}
|
||||
}
|
||||
|
||||
private void addOffsetInstructionMethodItem(OffsetInstructionFormatMethodItem methodItem, boolean commentedOut,
|
||||
String comment) {
|
||||
if (commentedOut) {
|
||||
instructions.add(new CommentedOutMethodItem(stg, methodItem));
|
||||
} else {
|
||||
instructions.add(methodItem);
|
||||
LabelMethodItem label = methodItem.getLabel();
|
||||
label.setUncommented();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addInstructionMethodItem(InstructionFormatMethodItem methodItem, boolean commentedOut,
|
||||
String comment) {
|
||||
if (commentedOut) {
|
||||
@ -275,26 +300,13 @@ public class MethodDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
private void addLabelMethodItem(LabelMethodItem labelMethodItem) {
|
||||
LabelMethodItem internedLabelMethodItem = labels.get(labelMethodItem);
|
||||
if (internedLabelMethodItem != null) {
|
||||
if (!labelMethodItem.isCommentedOut() && internedLabelMethodItem.isCommentedOut()) {
|
||||
internedLabelMethodItem.setCommentedOut(false);
|
||||
}
|
||||
} else {
|
||||
labels.put(labelMethodItem, labelMethodItem);
|
||||
}
|
||||
}
|
||||
|
||||
private void addMethodItemsForInstruction(int offset, Instruction instruction, boolean commentedOut,
|
||||
String comment) {
|
||||
switch (instruction.getFormat()) {
|
||||
case Format10t:
|
||||
addInstructionMethodItem(
|
||||
new Instruction10tMethodItem(codeItem, offset, stg,(Instruction10t)instruction),
|
||||
addOffsetInstructionMethodItem(
|
||||
new Instruction10tMethodItem(labels, codeItem, offset, stg,(Instruction10t)instruction),
|
||||
commentedOut, comment);
|
||||
addLabelMethodItem(new LabelMethodItem(offset + ((Instruction10t)instruction).getOffset(), stg,
|
||||
"goto_", commentedOut));
|
||||
return;
|
||||
case Format10x:
|
||||
addInstructionMethodItem(
|
||||
@ -317,11 +329,9 @@ public class MethodDefinition {
|
||||
commentedOut, comment);
|
||||
return;
|
||||
case Format20t:
|
||||
addInstructionMethodItem(
|
||||
new Instruction20tMethodItem(codeItem, offset, stg, (Instruction20t)instruction),
|
||||
addOffsetInstructionMethodItem(
|
||||
new Instruction20tMethodItem(labels, codeItem, offset, stg, (Instruction20t)instruction),
|
||||
commentedOut, comment);
|
||||
addLabelMethodItem(new LabelMethodItem(offset + ((Instruction20t)instruction).getOffset(), stg,
|
||||
"goto_", commentedOut));
|
||||
return;
|
||||
case Format21c:
|
||||
addInstructionMethodItem(
|
||||
@ -339,11 +349,9 @@ public class MethodDefinition {
|
||||
commentedOut, comment);
|
||||
return;
|
||||
case Format21t:
|
||||
addInstructionMethodItem(
|
||||
new Instruction21tMethodItem(codeItem, offset, stg, (Instruction21t)instruction),
|
||||
addOffsetInstructionMethodItem(
|
||||
new Instruction21tMethodItem(labels, codeItem, offset, stg, (Instruction21t)instruction),
|
||||
commentedOut, comment);
|
||||
addLabelMethodItem(new LabelMethodItem(offset + ((Instruction21t)instruction).getOffset(), stg,
|
||||
"cond_", commentedOut));
|
||||
return;
|
||||
case Format22b:
|
||||
addInstructionMethodItem(
|
||||
@ -371,11 +379,9 @@ public class MethodDefinition {
|
||||
commentedOut, comment);
|
||||
return;
|
||||
case Format22t:
|
||||
addInstructionMethodItem(
|
||||
new Instruction22tMethodItem(codeItem, offset, stg, (Instruction22t)instruction),
|
||||
addOffsetInstructionMethodItem(
|
||||
new Instruction22tMethodItem(labels, codeItem, offset, stg, (Instruction22t)instruction),
|
||||
commentedOut, comment);
|
||||
addLabelMethodItem(new LabelMethodItem(offset + ((Instruction22t)instruction).getOffset(), stg,
|
||||
"cond_", commentedOut));
|
||||
return;
|
||||
case Format22x:
|
||||
addInstructionMethodItem(
|
||||
@ -388,11 +394,9 @@ public class MethodDefinition {
|
||||
commentedOut, comment);
|
||||
return;
|
||||
case Format30t:
|
||||
addInstructionMethodItem(
|
||||
new Instruction30tMethodItem(codeItem, offset, stg, (Instruction30t)instruction),
|
||||
addOffsetInstructionMethodItem(
|
||||
new Instruction30tMethodItem(labels, codeItem, offset, stg, (Instruction30t)instruction),
|
||||
commentedOut, comment);
|
||||
addLabelMethodItem(new LabelMethodItem(offset + ((Instruction30t)instruction).getOffset(), stg,
|
||||
"goto_", commentedOut));
|
||||
return;
|
||||
case Format31c:
|
||||
addInstructionMethodItem(
|
||||
@ -405,19 +409,9 @@ public class MethodDefinition {
|
||||
commentedOut, comment);
|
||||
return;
|
||||
case Format31t:
|
||||
addInstructionMethodItem(
|
||||
new Instruction31tMethodItem(codeItem, offset, stg, (Instruction31t)instruction),
|
||||
addOffsetInstructionMethodItem(
|
||||
new Instruction31tMethodItem(labels, codeItem, offset, stg, (Instruction31t)instruction),
|
||||
commentedOut, comment);
|
||||
if (instruction.opcode == Opcode.FILL_ARRAY_DATA) {
|
||||
addLabelMethodItem(new LabelMethodItem(offset + ((Instruction31t)instruction).getOffset(), stg,
|
||||
"array_", commentedOut));
|
||||
} else if (instruction.opcode == Opcode.PACKED_SWITCH) {
|
||||
addLabelMethodItem(new LabelMethodItem(offset + ((Instruction31t)instruction).getOffset(), stg,
|
||||
"pswitch_data_", commentedOut));
|
||||
} else if (instruction.opcode == Opcode.SPARSE_SWITCH) {
|
||||
addLabelMethodItem(new LabelMethodItem(offset + ((Instruction31t)instruction).getOffset(), stg,
|
||||
"sswitch_data_", commentedOut));
|
||||
}
|
||||
return;
|
||||
case Format32x:
|
||||
addInstructionMethodItem(
|
||||
@ -482,16 +476,14 @@ public class MethodDefinition {
|
||||
PackedSwitchDataPseudoInstruction packedSwitchInstruction =
|
||||
(PackedSwitchDataPseudoInstruction)instruction;
|
||||
|
||||
addInstructionMethodItem(
|
||||
new PackedSwitchMethodItem(codeItem, offset, stg, packedSwitchInstruction, baseAddress),
|
||||
commentedOut, comment);
|
||||
PackedSwitchMethodItem packedSwitch = new PackedSwitchMethodItem(labels, codeItem, offset, stg,
|
||||
packedSwitchInstruction, baseAddress);
|
||||
addInstructionMethodItem(packedSwitch, commentedOut, comment);
|
||||
|
||||
Iterator<PackedSwitchDataPseudoInstruction.PackedSwitchTarget> iterator =
|
||||
packedSwitchInstruction.getTargets();
|
||||
while (iterator.hasNext()) {
|
||||
PackedSwitchDataPseudoInstruction.PackedSwitchTarget target = iterator.next();
|
||||
addLabelMethodItem(new LabelMethodItem(baseAddress + target.target, stg, "pswitch_",
|
||||
commentedOut));
|
||||
if (!commentedOut) {
|
||||
for (LabelMethodItem label: packedSwitch) {
|
||||
label.setUncommented();
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -504,16 +496,14 @@ public class MethodDefinition {
|
||||
SparseSwitchDataPseudoInstruction sparseSwitchInstruction =
|
||||
(SparseSwitchDataPseudoInstruction)instruction;
|
||||
|
||||
addInstructionMethodItem(
|
||||
new SparseSwitchMethodItem(codeItem, offset, stg, sparseSwitchInstruction, baseAddress),
|
||||
commentedOut, comment);
|
||||
SparseSwitchMethodItem sparseSwitch = new SparseSwitchMethodItem(labels, codeItem, offset, stg,
|
||||
sparseSwitchInstruction, baseAddress);
|
||||
addInstructionMethodItem(sparseSwitch, commentedOut, comment);
|
||||
|
||||
Iterator<SparseSwitchDataPseudoInstruction.SparseSwitchTarget> iterator =
|
||||
sparseSwitchInstruction.getTargets();
|
||||
while (iterator.hasNext()) {
|
||||
SparseSwitchDataPseudoInstruction.SparseSwitchTarget target = iterator.next();
|
||||
addLabelMethodItem(new LabelMethodItem(baseAddress + target.target, stg, "sswitch_",
|
||||
commentedOut));
|
||||
if (!commentedOut) {
|
||||
for (LabelMethodItem label: sparseSwitch) {
|
||||
label.setUncommented();
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -575,35 +565,17 @@ public class MethodDefinition {
|
||||
//add the catch all handler if it exists
|
||||
int catchAllAddress = tryItem.encodedCatchHandler.catchAllHandlerAddress;
|
||||
if (catchAllAddress != -1) {
|
||||
CatchMethodItem catchMethodItem = new CatchMethodItem(lastInstructionOffset, stg, null,
|
||||
startAddress, endAddress, catchAllAddress) {
|
||||
public String getTemplateName() {
|
||||
return "CatchAll";
|
||||
}
|
||||
};
|
||||
CatchMethodItem catchMethodItem = new CatchMethodItem(labels, lastInstructionOffset, stg, null,
|
||||
startAddress, endAddress, catchAllAddress);
|
||||
catches.add(catchMethodItem);
|
||||
|
||||
addLabelMethodItem(new LabelMethodItem(startAddress, stg, "try_start_", false));
|
||||
//use the offset from the last covered instruction, but make the label
|
||||
//name refer to the address of the next instruction
|
||||
addLabelMethodItem(new EndTryLabelMethodItem(lastInstructionOffset, stg, endAddress));
|
||||
addLabelMethodItem(new LabelMethodItem(catchAllAddress, stg, "handler_", false));
|
||||
|
||||
}
|
||||
|
||||
//add the rest of the handlers
|
||||
//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, stg,
|
||||
CatchMethodItem catchMethodItem = new CatchMethodItem(labels, lastInstructionOffset, stg,
|
||||
handler.exceptionType, startAddress, endAddress, handler.handlerAddress);
|
||||
catches.add(catchMethodItem);
|
||||
|
||||
addLabelMethodItem(new LabelMethodItem(startAddress, stg, "try_start_", false));
|
||||
//use the offset from the last covered instruction, but make the label
|
||||
//name refer to the address of the next instruction
|
||||
addLabelMethodItem(new EndTryLabelMethodItem(lastInstructionOffset, stg, endAddress));
|
||||
addLabelMethodItem(new LabelMethodItem(handler.handlerAddress, stg, "handler_", false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -676,5 +648,46 @@ public class MethodDefinition {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setLabelIndexes() {
|
||||
HashMap<String, Integer> nextLabelIndexByType = new HashMap<String, Integer>();
|
||||
ArrayList<LabelMethodItem> sortedLabels = new ArrayList<LabelMethodItem>(labels.getLabels());
|
||||
|
||||
//sort the labels by their location in the method
|
||||
Collections.sort(sortedLabels);
|
||||
|
||||
for (LabelMethodItem labelMethodItem: sortedLabels) {
|
||||
Integer labelIndex = nextLabelIndexByType.get(labelMethodItem.getLabelPrefix());
|
||||
if (labelIndex == null) {
|
||||
labelIndex = 0;
|
||||
}
|
||||
labelMethodItem.setLabelIndex(labelIndex);
|
||||
nextLabelIndexByType.put(labelMethodItem.getLabelPrefix(), labelIndex + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class LabelCache {
|
||||
protected HashMap<LabelMethodItem, LabelMethodItem> labels = new HashMap<LabelMethodItem, LabelMethodItem>();
|
||||
|
||||
public LabelCache() {
|
||||
}
|
||||
|
||||
public LabelMethodItem internLabel(LabelMethodItem labelMethodItem) {
|
||||
LabelMethodItem internedLabelMethodItem = labels.get(labelMethodItem);
|
||||
if (internedLabelMethodItem != null) {
|
||||
if (!labelMethodItem.isCommentedOut()) {
|
||||
internedLabelMethodItem.setUncommented();
|
||||
}
|
||||
return internedLabelMethodItem;
|
||||
}
|
||||
labels.put(labelMethodItem, labelMethodItem);
|
||||
return labelMethodItem;
|
||||
}
|
||||
|
||||
|
||||
public Collection<LabelMethodItem> getLabels() {
|
||||
return labels.values();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,13 +43,17 @@ import java.io.*;
|
||||
public class baksmali {
|
||||
public static boolean noParameterRegisters = false;
|
||||
public static boolean useLocalsDirective = false;
|
||||
public static boolean useIndexedLabels = false;
|
||||
public static DeodexUtil deodexUtil = null;
|
||||
|
||||
public static void disassembleDexFile(DexFile dexFile, Deodexerant deodexerant, String outputDirectory,
|
||||
boolean noParameterRegisters, boolean useLocalsDirective)
|
||||
boolean noParameterRegisters, boolean useLocalsDirective,
|
||||
boolean useIndexedLabels)
|
||||
{
|
||||
baksmali.noParameterRegisters = noParameterRegisters;
|
||||
baksmali.useLocalsDirective = useLocalsDirective;
|
||||
baksmali.useIndexedLabels = useIndexedLabels;
|
||||
|
||||
if (deodexerant != null) {
|
||||
baksmali.deodexUtil = new DeodexUtil(deodexerant);
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ public class main {
|
||||
boolean fixRegisters = false;
|
||||
boolean noParameterRegisters = false;
|
||||
boolean useLocalsDirective = false;
|
||||
boolean useIndexedLabels = false;
|
||||
|
||||
|
||||
String outputDirectory = "out";
|
||||
@ -135,6 +136,10 @@ public class main {
|
||||
useLocalsDirective = true;
|
||||
}
|
||||
|
||||
if (commandLine.hasOption("i")) {
|
||||
useIndexedLabels = true;
|
||||
}
|
||||
|
||||
if (commandLine.hasOption("x")) {
|
||||
String deodexerantAddress = commandLine.getOptionValue("x");
|
||||
String[] parts = deodexerantAddress.split(":");
|
||||
@ -186,7 +191,7 @@ public class main {
|
||||
|
||||
if (disassemble) {
|
||||
baksmali.disassembleDexFile(dexFile, deodexerant, outputDirectory, noParameterRegisters,
|
||||
useLocalsDirective);
|
||||
useLocalsDirective, useIndexedLabels);
|
||||
}
|
||||
|
||||
if ((doDump || write) && !dexFile.isOdex()) {
|
||||
@ -282,10 +287,15 @@ public class main {
|
||||
.create("x");
|
||||
|
||||
Option useLocalsOption = OptionBuilder.withLongOpt("use-locals")
|
||||
.withDescription("output the .locals directive with the number of non-parameter registers, instead of" +
|
||||
" the .register directive with the total number of register")
|
||||
.withDescription("output the .locals directive with the number of non-parameter registers, rather" +
|
||||
" than the .register directive with the total number of register")
|
||||
.create("l");
|
||||
|
||||
Option indexedLabelsOption = OptionBuilder.withLongOpt("indexed-labels")
|
||||
.withDescription("create label names using a per-method/per-label-type auto-index as the suffix, " +
|
||||
" rather than the bytecode offset")
|
||||
.create("i");
|
||||
|
||||
OptionGroup dumpCommand = new OptionGroup();
|
||||
|
||||
options.addOption(versionOption);
|
||||
@ -299,5 +309,6 @@ public class main {
|
||||
options.addOption(noParameterRegistersOption);
|
||||
options.addOption(deodexerantOption);
|
||||
options.addOption(useLocalsOption);
|
||||
options.addOption(indexedLabelsOption);
|
||||
}
|
||||
}
|
@ -123,18 +123,9 @@ Parameter(ParameterName, Annotations) ::=
|
||||
<endif>
|
||||
>>
|
||||
|
||||
|
||||
|
||||
Format31tLabelMap ::= [
|
||||
"fill-array-data":"array_",
|
||||
"packed-switch":"pswitch_data_",
|
||||
"sparse-switch":"sswitch_data_"
|
||||
]
|
||||
|
||||
|
||||
Format10t(Opcode, Target) ::=
|
||||
Format10t(Opcode, TargetLabel) ::=
|
||||
<<
|
||||
<Opcode> :goto_<Target>
|
||||
<Opcode> <TargetLabel>
|
||||
>>
|
||||
|
||||
Format10x(Opcode) ::=
|
||||
@ -157,9 +148,9 @@ Format12x(Opcode, RegisterA, RegisterB) ::=
|
||||
<Opcode> <RegisterA>, <RegisterB>
|
||||
>>
|
||||
|
||||
Format20t(Opcode, Target) ::=
|
||||
Format20t(Opcode, TargetLabel) ::=
|
||||
<<
|
||||
<Opcode> :goto_<Target>
|
||||
<Opcode> <TargetLabel>
|
||||
>>
|
||||
|
||||
Format21c(Opcode, Register, Reference) ::=
|
||||
@ -177,9 +168,9 @@ Format21s(Opcode, Register, Literal) ::=
|
||||
<Opcode> <Register>, <Literal>
|
||||
>>
|
||||
|
||||
Format21t(Opcode, Register, Target) ::=
|
||||
Format21t(Opcode, Register, TargetLabel) ::=
|
||||
<<
|
||||
<Opcode> <Register>, :cond_<Target>
|
||||
<Opcode> <Register>, <TargetLabel>
|
||||
>>
|
||||
|
||||
Format22b(Opcode, RegisterA, RegisterB, Literal) ::=
|
||||
@ -207,9 +198,9 @@ Format22s(Opcode, RegisterA, RegisterB, Literal) ::=
|
||||
<Opcode> <RegisterA>, <RegisterB>, <Literal>
|
||||
>>
|
||||
|
||||
Format22t(Opcode, RegisterA, RegisterB, Target) ::=
|
||||
Format22t(Opcode, RegisterA, RegisterB, TargetLabel) ::=
|
||||
<<
|
||||
<Opcode> <RegisterA>, <RegisterB>, :cond_<Target>
|
||||
<Opcode> <RegisterA>, <RegisterB>, <TargetLabel>
|
||||
>>
|
||||
|
||||
Format22x(Opcode, RegisterA, RegisterB) ::=
|
||||
@ -222,9 +213,9 @@ Format23x(Opcode, RegisterA, RegisterB, RegisterC) ::=
|
||||
<Opcode> <RegisterA>, <RegisterB>, <RegisterC>
|
||||
>>
|
||||
|
||||
Format30t(Opcode, Target) ::=
|
||||
Format30t(Opcode, TargetLabel) ::=
|
||||
<<
|
||||
<Opcode> :goto_<Target>
|
||||
<Opcode> <TargetLabel>
|
||||
>>
|
||||
|
||||
Format31c(Opcode, Register, Reference) ::=
|
||||
@ -237,9 +228,9 @@ Format31i(Opcode, Register, Literal) ::=
|
||||
<Opcode> <Register>, <Literal>
|
||||
>>
|
||||
|
||||
Format31t(Opcode, Register, Target) ::=
|
||||
Format31t(Opcode, Register, TargetLabel) ::=
|
||||
<<
|
||||
<Opcode> <Register>, :<Format31tLabelMap.(Opcode)><Target>
|
||||
<Opcode> <Register>, <TargetLabel>
|
||||
>>
|
||||
|
||||
Format32x(Opcode, RegisterA, RegisterB) ::=
|
||||
@ -322,21 +313,21 @@ ArrayElement(Bytes) ::=
|
||||
PackedSwitchData(Opcode, FirstKey, Targets) ::=
|
||||
<<
|
||||
.packed-switch <FirstKey>
|
||||
<Targets: {:pswitch_<it>}; separator="\n">
|
||||
<Targets: {<it>}; separator="\n">
|
||||
.end packed-switch
|
||||
>>
|
||||
|
||||
SparseSwitchData(Opcode, Targets) ::=
|
||||
<<
|
||||
.sparse-switch
|
||||
<Targets:{<it.Value> -> :sswitch_<it.Target>}; separator="\n">
|
||||
<Targets:{<it.Value> -> <it.Target>}; separator="\n">
|
||||
.end sparse-switch
|
||||
>>
|
||||
|
||||
|
||||
Label(Prefix, HexOffset, CommentedOut) ::=
|
||||
Label(Prefix, Suffix) ::=
|
||||
<<
|
||||
<if(CommentedOut)>#<endif>:<Prefix><HexOffset>
|
||||
:<Prefix><Suffix>
|
||||
>>
|
||||
|
||||
Line(Line) ::=
|
||||
@ -379,17 +370,11 @@ Blank(Blank) ::=
|
||||
|
||||
>>
|
||||
|
||||
Catch(ExceptionType, StartAddress, EndAddress, HandlerAddress) ::=
|
||||
Catch(ExceptionType, StartLabel, EndLabel, HandlerLabel) ::=
|
||||
<<
|
||||
.catch <ExceptionType> {:try_start_<StartAddress> .. :try_end_<EndAddress>} :handler_<HandlerAddress>
|
||||
<if(ExceptionType)>.catch <ExceptionType><else>.catchall<endif> {<StartLabel> .. <EndLabel>} <HandlerLabel>
|
||||
>>
|
||||
|
||||
CatchAll(StartAddress, EndAddress, HandlerAddress) ::=
|
||||
<<
|
||||
.catchall {:try_start_<StartAddress> .. :try_end_<EndAddress>} :handler_<HandlerAddress>
|
||||
>>
|
||||
|
||||
|
||||
|
||||
StringReference(EscapedValue) ::=
|
||||
<<
|
||||
|
Loading…
x
Reference in New Issue
Block a user