Seperate out execute-inline and execute-inline/range into seperate 35mi and 3rmi formats
diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java
index 4b0a995..a51cfb1 100644
--- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java
+++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java
@@ -186,6 +186,12 @@
writer.write(", ");
writeReference(writer);
return true;
+ case Format35mi:
+ writeOpcode(writer);
+ writer.write(' ');
+ writeInvokeRegisters(writer);
+ writer.write(", ");
+ writeInlineIndex(writer);
case Format35ms:
writeOpcode(writer);
writer.write(' ');
@@ -200,6 +206,13 @@
writer.write(", ");
writeReference(writer);
return true;
+ case Format3rmi:
+ writeOpcode(writer);
+ writer.write(' ');
+ writeInvokeRangeRegisters(writer);
+ writer.write(", ");
+ writeInlineIndex(writer);
+ return true;
case Format3rms:
writeOpcode(writer);
writer.write(' ');
@@ -304,6 +317,11 @@
writer.printUnsignedLongAsHex(((OdexedFieldAccess) instruction).getFieldOffset());
}
+ protected void writeInlineIndex(IndentingWriter writer) throws IOException {
+ writer.write("inline@0x");
+ writer.printUnsignedLongAsHex(((OdexedInvokeInline) instruction).getInlineIndex());
+ }
+
protected void writeVtableIndex(IndentingWriter writer) throws IOException {
writer.write("vtable@0x");
writer.printUnsignedLongAsHex(((OdexedInvokeVirtual) instruction).getVtableIndex());
diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/InlineMethodResolver.java b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/InlineMethodResolver.java
index aad4cb5..eb4e9dc 100644
--- a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/InlineMethodResolver.java
+++ b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/InlineMethodResolver.java
@@ -28,10 +28,10 @@
package org.jf.dexlib.Code.Analysis;
-import org.jf.dexlib.Code.Format.Instruction35ms;
-import org.jf.dexlib.Code.Format.Instruction3rms;
+import org.jf.dexlib.Code.Format.Instruction35mi;
+import org.jf.dexlib.Code.Format.Instruction3rmi;
+import org.jf.dexlib.Code.OdexedInvokeInline;
import org.jf.dexlib.Code.OdexedInvokeVirtual;
-import org.jf.dexlib.MethodIdItem;
import static org.jf.dexlib.Code.Analysis.DeodexUtil.Static;
import static org.jf.dexlib.Code.Analysis.DeodexUtil.Virtual;
@@ -143,16 +143,16 @@
@Override
public DeodexUtil.InlineMethod resolveExecuteInline(AnalyzedInstruction analyzedInstruction) {
- assert analyzedInstruction.instruction instanceof OdexedInvokeVirtual;
+ assert analyzedInstruction.instruction instanceof OdexedInvokeInline;
- OdexedInvokeVirtual instruction = (OdexedInvokeVirtual)analyzedInstruction.instruction;
- int methodIndex = instruction.getVtableIndex();
+ OdexedInvokeInline instruction = (OdexedInvokeInline)analyzedInstruction.instruction;
+ int inlineIndex = instruction.getInlineIndex();
- if (methodIndex < 0 || methodIndex >= inlineMethods.length) {
- throw new RuntimeException("Invalid method index: " + methodIndex);
+ if (inlineIndex < 0 || inlineIndex >= inlineMethods.length) {
+ throw new RuntimeException("Invalid method index: " + inlineIndex);
}
- if (methodIndex == 4) {
+ if (inlineIndex == 4) {
int parameterCount = getParameterCount(instruction);
if (parameterCount == 2) {
return indexOfIMethod;
@@ -161,7 +161,7 @@
} else {
throw new RuntimeException("Could not determine the correct inline method to use");
}
- } else if (methodIndex == 5) {
+ } else if (inlineIndex == 5) {
int parameterCount = getParameterCount(instruction);
if (parameterCount == 3) {
return indexOfIIMethod;
@@ -172,14 +172,14 @@
}
}
- return inlineMethods[methodIndex];
+ return inlineMethods[inlineIndex];
}
- private int getParameterCount(OdexedInvokeVirtual instruction) {
- if (instruction instanceof Instruction35ms) {
- return ((Instruction35ms)instruction).getRegCount();
+ private int getParameterCount(OdexedInvokeInline instruction) {
+ if (instruction instanceof Instruction35mi) {
+ return ((Instruction35mi)instruction).getRegCount();
} else {
- return ((Instruction3rms)instruction).getRegCount();
+ return ((Instruction3rmi)instruction).getRegCount();
}
}
};
diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java
index 232b891..8810e35 100644
--- a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java
+++ b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java
@@ -252,11 +252,13 @@
case Format22cs:
objectRegisterNumber = ((Instruction22cs)instruction.instruction).getRegisterB();
break;
+ case Format35mi:
case Format35ms:
- objectRegisterNumber = ((Instruction35ms)instruction.instruction).getRegisterD();
+ objectRegisterNumber = ((FiveRegisterInstruction)instruction.instruction).getRegisterD();
break;
+ case Format3rmi:
case Format3rms:
- objectRegisterNumber = ((Instruction3rms)instruction.instruction).getStartRegister();
+ objectRegisterNumber = ((RegisterRangeInstruction)instruction.instruction).getStartRegister();
break;
default:
continue;
@@ -3338,13 +3340,13 @@
throw new ValidationException("Cannot analyze an odexed instruction unless we are deodexing");
}
- Instruction35ms instruction = (Instruction35ms)analyzedInstruction.instruction;
+ Instruction35mi instruction = (Instruction35mi)analyzedInstruction.instruction;
DeodexUtil.InlineMethod inlineMethod = deodexUtil.lookupInlineMethod(analyzedInstruction);
MethodIdItem inlineMethodIdItem = inlineMethod.getMethodIdItem();
if (inlineMethodIdItem == null) {
throw new ValidationException(String.format("Cannot load inline method with index %d",
- instruction.getVtableIndex()));
+ instruction.getInlineIndex()));
}
Opcode deodexedOpcode = null;
@@ -3376,13 +3378,13 @@
throw new ValidationException("Cannot analyze an odexed instruction unless we are deodexing");
}
- Instruction3rms instruction = (Instruction3rms)analyzedInstruction.instruction;
+ Instruction3rmi instruction = (Instruction3rmi)analyzedInstruction.instruction;
DeodexUtil.InlineMethod inlineMethod = deodexUtil.lookupInlineMethod(analyzedInstruction);
MethodIdItem inlineMethodIdItem = inlineMethod.getMethodIdItem();
if (inlineMethodIdItem == null) {
throw new ValidationException(String.format("Cannot load inline method with index %d",
- instruction.getVtableIndex()));
+ instruction.getInlineIndex()));
}
Opcode deodexedOpcode = null;
diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java
index 4ed9fec..4958cb2 100644
--- a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java
+++ b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java
@@ -56,8 +56,10 @@
Format32x(Instruction32x.Factory, 6),
Format35c(Instruction35c.Factory, 6),
Format35s(Instruction35s.Factory, 6),
+ Format35mi(Instruction35mi.Factory, 6),
Format35ms(Instruction35ms.Factory, 6),
Format3rc(Instruction3rc.Factory, 6),
+ Format3rmi(Instruction3rmi.Factory, 6),
Format3rms(Instruction3rms.Factory, 6),
Format51l(Instruction51l.Factory, 10),
ArrayData(null, -1, true),
diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35mi.java b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35mi.java
new file mode 100644
index 0000000..787bd07
--- /dev/null
+++ b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35mi.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2011, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.jf.dexlib.Code.Format;
+
+import org.jf.dexlib.Code.*;
+import org.jf.dexlib.DexFile;
+import org.jf.dexlib.Util.AnnotatedOutput;
+import org.jf.dexlib.Util.NumberUtils;
+
+
+public class Instruction35mi extends Instruction implements FiveRegisterInstruction, OdexedInvokeInline {
+ public static final InstructionFactory Factory = new Factory();
+ private byte regCount;
+ private byte regA;
+ private byte regD;
+ private byte regE;
+ private byte regF;
+ private byte regG;
+ private short inlineIndex;
+
+ public Instruction35mi(Opcode opcode, int regCount, byte regD, byte regE, byte regF, byte regG,
+ byte regA, int inlineIndex) {
+ super(opcode);
+ if (regCount > 5) {
+ throw new RuntimeException("regCount cannot be greater than 5");
+ }
+
+ if (regD >= 1 << 4 ||
+ regE >= 1 << 4 ||
+ regF >= 1 << 4 ||
+ regG >= 1 << 4 ||
+ regA >= 1 << 4) {
+ throw new RuntimeException("All register args must fit in 4 bits");
+ }
+
+ if (inlineIndex >= 1 << 16) {
+ throw new RuntimeException("The method index must be less than 65536");
+ }
+
+ this.regCount = (byte)regCount;
+ this.regA = regA;
+ this.regD = regD;
+ this.regE = regE;
+ this.regF = regF;
+ this.regG = regG;
+ this.inlineIndex = (short)inlineIndex;
+ }
+
+ private Instruction35mi(Opcode opcode, byte[] buffer, int bufferIndex) {
+ super(opcode);
+
+ this.regCount = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
+ this.regA = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
+ this.regD = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 4]);
+ this.regE = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 4]);
+ this.regF = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 5]);
+ this.regG = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 5]);
+ this.inlineIndex = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
+ }
+
+ protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) {
+ out.writeByte(opcode.value);
+ out.writeByte((regCount << 4) | regA);
+ out.writeShort(inlineIndex);
+ out.writeByte((regE << 4) | regD);
+ out.writeByte((regG << 4) | regF);
+ }
+
+ public Format getFormat() {
+ return Format.Format35ms;
+ }
+
+ public byte getRegCount() {
+ return regCount;
+ }
+
+ public byte getRegisterA() {
+ return regA;
+ }
+
+ public byte getRegisterD() {
+ return regD;
+ }
+
+ public byte getRegisterE() {
+ return regE;
+ }
+
+ public byte getRegisterF() {
+ return regF;
+ }
+
+ public byte getRegisterG() {
+ return regG;
+ }
+
+ public int getInlineIndex() {
+ return inlineIndex & 0xFFFF;
+ }
+
+ private static class Factory implements InstructionFactory {
+ public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
+ return new Instruction35mi(opcode, buffer, bufferIndex);
+ }
+ }
+}
+
diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rmi.java b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rmi.java
new file mode 100644
index 0000000..9e9624d
--- /dev/null
+++ b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rmi.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2011, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.jf.dexlib.Code.Format;
+
+import org.jf.dexlib.Code.*;
+import org.jf.dexlib.DexFile;
+import org.jf.dexlib.Util.AnnotatedOutput;
+import org.jf.dexlib.Util.NumberUtils;
+
+public class Instruction3rmi extends Instruction implements RegisterRangeInstruction, OdexedInvokeInline {
+ public static final InstructionFactory Factory = new Factory();
+ private byte regCount;
+ private short startReg;
+ private short inlineIndex;
+
+ public Instruction3rmi(Opcode opcode, short regCount, int startReg, int inlineIndex) {
+ super(opcode);
+
+ if (regCount >= 1 << 8) {
+ throw new RuntimeException("regCount must be less than 256");
+ }
+ if (regCount < 0) {
+ throw new RuntimeException("regCount cannot be negative");
+ }
+
+ if (startReg >= 1 << 16) {
+ throw new RuntimeException("The beginning register of the range must be less than 65536");
+ }
+ if (startReg < 0) {
+ throw new RuntimeException("The beginning register of the range cannot be negative");
+ }
+
+ if (inlineIndex >= 1 << 16) {
+ throw new RuntimeException("The method index must be less than 65536");
+ }
+
+ this.regCount = (byte)regCount;
+ this.startReg = (short)startReg;
+ this.inlineIndex = (short)inlineIndex;
+ }
+
+ private Instruction3rmi(Opcode opcode, byte[] buffer, int bufferIndex) {
+ super(opcode);
+
+ this.regCount = (byte)NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
+ this.inlineIndex = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
+ this.startReg = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4);
+ }
+
+ protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) {
+ out.writeByte(opcode.value);
+ out.writeByte(regCount);
+ out.writeShort(inlineIndex);
+ out.writeShort(startReg);
+ }
+
+ public Format getFormat() {
+ return Format.Format3rms;
+ }
+
+ public short getRegCount() {
+ return (short)(regCount & 0xFF);
+ }
+
+ public int getStartRegister() {
+ return startReg & 0xFFFF;
+ }
+
+ public int getInlineIndex() {
+ return inlineIndex & 0xFFFF;
+ }
+
+ private static class Factory implements InstructionFactory {
+ public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
+ return new Instruction3rmi(opcode, buffer, bufferIndex);
+ }
+ }
+}
diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/OdexedInvokeInline.java b/dexlib/src/main/java/org/jf/dexlib/Code/OdexedInvokeInline.java
new file mode 100644
index 0000000..1f077fa
--- /dev/null
+++ b/dexlib/src/main/java/org/jf/dexlib/Code/OdexedInvokeInline.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2011, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.jf.dexlib.Code;
+
+public interface OdexedInvokeInline {
+ int getInlineIndex();
+}
diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java b/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java
index 65dc077..24e2e2b 100644
--- a/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java
+++ b/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java
@@ -264,8 +264,8 @@
SPUT_WIDE_VOLATILE((byte)0xeb, "sput-wide-volatile", ReferenceType.field, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
THROW_VERIFICATION_ERROR((byte)0xed, "throw-verification-error", ReferenceType.none, Format.Format20bc, Opcode.ODEX_ONLY | Opcode.CAN_THROW),
- EXECUTE_INLINE((byte)0xee, "execute-inline", ReferenceType.none, Format.Format35ms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
- EXECUTE_INLINE_RANGE((byte)0xef, "execute-inline/range", ReferenceType.none, Format.Format3rms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
+ EXECUTE_INLINE((byte)0xee, "execute-inline", ReferenceType.none, Format.Format35mi, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
+ EXECUTE_INLINE_RANGE((byte)0xef, "execute-inline/range", ReferenceType.none, Format.Format3rmi, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_DIRECT_EMPTY((byte)0xf0, "invoke-direct-empty", ReferenceType.method, Format.Format35s, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
IGET_QUICK((byte)0xf2, "iget-quick", ReferenceType.none, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_WIDE_QUICK((byte)0xf3, "iget-wide-quick", ReferenceType.none, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
diff --git a/smali/src/main/antlr3/org/jf/smali/smaliLexer.g b/smali/src/main/antlr3/org/jf/smali/smaliLexer.g
index ceac954..c07970e 100644
--- a/smali/src/main/antlr3/org/jf/smali/smaliLexer.g
+++ b/smali/src/main/antlr3/org/jf/smali/smaliLexer.g
@@ -343,7 +343,10 @@
| 'class-change-error'
| 'instantiation-error';
-VTABLE_OFFSET
+INLINE_INDEX
+ : 'inline@0x' HEX_DIGIT+;
+
+VTABLE_INDEX
: 'vtable@0x' HEX_DIGIT+;
FIELD_OFFSET
@@ -663,9 +666,11 @@
INSTRUCTION_FORMAT35s_METHOD
: 'invoke-direct-empty';
+INSTRUCTION_FORMAT35mi_METHOD
+ : 'execute-inline';
+
INSTRUCTION_FORMAT35ms_METHOD
- : 'execute-inline'
- | 'invoke-virtual-quick'
+ : 'invoke-virtual-quick'
| 'invoke-super-quick';
INSTRUCTION_FORMAT3rc_METHOD
@@ -678,9 +683,11 @@
INSTRUCTION_FORMAT3rc_TYPE
: 'filled-new-array/range';
+INSTRUCTION_FORMAT3rmi_METHOD
+ : 'execute-inline/range';
+
INSTRUCTION_FORMAT3rms_METHOD
- : 'execute-inline/range'
- | 'invoke-virtual-quick/range'
+ : 'invoke-virtual-quick/range'
| 'invoke-super-quick/range';
INSTRUCTION_FORMAT51l
diff --git a/smali/src/main/antlr3/org/jf/smali/smaliParser.g b/smali/src/main/antlr3/org/jf/smali/smaliParser.g
index 942b6ca..e69e411 100644
--- a/smali/src/main/antlr3/org/jf/smali/smaliParser.g
+++ b/smali/src/main/antlr3/org/jf/smali/smaliParser.g
@@ -459,6 +459,7 @@
| INSTRUCTION_FORMAT35c_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT35c_METHOD]
| INSTRUCTION_FORMAT35c_TYPE -> SIMPLE_NAME[$INSTRUCTION_FORMAT35c_TYPE]
| INSTRUCTION_FORMAT35s_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT35s_METHOD]
+ | INSTRUCTION_FORMAT35mi_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT35mi_METHOD]
| INSTRUCTION_FORMAT35ms_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT35ms_METHOD]
| INSTRUCTION_FORMAT51l -> SIMPLE_NAME[$INSTRUCTION_FORMAT51l];
@@ -806,8 +807,13 @@
{
throwOdexedInstructionException(input, $INSTRUCTION_FORMAT35s_METHOD.text);
}
- | //e.g. invoke-virtual-range {v0, v1}, vtable@0x4
- INSTRUCTION_FORMAT35ms_METHOD OPEN_BRACE register_list CLOSE_BRACE COMMA VTABLE_OFFSET
+ | //e.g. execute-inline {v0, v1}, inline@0x4
+ INSTRUCTION_FORMAT35mi_METHOD OPEN_BRACE register_list CLOSE_BRACE COMMA INLINE_INDEX
+ {
+ throwOdexedInstructionException(input, $INSTRUCTION_FORMAT35mi_METHOD.text);
+ }
+ | //e.g. invoke-virtual-quick {v0, v1}, vtable@0x4
+ INSTRUCTION_FORMAT35ms_METHOD OPEN_BRACE register_list CLOSE_BRACE COMMA VTABLE_INDEX
{
throwOdexedInstructionException(input, $INSTRUCTION_FORMAT35ms_METHOD.text);
}
@@ -817,8 +823,13 @@
| //e.g. filled-new-array/range {v0..v6}, I
INSTRUCTION_FORMAT3rc_TYPE OPEN_BRACE register_range CLOSE_BRACE COMMA nonvoid_type_descriptor {$size = Format.Format3rc.size;}
-> ^(I_STATEMENT_FORMAT3rc_TYPE[$start, "I_STATEMENT_FORMAT3rc_TYPE"] INSTRUCTION_FORMAT3rc_TYPE register_range nonvoid_type_descriptor)
+ | //e.g. execute-inline/range {v0 .. v10}, inline@0x14
+ INSTRUCTION_FORMAT3rmi_METHOD OPEN_BRACE register_range CLOSE_BRACE COMMA INLINE_INDEX
+ {
+ throwOdexedInstructionException(input, $INSTRUCTION_FORMAT3rmi_METHOD.text);
+ }
| //e.g. invoke-virtual-quick/range {v0 .. v10}, vtable@0x14
- INSTRUCTION_FORMAT3rms_METHOD OPEN_BRACE register_range CLOSE_BRACE COMMA VTABLE_OFFSET
+ INSTRUCTION_FORMAT3rms_METHOD OPEN_BRACE register_range CLOSE_BRACE COMMA VTABLE_INDEX
{
throwOdexedInstructionException(input, $INSTRUCTION_FORMAT3rms_METHOD.text);
}
diff --git a/smali/src/main/jflex/smaliLexer.flex b/smali/src/main/jflex/smaliLexer.flex
index ab1dca9..8697b8d 100644
--- a/smali/src/main/jflex/smaliLexer.flex
+++ b/smali/src/main/jflex/smaliLexer.flex
@@ -369,7 +369,8 @@
return newToken(VERIFICATION_ERROR_TYPE);
}
- "vtable@0x" {HexDigit}+ { return newToken(VTABLE_OFFSET); }
+ "inline@0x" {HexDigit}+ { return newToken(INLINE_INDEX); }
+ "vtable@0x" {HexDigit}+ { return newToken(VTABLE_INDEX); }
"field@0x" {HexDigit}+ { return newToken(FIELD_OFFSET); }
"+" {Integer} { return newToken(OFFSET); }
@@ -536,7 +537,11 @@
return newToken(INSTRUCTION_FORMAT35s_METHOD);
}
- "execute-inline" | "invoke-virtual-quick" | "invoke-super-quick" {
+ "execute-inline" {
+ return newToken(INSTRUCTION_FORMAT35mi_METHOD);
+ }
+
+ "invoke-virtual-quick" | "invoke-super-quick" {
return newToken(INSTRUCTION_FORMAT35ms_METHOD);
}
@@ -549,7 +554,11 @@
return newToken(INSTRUCTION_FORMAT3rc_TYPE);
}
- "execute-inline/range" | "invoke-virtual-quick/range" | "invoke-super-quick/range" {
+ "execute-inline/range" {
+ return newToken(INSTRUCTION_FORMAT3rmi_METHOD);
+ }
+
+ "invoke-virtual-quick/range" | "invoke-super-quick/range" {
return newToken(INSTRUCTION_FORMAT3rms_METHOD);
}
diff --git a/smali/src/test/resources/LexerTest/InstructionTest.smali b/smali/src/test/resources/LexerTest/InstructionTest.smali
index e5fa785..7a7c335 100644
--- a/smali/src/test/resources/LexerTest/InstructionTest.smali
+++ b/smali/src/test/resources/LexerTest/InstructionTest.smali
@@ -219,6 +219,7 @@
invoke-direct/range
invoke-static/range
filled-new-array/range
+execute-inline/range
invoke-virtual-quick/range
invoke-super-quick/range
const-wide
\ No newline at end of file
diff --git a/smali/src/test/resources/LexerTest/InstructionTest.tokens b/smali/src/test/resources/LexerTest/InstructionTest.tokens
index a4b1b74..23e4895 100644
--- a/smali/src/test/resources/LexerTest/InstructionTest.tokens
+++ b/smali/src/test/resources/LexerTest/InstructionTest.tokens
@@ -211,7 +211,7 @@
INSTRUCTION_FORMAT35c_TYPE("filled-new-array")
INSTRUCTION_FORMAT35s_METHOD("invoke-direct-empty")
INSTRUCTION_FORMAT20bc("throw-verification-error")
-INSTRUCTION_FORMAT35ms_METHOD("execute-inline")
+INSTRUCTION_FORMAT35mi_METHOD("execute-inline")
INSTRUCTION_FORMAT35ms_METHOD("invoke-virtual-quick")
INSTRUCTION_FORMAT35ms_METHOD("invoke-super-quick")
INSTRUCTION_FORMAT3rc_METHOD("invoke-virtual/range")
@@ -219,6 +219,7 @@
INSTRUCTION_FORMAT3rc_METHOD("invoke-direct/range")
INSTRUCTION_FORMAT3rc_METHOD("invoke-static/range")
INSTRUCTION_FORMAT3rc_TYPE("filled-new-array/range")
+INSTRUCTION_FORMAT3rmi_METHOD("execute-inline/range")
INSTRUCTION_FORMAT3rms_METHOD("invoke-virtual-quick/range")
INSTRUCTION_FORMAT3rms_METHOD("invoke-super-quick/range")
INSTRUCTION_FORMAT51l("const-wide")
\ No newline at end of file
diff --git a/smali/src/test/resources/LexerTest/MiscTest.smali b/smali/src/test/resources/LexerTest/MiscTest.smali
index 3c280e8..32bbd27 100644
--- a/smali/src/test/resources/LexerTest/MiscTest.smali
+++ b/smali/src/test/resources/LexerTest/MiscTest.smali
@@ -45,6 +45,10 @@
class-change-error
instantiation-error
+inline@0xABCD
+inline@0x0123
+inline@0x0123ABCD
+
vtable@0xABCD
vtable@0x0123
vtable@0x0123ABCD
@@ -53,6 +57,9 @@
field@0x0123
field@0x0123ABCD
+inline@
+inline@zzz
+inline@abcd
vtable@
vtable@zzz
vtable@abcd
diff --git a/smali/src/test/resources/LexerTest/MiscTest.tokens b/smali/src/test/resources/LexerTest/MiscTest.tokens
index fda05c4..841c993 100644
--- a/smali/src/test/resources/LexerTest/MiscTest.tokens
+++ b/smali/src/test/resources/LexerTest/MiscTest.tokens
@@ -45,14 +45,21 @@
VERIFICATION_ERROR_TYPE("class-change-error")
VERIFICATION_ERROR_TYPE("instantiation-error")
-VTABLE_OFFSET("vtable@0xABCD")
-VTABLE_OFFSET("vtable@0x0123")
-VTABLE_OFFSET("vtable@0x0123ABCD")
+INLINE_INDEX("inline@0xABCD")
+INLINE_INDEX("inline@0x0123")
+INLINE_INDEX("inline@0x0123ABCD")
+
+VTABLE_INDEX("vtable@0xABCD")
+VTABLE_INDEX("vtable@0x0123")
+VTABLE_INDEX("vtable@0x0123ABCD")
FIELD_OFFSET("field@0xABCD")
FIELD_OFFSET("field@0x0123")
FIELD_OFFSET("field@0x0123ABCD")
+SIMPLE_NAME("inline") INVALID_TOKEN("@")
+SIMPLE_NAME("inline") INVALID_TOKEN("@") SIMPLE_NAME("zzz")
+SIMPLE_NAME("inline") INVALID_TOKEN("@") SIMPLE_NAME("abcd")
SIMPLE_NAME("vtable") INVALID_TOKEN("@")
SIMPLE_NAME("vtable") INVALID_TOKEN("@") SIMPLE_NAME("zzz")
SIMPLE_NAME("vtable") INVALID_TOKEN("@") SIMPLE_NAME("abcd")