mirror of
https://github.com/revanced/Apktool.git
synced 2024-11-11 23:19:23 +01:00
Updating JesusFreke smali/baksmali to v1.4.1 (API17 changes)
This commit is contained in:
parent
6b31aeb7c4
commit
9e7ccc5112
@ -34,6 +34,7 @@ import org.jf.util.IndentingWriter;
|
|||||||
import org.jf.dexlib.*;
|
import org.jf.dexlib.*;
|
||||||
import org.jf.dexlib.Code.Analysis.ValidationException;
|
import org.jf.dexlib.Code.Analysis.ValidationException;
|
||||||
import org.jf.dexlib.Code.Format.Instruction21c;
|
import org.jf.dexlib.Code.Format.Instruction21c;
|
||||||
|
import org.jf.dexlib.Code.Format.Instruction41c;
|
||||||
import org.jf.dexlib.Code.Instruction;
|
import org.jf.dexlib.Code.Instruction;
|
||||||
import org.jf.dexlib.EncodedValue.EncodedValue;
|
import org.jf.dexlib.EncodedValue.EncodedValue;
|
||||||
import org.jf.dexlib.Util.AccessFlags;
|
import org.jf.dexlib.Util.AccessFlags;
|
||||||
@ -86,6 +87,18 @@ public class ClassDefinition {
|
|||||||
fieldsSetInStaticConstructor.put(fieldIdItem.getIndex(), fieldIdItem);
|
fieldsSetInStaticConstructor.put(fieldIdItem.getIndex(), fieldIdItem);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SPUT_JUMBO:
|
||||||
|
case SPUT_BOOLEAN_JUMBO:
|
||||||
|
case SPUT_BYTE_JUMBO:
|
||||||
|
case SPUT_CHAR_JUMBO:
|
||||||
|
case SPUT_OBJECT_JUMBO:
|
||||||
|
case SPUT_SHORT_JUMBO:
|
||||||
|
case SPUT_WIDE_JUMBO: {
|
||||||
|
Instruction41c ins = (Instruction41c)instruction;
|
||||||
|
FieldIdItem fieldIdItem = (FieldIdItem)ins.getReferencedItem();
|
||||||
|
fieldsSetInStaticConstructor.put(fieldIdItem.getIndex(), fieldIdItem);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,7 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
|
|||||||
return true;
|
return true;
|
||||||
case Format21c:
|
case Format21c:
|
||||||
case Format31c:
|
case Format31c:
|
||||||
|
case Format41c:
|
||||||
writeOpcode(writer);
|
writeOpcode(writer);
|
||||||
writer.write(' ');
|
writer.write(' ');
|
||||||
writeFirstRegister(writer);
|
writeFirstRegister(writer);
|
||||||
@ -141,6 +142,7 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
|
|||||||
writeLiteral(writer);
|
writeLiteral(writer);
|
||||||
return true;
|
return true;
|
||||||
case Format22c:
|
case Format22c:
|
||||||
|
case Format52c:
|
||||||
writeOpcode(writer);
|
writeOpcode(writer);
|
||||||
writer.write(' ');
|
writer.write(' ');
|
||||||
writeFirstRegister(writer);
|
writeFirstRegister(writer);
|
||||||
@ -206,6 +208,7 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
|
|||||||
writeVtableIndex(writer);
|
writeVtableIndex(writer);
|
||||||
return true;
|
return true;
|
||||||
case Format3rc:
|
case Format3rc:
|
||||||
|
case Format5rc:
|
||||||
writeOpcode(writer);
|
writeOpcode(writer);
|
||||||
writer.write(' ');
|
writer.write(' ');
|
||||||
writeInvokeRangeRegisters(writer);
|
writeInvokeRangeRegisters(writer);
|
||||||
|
@ -49,14 +49,14 @@ public class SyntheticAccessCommentMethodItem extends MethodItem {
|
|||||||
|
|
||||||
public boolean writeTo(IndentingWriter writer) throws IOException {
|
public boolean writeTo(IndentingWriter writer) throws IOException {
|
||||||
writer.write('#');
|
writer.write('#');
|
||||||
if (accessedMember.getAccessedMemberType() == SyntheticAccessorResolver.METHOD) {
|
if (accessedMember.accessedMemberType == SyntheticAccessorResolver.METHOD) {
|
||||||
writer.write("calls: ");
|
writer.write("calls: ");
|
||||||
} else if (accessedMember.getAccessedMemberType() == SyntheticAccessorResolver.GETTER) {
|
} else if (accessedMember.accessedMemberType == SyntheticAccessorResolver.GETTER) {
|
||||||
writer.write("getter for: ");
|
writer.write("getter for: ");
|
||||||
} else {
|
} else {
|
||||||
writer.write("setter for: ");
|
writer.write("setter for: ");
|
||||||
}
|
}
|
||||||
ReferenceFormatter.writeReference(writer, accessedMember.getAccessedMember());
|
ReferenceFormatter.writeReference(writer, accessedMember.accessedMember);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ public class baksmali {
|
|||||||
boolean noParameterRegisters, boolean useLocalsDirective,
|
boolean noParameterRegisters, boolean useLocalsDirective,
|
||||||
boolean useSequentialLabels, boolean outputDebugInfo, boolean addCodeOffsets,
|
boolean useSequentialLabels, boolean outputDebugInfo, boolean addCodeOffsets,
|
||||||
boolean noAccessorComments, int registerInfo, boolean verify,
|
boolean noAccessorComments, int registerInfo, boolean verify,
|
||||||
boolean ignoreErrors, String inlineTable)
|
boolean ignoreErrors, String inlineTable, boolean checkPackagePrivateAccess)
|
||||||
{
|
{
|
||||||
baksmali.noParameterRegisters = noParameterRegisters;
|
baksmali.noParameterRegisters = noParameterRegisters;
|
||||||
baksmali.useLocalsDirective = useLocalsDirective;
|
baksmali.useLocalsDirective = useLocalsDirective;
|
||||||
@ -91,14 +91,15 @@ public class baksmali {
|
|||||||
if (extraBootClassPathArray == null && isExtJar(dexFilePath)) {
|
if (extraBootClassPathArray == null && isExtJar(dexFilePath)) {
|
||||||
extraBootClassPathArray = new String[] {"framework.jar"};
|
extraBootClassPathArray = new String[] {"framework.jar"};
|
||||||
}
|
}
|
||||||
ClassPath.InitializeClassPathFromOdex(classPathDirs, extraBootClassPathArray, dexFilePath, dexFile);
|
ClassPath.InitializeClassPathFromOdex(classPathDirs, extraBootClassPathArray, dexFilePath, dexFile,
|
||||||
|
checkPackagePrivateAccess);
|
||||||
} else {
|
} else {
|
||||||
String[] bootClassPathArray = null;
|
String[] bootClassPathArray = null;
|
||||||
if (bootClassPath != null) {
|
if (bootClassPath != null) {
|
||||||
bootClassPathArray = bootClassPath.split(":");
|
bootClassPathArray = bootClassPath.split(":");
|
||||||
}
|
}
|
||||||
ClassPath.InitializeClassPath(classPathDirs, bootClassPathArray, extraBootClassPathArray,
|
ClassPath.InitializeClassPath(classPathDirs, bootClassPathArray, extraBootClassPathArray,
|
||||||
dexFilePath, dexFile);
|
dexFilePath, dexFile, checkPackagePrivateAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inlineTable != null) {
|
if (inlineTable != null) {
|
||||||
|
@ -114,6 +114,7 @@ public class main {
|
|||||||
boolean deodex = false;
|
boolean deodex = false;
|
||||||
boolean verify = false;
|
boolean verify = false;
|
||||||
boolean ignoreErrors = false;
|
boolean ignoreErrors = false;
|
||||||
|
boolean checkPackagePrivateAccess = false;
|
||||||
|
|
||||||
int apiLevel = 14;
|
int apiLevel = 14;
|
||||||
|
|
||||||
@ -128,6 +129,7 @@ public class main {
|
|||||||
List<String> bootClassPathDirs = new ArrayList<String>();
|
List<String> bootClassPathDirs = new ArrayList<String>();
|
||||||
bootClassPathDirs.add(".");
|
bootClassPathDirs.add(".");
|
||||||
String inlineTable = null;
|
String inlineTable = null;
|
||||||
|
boolean jumboInstructions = false;
|
||||||
|
|
||||||
String[] remainingArgs = commandLine.getArgs();
|
String[] remainingArgs = commandLine.getArgs();
|
||||||
|
|
||||||
@ -219,6 +221,9 @@ public class main {
|
|||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
apiLevel = Integer.parseInt(commandLine.getOptionValue("a"));
|
apiLevel = Integer.parseInt(commandLine.getOptionValue("a"));
|
||||||
|
if (apiLevel >= 17) {
|
||||||
|
checkPackagePrivateAccess = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
disassemble = false;
|
disassemble = false;
|
||||||
@ -230,6 +235,9 @@ public class main {
|
|||||||
case 'I':
|
case 'I':
|
||||||
ignoreErrors = true;
|
ignoreErrors = true;
|
||||||
break;
|
break;
|
||||||
|
case 'J':
|
||||||
|
jumboInstructions = true;
|
||||||
|
break;
|
||||||
case 'W':
|
case 'W':
|
||||||
write = true;
|
write = true;
|
||||||
outputDexFileName = commandLine.getOptionValue("W");
|
outputDexFileName = commandLine.getOptionValue("W");
|
||||||
@ -246,6 +254,9 @@ public class main {
|
|||||||
case 'T':
|
case 'T':
|
||||||
inlineTable = commandLine.getOptionValue("T");
|
inlineTable = commandLine.getOptionValue("T");
|
||||||
break;
|
break;
|
||||||
|
case 'K':
|
||||||
|
checkPackagePrivateAccess = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert false;
|
assert false;
|
||||||
}
|
}
|
||||||
@ -265,7 +276,7 @@ public class main {
|
|||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Opcode.updateMapsForApiLevel(apiLevel);
|
Opcode.updateMapsForApiLevel(apiLevel, jumboInstructions);
|
||||||
|
|
||||||
//Read in and parse the dex file
|
//Read in and parse the dex file
|
||||||
DexFile dexFile = new DexFile(dexFileFile, !fixRegisters, false);
|
DexFile dexFile = new DexFile(dexFileFile, !fixRegisters, false);
|
||||||
@ -299,7 +310,7 @@ public class main {
|
|||||||
baksmali.disassembleDexFile(dexFileFile.getPath(), dexFile, deodex, outputDirectory,
|
baksmali.disassembleDexFile(dexFileFile.getPath(), dexFile, deodex, outputDirectory,
|
||||||
bootClassPathDirsArray, bootClassPath, extraBootClassPathEntries.toString(),
|
bootClassPathDirsArray, bootClassPath, extraBootClassPathEntries.toString(),
|
||||||
noParameterRegisters, useLocalsDirective, useSequentialLabels, outputDebugInfo, addCodeOffsets,
|
noParameterRegisters, useLocalsDirective, useSequentialLabels, outputDebugInfo, addCodeOffsets,
|
||||||
noAccessorComments, registerInfo, verify, ignoreErrors, inlineTable);
|
noAccessorComments, registerInfo, verify, ignoreErrors, inlineTable, checkPackagePrivateAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((doDump || write) && !dexFile.isOdex()) {
|
if ((doDump || write) && !dexFile.isOdex()) {
|
||||||
@ -448,6 +459,12 @@ public class main {
|
|||||||
" behavior is to stop disassembling and exit once an error is encountered")
|
" behavior is to stop disassembling and exit once an error is encountered")
|
||||||
.create("I");
|
.create("I");
|
||||||
|
|
||||||
|
Option jumboInstructionsOption = OptionBuilder.withLongOpt("jumbo-instructions")
|
||||||
|
.withDescription("adds support for the jumbo opcodes that were temporarily available around the" +
|
||||||
|
" ics timeframe. Note that support for these opcodes was removed from newer version of" +
|
||||||
|
" dalvik. You shouldn't use this option unless you know the dex file contains these jumbo" +
|
||||||
|
" opcodes.")
|
||||||
|
.create("J");
|
||||||
|
|
||||||
Option noDisassemblyOption = OptionBuilder.withLongOpt("no-disassembly")
|
Option noDisassemblyOption = OptionBuilder.withLongOpt("no-disassembly")
|
||||||
.withDescription("suppresses the output of the disassembly")
|
.withDescription("suppresses the output of the disassembly")
|
||||||
@ -495,6 +512,7 @@ public class main {
|
|||||||
|
|
||||||
debugOptions.addOption(dumpOption);
|
debugOptions.addOption(dumpOption);
|
||||||
debugOptions.addOption(ignoreErrorsOption);
|
debugOptions.addOption(ignoreErrorsOption);
|
||||||
|
debugOptions.addOption(jumboInstructionsOption);
|
||||||
debugOptions.addOption(noDisassemblyOption);
|
debugOptions.addOption(noDisassemblyOption);
|
||||||
debugOptions.addOption(writeDexOption);
|
debugOptions.addOption(writeDexOption);
|
||||||
debugOptions.addOption(sortOption);
|
debugOptions.addOption(sortOption);
|
||||||
|
@ -1 +1 @@
|
|||||||
application.version=1.4.0
|
application.version=1.4.1
|
@ -431,10 +431,9 @@ public class ClassDataItem extends Item<ClassDataItem> {
|
|||||||
* Returns the parent type for a non-empty ClassDataItem, or null for an empty one (which could be referenced by
|
* Returns the parent type for a non-empty ClassDataItem, or null for an empty one (which could be referenced by
|
||||||
* multiple ClassDefItem parents)
|
* multiple ClassDefItem parents)
|
||||||
*
|
*
|
||||||
* Specifically, the AnnotationDirectoryItem may be referenced by multiple classes if it has only class annotations,
|
* Only an empty ClassDataItem may have multiple parents.
|
||||||
* but not field/method/parameter annotations.
|
|
||||||
*
|
*
|
||||||
* @return The parent type for this AnnotationDirectoryItem, or null if it may have multiple parents
|
* @return The parent type for this ClassDefItem, or null if it may have multiple parents
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public TypeIdItem getParentType() {
|
public TypeIdItem getParentType() {
|
||||||
|
@ -48,6 +48,13 @@ public class ClassPath {
|
|||||||
|
|
||||||
private static ClassPath theClassPath = null;
|
private static ClassPath theClassPath = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current version of dalvik in master(AOSP) has a slight change to the way the
|
||||||
|
* virtual tables are computed. This should be set to true to use the new logic.
|
||||||
|
* TODO: set this based on api level, once it's present in a released version of Android
|
||||||
|
*/
|
||||||
|
private boolean checkPackagePrivateAccess;
|
||||||
|
|
||||||
private final HashMap<String, ClassDef> classDefs;
|
private final HashMap<String, ClassDef> classDefs;
|
||||||
protected ClassDef javaLangObjectClassDef; //cached ClassDef for Ljava/lang/Object;
|
protected ClassDef javaLangObjectClassDef; //cached ClassDef for Ljava/lang/Object;
|
||||||
|
|
||||||
@ -65,7 +72,8 @@ public class ClassPath {
|
|||||||
* @param dexFile The DexFile to load - it must represents an odex file
|
* @param dexFile The DexFile to load - it must represents an odex file
|
||||||
*/
|
*/
|
||||||
public static void InitializeClassPathFromOdex(String[] classPathDirs, String[] extraBootClassPathEntries,
|
public static void InitializeClassPathFromOdex(String[] classPathDirs, String[] extraBootClassPathEntries,
|
||||||
String dexFilePath, DexFile dexFile) {
|
String dexFilePath, DexFile dexFile,
|
||||||
|
boolean checkPackagePrivateAccess) {
|
||||||
if (!dexFile.isOdex()) {
|
if (!dexFile.isOdex()) {
|
||||||
throw new ExceptionWithContext("Cannot use InitialiazeClassPathFromOdex with a non-odex DexFile");
|
throw new ExceptionWithContext("Cannot use InitialiazeClassPathFromOdex with a non-odex DexFile");
|
||||||
}
|
}
|
||||||
@ -102,7 +110,8 @@ public class ClassPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
theClassPath = new ClassPath();
|
theClassPath = new ClassPath();
|
||||||
theClassPath.initClassPath(classPathDirs, bootClassPath, extraBootClassPathEntries, dexFilePath, dexFile);
|
theClassPath.initClassPath(classPathDirs, bootClassPath, extraBootClassPathEntries, dexFilePath, dexFile,
|
||||||
|
checkPackagePrivateAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,17 +120,18 @@ public class ClassPath {
|
|||||||
* @param bootClassPath A list of the boot class path entries to search for and load
|
* @param bootClassPath A list of the boot class path entries to search for and load
|
||||||
* @param dexFilePath The path of the dex file (used for error reporting purposes only)
|
* @param dexFilePath The path of the dex file (used for error reporting purposes only)
|
||||||
* @param dexFile the DexFile to load
|
* @param dexFile the DexFile to load
|
||||||
* @param errorHandler a ClassPathErrorHandler object to receive and handle any errors that occur while loading
|
|
||||||
* classes
|
* classes
|
||||||
*/
|
*/
|
||||||
public static void InitializeClassPath(String[] classPathDirs, String[] bootClassPath,
|
public static void InitializeClassPath(String[] classPathDirs, String[] bootClassPath,
|
||||||
String[] extraBootClassPathEntries, String dexFilePath, DexFile dexFile) {
|
String[] extraBootClassPathEntries, String dexFilePath, DexFile dexFile,
|
||||||
|
boolean checkPackagePrivateAccess) {
|
||||||
if (theClassPath != null) {
|
if (theClassPath != null) {
|
||||||
throw new ExceptionWithContext("Cannot initialize ClassPath multiple times");
|
throw new ExceptionWithContext("Cannot initialize ClassPath multiple times");
|
||||||
}
|
}
|
||||||
|
|
||||||
theClassPath = new ClassPath();
|
theClassPath = new ClassPath();
|
||||||
theClassPath.initClassPath(classPathDirs, bootClassPath, extraBootClassPathEntries, dexFilePath, dexFile);
|
theClassPath.initClassPath(classPathDirs, bootClassPath, extraBootClassPathEntries, dexFilePath, dexFile,
|
||||||
|
checkPackagePrivateAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassPath() {
|
private ClassPath() {
|
||||||
@ -129,7 +139,8 @@ public class ClassPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initClassPath(String[] classPathDirs, String[] bootClassPath, String[] extraBootClassPathEntries,
|
private void initClassPath(String[] classPathDirs, String[] bootClassPath, String[] extraBootClassPathEntries,
|
||||||
String dexFilePath, DexFile dexFile) {
|
String dexFilePath, DexFile dexFile, boolean checkPackagePrivateAccess) {
|
||||||
|
this.checkPackagePrivateAccess = checkPackagePrivateAccess;
|
||||||
unloadedClasses = new LinkedHashMap<String, UnresolvedClassInfo>();
|
unloadedClasses = new LinkedHashMap<String, UnresolvedClassInfo>();
|
||||||
|
|
||||||
if (bootClassPath != null) {
|
if (bootClassPath != null) {
|
||||||
@ -588,7 +599,7 @@ public class ClassPath {
|
|||||||
|
|
||||||
private final int classDepth;
|
private final int classDepth;
|
||||||
|
|
||||||
private final String[] vtable;
|
private final VirtualMethod[] vtable;
|
||||||
|
|
||||||
//this maps a method name of the form method(III)Ljava/lang/String; to an integer
|
//this maps a method name of the form method(III)Ljava/lang/String; to an integer
|
||||||
//If the value is non-negative, it is a vtable index
|
//If the value is non-negative, it is a vtable index
|
||||||
@ -611,7 +622,7 @@ public class ClassPath {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//This is only the virtual methods that this class declares itself.
|
//This is only the virtual methods that this class declares itself.
|
||||||
private String[] virtualMethods;
|
private VirtualMethod[] virtualMethods;
|
||||||
//this is a list of all the interfaces that the class implements directory, or any super interfaces of those
|
//this is a list of all the interfaces that the class implements directory, or any super interfaces of those
|
||||||
//interfaces. It is generated in such a way that it is ordered in the same way as dalvik's ClassObject.iftable,
|
//interfaces. It is generated in such a way that it is ordered in the same way as dalvik's ClassObject.iftable,
|
||||||
private LinkedHashMap<String, ClassDef> interfaceTable;
|
private LinkedHashMap<String, ClassDef> interfaceTable;
|
||||||
@ -696,7 +707,7 @@ public class ClassPath {
|
|||||||
}
|
}
|
||||||
methodLookup = new HashMap<String, Integer>((int)Math.ceil(((vtable.length + directMethodCount)/ .7f)), .75f);
|
methodLookup = new HashMap<String, Integer>((int)Math.ceil(((vtable.length + directMethodCount)/ .7f)), .75f);
|
||||||
for (int i=0; i<vtable.length; i++) {
|
for (int i=0; i<vtable.length; i++) {
|
||||||
methodLookup.put(vtable[i], i);
|
methodLookup.put(vtable[i].method, i);
|
||||||
}
|
}
|
||||||
if (directMethodCount > 0) {
|
if (directMethodCount > 0) {
|
||||||
for (int i=0; i<classInfo.directMethods.length; i++) {
|
for (int i=0; i<classInfo.directMethods.length; i++) {
|
||||||
@ -794,7 +805,7 @@ public class ClassPath {
|
|||||||
if (vtableIndex < 0 || vtableIndex >= vtable.length) {
|
if (vtableIndex < 0 || vtableIndex >= vtable.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return this.vtable[vtableIndex];
|
return this.vtable[vtableIndex].method;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void swap(byte[] fieldTypes, FieldDef[] fields, int position1, int position2) {
|
private void swap(byte[] fieldTypes, FieldDef[] fields, int position1, int position2) {
|
||||||
@ -912,19 +923,16 @@ public class ClassPath {
|
|||||||
return interfaceTable;
|
return interfaceTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] loadVtable(UnresolvedClassInfo classInfo) {
|
//TODO: check the case when we have a package private method that overrides an interface method
|
||||||
|
private VirtualMethod[] loadVtable(UnresolvedClassInfo classInfo) {
|
||||||
//TODO: it might be useful to keep track of which class's implementation is used for each virtual method. In other words, associate the implementing class type with each vtable entry
|
//TODO: it might be useful to keep track of which class's implementation is used for each virtual method. In other words, associate the implementing class type with each vtable entry
|
||||||
List<String> virtualMethodList = new LinkedList<String>();
|
List<VirtualMethod> virtualMethodList = new LinkedList<VirtualMethod>();
|
||||||
//use a temp hash table, so that we can construct the final lookup with an appropriate
|
|
||||||
//capacity, based on the number of virtual methods
|
|
||||||
HashMap<String, Integer> tempVirtualMethodLookup = new HashMap<String, Integer>();
|
|
||||||
|
|
||||||
//copy the virtual methods from the superclass
|
//copy the virtual methods from the superclass
|
||||||
int methodIndex = 0;
|
int methodIndex = 0;
|
||||||
if (superclass != null) {
|
if (superclass != null) {
|
||||||
for (String method: superclass.vtable) {
|
for (int i=0; i<superclass.vtable.length; i++) {
|
||||||
virtualMethodList.add(method);
|
virtualMethodList.add(superclass.vtable[i]);
|
||||||
tempVirtualMethodLookup.put(method, methodIndex++);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert superclass.instanceFields != null;
|
assert superclass.instanceFields != null;
|
||||||
@ -935,12 +943,7 @@ public class ClassPath {
|
|||||||
//method (i.e. if it was implemented by the superclass)
|
//method (i.e. if it was implemented by the superclass)
|
||||||
if (!this.isInterface) {
|
if (!this.isInterface) {
|
||||||
if (classInfo.virtualMethods != null) {
|
if (classInfo.virtualMethods != null) {
|
||||||
for (String virtualMethod: classInfo.virtualMethods) {
|
addToVtable(classInfo.virtualMethods, virtualMethodList);
|
||||||
if (tempVirtualMethodLookup.get(virtualMethod) == null) {
|
|
||||||
virtualMethodList.add(virtualMethod);
|
|
||||||
tempVirtualMethodLookup.put(virtualMethod, methodIndex++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interfaceTable != null) {
|
if (interfaceTable != null) {
|
||||||
@ -949,17 +952,12 @@ public class ClassPath {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String virtualMethod: interfaceDef.virtualMethods) {
|
addToVtable(interfaceDef.virtualMethods, virtualMethodList);
|
||||||
if (tempVirtualMethodLookup.get(virtualMethod) == null) {
|
|
||||||
virtualMethodList.add(virtualMethod);
|
|
||||||
tempVirtualMethodLookup.put(virtualMethod, methodIndex++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] vtable = new String[virtualMethodList.size()];
|
VirtualMethod[] vtable = new VirtualMethod[virtualMethodList.size()];
|
||||||
for (int i=0; i<virtualMethodList.size(); i++) {
|
for (int i=0; i<virtualMethodList.size(); i++) {
|
||||||
vtable[i] = virtualMethodList.get(i);
|
vtable[i] = virtualMethodList.get(i);
|
||||||
}
|
}
|
||||||
@ -967,6 +965,43 @@ public class ClassPath {
|
|||||||
return vtable;
|
return vtable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addToVtable(VirtualMethod[] localMethods, List<VirtualMethod> vtable) {
|
||||||
|
for (VirtualMethod virtualMethod: localMethods) {
|
||||||
|
boolean found = false;
|
||||||
|
for (int i=0; i<vtable.size(); i++) {
|
||||||
|
VirtualMethod superMethod = vtable.get(i);
|
||||||
|
if (superMethod.method.equals(virtualMethod.method)) {
|
||||||
|
if (!ClassPath.theClassPath.checkPackagePrivateAccess || this.canAccess(superMethod)) {
|
||||||
|
found = true;
|
||||||
|
vtable.set(i, virtualMethod);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
vtable.add(virtualMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canAccess(VirtualMethod virtualMethod) {
|
||||||
|
if (!virtualMethod.isPackagePrivate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String otherPackage = getPackage(virtualMethod.containingClass);
|
||||||
|
String ourPackage = getPackage(this.classType);
|
||||||
|
return otherPackage.equals(ourPackage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getPackage(String classType) {
|
||||||
|
int lastSlash = classType.lastIndexOf('/');
|
||||||
|
if (lastSlash < 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return classType.substring(1, lastSlash);
|
||||||
|
}
|
||||||
|
|
||||||
private int getNextFieldOffset() {
|
private int getNextFieldOffset() {
|
||||||
if (instanceFields == null || instanceFields.size() == 0) {
|
if (instanceFields == null || instanceFields.size() == 0) {
|
||||||
return 8;
|
return 8;
|
||||||
@ -1178,6 +1213,12 @@ public class ClassPath {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class VirtualMethod {
|
||||||
|
public String containingClass;
|
||||||
|
public String method;
|
||||||
|
public boolean isPackagePrivate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This aggregates the basic information about a class in an easy-to-use format, without requiring references
|
* This aggregates the basic information about a class in an easy-to-use format, without requiring references
|
||||||
* to any other class.
|
* to any other class.
|
||||||
@ -1190,7 +1231,7 @@ public class ClassPath {
|
|||||||
public final String[] interfaces;
|
public final String[] interfaces;
|
||||||
public final boolean[] staticMethods;
|
public final boolean[] staticMethods;
|
||||||
public final String[] directMethods;
|
public final String[] directMethods;
|
||||||
public final String[] virtualMethods;
|
public final VirtualMethod[] virtualMethods;
|
||||||
public final String[][] instanceFields;
|
public final String[][] instanceFields;
|
||||||
|
|
||||||
public UnresolvedClassInfo(String dexFilePath, ClassDefItem classDefItem) {
|
public UnresolvedClassInfo(String dexFilePath, ClassDefItem classDefItem) {
|
||||||
@ -1259,18 +1300,29 @@ public class ClassPath {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] loadVirtualMethods(ClassDataItem classDataItem) {
|
private VirtualMethod[] loadVirtualMethods(ClassDataItem classDataItem) {
|
||||||
List<EncodedMethod> encodedMethods = classDataItem.getVirtualMethods();
|
List<EncodedMethod> encodedMethods = classDataItem.getVirtualMethods();
|
||||||
if (encodedMethods.size() > 0) {
|
if (encodedMethods.size() > 0) {
|
||||||
String[] virtualMethods = new String[encodedMethods.size()];
|
VirtualMethod[] virtualMethods = new VirtualMethod[encodedMethods.size()];
|
||||||
for (int i=0; i<encodedMethods.size(); i++) {
|
for (int i=0; i<encodedMethods.size(); i++) {
|
||||||
virtualMethods[i] = encodedMethods.get(i).method.getShortMethodString();
|
virtualMethods[i] = new VirtualMethod();
|
||||||
|
EncodedMethod encodedMethod = encodedMethods.get(i);
|
||||||
|
|
||||||
|
virtualMethods[i].isPackagePrivate = methodIsPackagePrivate(encodedMethod.accessFlags);
|
||||||
|
virtualMethods[i].containingClass = classDataItem.getParentType().getTypeDescriptor();
|
||||||
|
virtualMethods[i].method = encodedMethods.get(i).method.getShortMethodString();
|
||||||
}
|
}
|
||||||
return virtualMethods;
|
return virtualMethods;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean methodIsPackagePrivate(int accessFlags) {
|
||||||
|
return (accessFlags & (AccessFlags.PRIVATE.getValue() |
|
||||||
|
AccessFlags.PROTECTED.getValue() |
|
||||||
|
AccessFlags.PUBLIC.getValue())) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
private String[][] loadInstanceFields(ClassDataItem classDataItem) {
|
private String[][] loadInstanceFields(ClassDataItem classDataItem) {
|
||||||
List<EncodedField> encodedFields = classDataItem.getInstanceFields();
|
List<EncodedField> encodedFields = classDataItem.getInstanceFields();
|
||||||
if (encodedFields.size() > 0) {
|
if (encodedFields.size() > 0) {
|
||||||
|
@ -135,7 +135,14 @@ public abstract class InlineMethodResolver {
|
|||||||
new DeodexUtil.InlineMethod(Static, "Ljava/lang/Float;", "intBitsToFloat", "I", "F"),
|
new DeodexUtil.InlineMethod(Static, "Ljava/lang/Float;", "intBitsToFloat", "I", "F"),
|
||||||
new DeodexUtil.InlineMethod(Static, "Ljava/lang/Double;", "doubleToLongBits", "D", "J"),
|
new DeodexUtil.InlineMethod(Static, "Ljava/lang/Double;", "doubleToLongBits", "D", "J"),
|
||||||
new DeodexUtil.InlineMethod(Static, "Ljava/lang/Double;", "doubleToRawLongBits", "D", "J"),
|
new DeodexUtil.InlineMethod(Static, "Ljava/lang/Double;", "doubleToRawLongBits", "D", "J"),
|
||||||
new DeodexUtil.InlineMethod(Static, "Ljava/lang/Double;", "longBitsToDouble", "J", "D")
|
new DeodexUtil.InlineMethod(Static, "Ljava/lang/Double;", "longBitsToDouble", "J", "D"),
|
||||||
|
new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "abs", "I", "I"),
|
||||||
|
new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "abs", "J", "J"),
|
||||||
|
new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "abs", "F", "F"),
|
||||||
|
new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "abs", "D", "D"),
|
||||||
|
new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "min", "II", "I"),
|
||||||
|
new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "max", "II", "I"),
|
||||||
|
new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "sqrt", "D", "D"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,28 +703,34 @@ public class MethodAnalyzer {
|
|||||||
analyzeConstString(analyzedInstruction);
|
analyzeConstString(analyzedInstruction);
|
||||||
return true;
|
return true;
|
||||||
case CONST_CLASS:
|
case CONST_CLASS:
|
||||||
|
case CONST_CLASS_JUMBO:
|
||||||
analyzeConstClass(analyzedInstruction);
|
analyzeConstClass(analyzedInstruction);
|
||||||
return true;
|
return true;
|
||||||
case MONITOR_ENTER:
|
case MONITOR_ENTER:
|
||||||
case MONITOR_EXIT:
|
case MONITOR_EXIT:
|
||||||
return true;
|
return true;
|
||||||
case CHECK_CAST:
|
case CHECK_CAST:
|
||||||
|
case CHECK_CAST_JUMBO:
|
||||||
analyzeCheckCast(analyzedInstruction);
|
analyzeCheckCast(analyzedInstruction);
|
||||||
return true;
|
return true;
|
||||||
case INSTANCE_OF:
|
case INSTANCE_OF:
|
||||||
|
case INSTANCE_OF_JUMBO:
|
||||||
analyzeInstanceOf(analyzedInstruction);
|
analyzeInstanceOf(analyzedInstruction);
|
||||||
return true;
|
return true;
|
||||||
case ARRAY_LENGTH:
|
case ARRAY_LENGTH:
|
||||||
analyzeArrayLength(analyzedInstruction);
|
analyzeArrayLength(analyzedInstruction);
|
||||||
return true;
|
return true;
|
||||||
case NEW_INSTANCE:
|
case NEW_INSTANCE:
|
||||||
|
case NEW_INSTANCE_JUMBO:
|
||||||
analyzeNewInstance(analyzedInstruction);
|
analyzeNewInstance(analyzedInstruction);
|
||||||
return true;
|
return true;
|
||||||
case NEW_ARRAY:
|
case NEW_ARRAY:
|
||||||
|
case NEW_ARRAY_JUMBO:
|
||||||
analyzeNewArray(analyzedInstruction);
|
analyzeNewArray(analyzedInstruction);
|
||||||
return true;
|
return true;
|
||||||
case FILLED_NEW_ARRAY:
|
case FILLED_NEW_ARRAY:
|
||||||
case FILLED_NEW_ARRAY_RANGE:
|
case FILLED_NEW_ARRAY_RANGE:
|
||||||
|
case FILLED_NEW_ARRAY_JUMBO:
|
||||||
return true;
|
return true;
|
||||||
case FILL_ARRAY_DATA:
|
case FILL_ARRAY_DATA:
|
||||||
analyzeArrayDataOrSwitch(analyzedInstruction);
|
analyzeArrayDataOrSwitch(analyzedInstruction);
|
||||||
@ -787,58 +793,86 @@ public class MethodAnalyzer {
|
|||||||
case APUT_OBJECT:
|
case APUT_OBJECT:
|
||||||
return true;
|
return true;
|
||||||
case IGET:
|
case IGET:
|
||||||
|
case IGET_JUMBO:
|
||||||
analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Integer);
|
analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Integer);
|
||||||
return true;
|
return true;
|
||||||
case IGET_BOOLEAN:
|
case IGET_BOOLEAN:
|
||||||
|
case IGET_BOOLEAN_JUMBO:
|
||||||
analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Boolean);
|
analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Boolean);
|
||||||
return true;
|
return true;
|
||||||
case IGET_BYTE:
|
case IGET_BYTE:
|
||||||
|
case IGET_BYTE_JUMBO:
|
||||||
analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Byte);
|
analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Byte);
|
||||||
return true;
|
return true;
|
||||||
case IGET_CHAR:
|
case IGET_CHAR:
|
||||||
|
case IGET_CHAR_JUMBO:
|
||||||
analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Char);
|
analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Char);
|
||||||
return true;
|
return true;
|
||||||
case IGET_SHORT:
|
case IGET_SHORT:
|
||||||
|
case IGET_SHORT_JUMBO:
|
||||||
analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Short);
|
analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Short);
|
||||||
return true;
|
return true;
|
||||||
case IGET_WIDE:
|
case IGET_WIDE:
|
||||||
|
case IGET_WIDE_JUMBO:
|
||||||
case IGET_OBJECT:
|
case IGET_OBJECT:
|
||||||
|
case IGET_OBJECT_JUMBO:
|
||||||
analyzeIgetWideObject(analyzedInstruction);
|
analyzeIgetWideObject(analyzedInstruction);
|
||||||
return true;
|
return true;
|
||||||
case IPUT:
|
case IPUT:
|
||||||
|
case IPUT_JUMBO:
|
||||||
case IPUT_BOOLEAN:
|
case IPUT_BOOLEAN:
|
||||||
|
case IPUT_BOOLEAN_JUMBO:
|
||||||
case IPUT_BYTE:
|
case IPUT_BYTE:
|
||||||
|
case IPUT_BYTE_JUMBO:
|
||||||
case IPUT_CHAR:
|
case IPUT_CHAR:
|
||||||
|
case IPUT_CHAR_JUMBO:
|
||||||
case IPUT_SHORT:
|
case IPUT_SHORT:
|
||||||
|
case IPUT_SHORT_JUMBO:
|
||||||
case IPUT_WIDE:
|
case IPUT_WIDE:
|
||||||
|
case IPUT_WIDE_JUMBO:
|
||||||
case IPUT_OBJECT:
|
case IPUT_OBJECT:
|
||||||
|
case IPUT_OBJECT_JUMBO:
|
||||||
return true;
|
return true;
|
||||||
case SGET:
|
case SGET:
|
||||||
|
case SGET_JUMBO:
|
||||||
analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Integer);
|
analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Integer);
|
||||||
return true;
|
return true;
|
||||||
case SGET_BOOLEAN:
|
case SGET_BOOLEAN:
|
||||||
|
case SGET_BOOLEAN_JUMBO:
|
||||||
analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Boolean);
|
analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Boolean);
|
||||||
return true;
|
return true;
|
||||||
case SGET_BYTE:
|
case SGET_BYTE:
|
||||||
|
case SGET_BYTE_JUMBO:
|
||||||
analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Byte);
|
analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Byte);
|
||||||
return true;
|
return true;
|
||||||
case SGET_CHAR:
|
case SGET_CHAR:
|
||||||
|
case SGET_CHAR_JUMBO:
|
||||||
analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Char);
|
analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Char);
|
||||||
return true;
|
return true;
|
||||||
case SGET_SHORT:
|
case SGET_SHORT:
|
||||||
|
case SGET_SHORT_JUMBO:
|
||||||
analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Short);
|
analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Short);
|
||||||
return true;
|
return true;
|
||||||
case SGET_WIDE:
|
case SGET_WIDE:
|
||||||
|
case SGET_WIDE_JUMBO:
|
||||||
case SGET_OBJECT:
|
case SGET_OBJECT:
|
||||||
|
case SGET_OBJECT_JUMBO:
|
||||||
analyzeSgetWideObject(analyzedInstruction);
|
analyzeSgetWideObject(analyzedInstruction);
|
||||||
return true;
|
return true;
|
||||||
case SPUT:
|
case SPUT:
|
||||||
|
case SPUT_JUMBO:
|
||||||
case SPUT_BOOLEAN:
|
case SPUT_BOOLEAN:
|
||||||
|
case SPUT_BOOLEAN_JUMBO:
|
||||||
case SPUT_BYTE:
|
case SPUT_BYTE:
|
||||||
|
case SPUT_BYTE_JUMBO:
|
||||||
case SPUT_CHAR:
|
case SPUT_CHAR:
|
||||||
|
case SPUT_CHAR_JUMBO:
|
||||||
case SPUT_SHORT:
|
case SPUT_SHORT:
|
||||||
|
case SPUT_SHORT_JUMBO:
|
||||||
case SPUT_WIDE:
|
case SPUT_WIDE:
|
||||||
|
case SPUT_WIDE_JUMBO:
|
||||||
case SPUT_OBJECT:
|
case SPUT_OBJECT:
|
||||||
|
case SPUT_OBJECT_JUMBO:
|
||||||
return true;
|
return true;
|
||||||
case INVOKE_VIRTUAL:
|
case INVOKE_VIRTUAL:
|
||||||
case INVOKE_SUPER:
|
case INVOKE_SUPER:
|
||||||
@ -849,13 +883,18 @@ public class MethodAnalyzer {
|
|||||||
case INVOKE_STATIC:
|
case INVOKE_STATIC:
|
||||||
case INVOKE_INTERFACE:
|
case INVOKE_INTERFACE:
|
||||||
case INVOKE_VIRTUAL_RANGE:
|
case INVOKE_VIRTUAL_RANGE:
|
||||||
|
case INVOKE_VIRTUAL_JUMBO:
|
||||||
case INVOKE_SUPER_RANGE:
|
case INVOKE_SUPER_RANGE:
|
||||||
|
case INVOKE_SUPER_JUMBO:
|
||||||
return true;
|
return true;
|
||||||
case INVOKE_DIRECT_RANGE:
|
case INVOKE_DIRECT_RANGE:
|
||||||
|
case INVOKE_DIRECT_JUMBO:
|
||||||
analyzeInvokeDirectRange(analyzedInstruction);
|
analyzeInvokeDirectRange(analyzedInstruction);
|
||||||
return true;
|
return true;
|
||||||
case INVOKE_STATIC_RANGE:
|
case INVOKE_STATIC_RANGE:
|
||||||
|
case INVOKE_STATIC_JUMBO:
|
||||||
case INVOKE_INTERFACE_RANGE:
|
case INVOKE_INTERFACE_RANGE:
|
||||||
|
case INVOKE_INTERFACE_JUMBO:
|
||||||
return true;
|
return true;
|
||||||
case NEG_INT:
|
case NEG_INT:
|
||||||
case NOT_INT:
|
case NOT_INT:
|
||||||
@ -1076,6 +1115,23 @@ public class MethodAnalyzer {
|
|||||||
case SPUT_OBJECT_VOLATILE:
|
case SPUT_OBJECT_VOLATILE:
|
||||||
analyzePutGetVolatile(analyzedInstruction);
|
analyzePutGetVolatile(analyzedInstruction);
|
||||||
return true;
|
return true;
|
||||||
|
case INVOKE_OBJECT_INIT_JUMBO:
|
||||||
|
analyzeInvokeObjectInitJumbo(analyzedInstruction);
|
||||||
|
return true;
|
||||||
|
case IGET_VOLATILE_JUMBO:
|
||||||
|
case IGET_WIDE_VOLATILE_JUMBO:
|
||||||
|
case IGET_OBJECT_VOLATILE_JUMBO:
|
||||||
|
case IPUT_VOLATILE_JUMBO:
|
||||||
|
case IPUT_WIDE_VOLATILE_JUMBO:
|
||||||
|
case IPUT_OBJECT_VOLATILE_JUMBO:
|
||||||
|
case SGET_VOLATILE_JUMBO:
|
||||||
|
case SGET_WIDE_VOLATILE_JUMBO:
|
||||||
|
case SGET_OBJECT_VOLATILE_JUMBO:
|
||||||
|
case SPUT_VOLATILE_JUMBO:
|
||||||
|
case SPUT_WIDE_VOLATILE_JUMBO:
|
||||||
|
case SPUT_OBJECT_VOLATILE_JUMBO:
|
||||||
|
analyzePutGetVolatile(analyzedInstruction);
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
assert false;
|
assert false;
|
||||||
return true;
|
return true;
|
||||||
@ -1141,6 +1197,7 @@ public class MethodAnalyzer {
|
|||||||
case CONST_STRING_JUMBO:
|
case CONST_STRING_JUMBO:
|
||||||
return;
|
return;
|
||||||
case CONST_CLASS:
|
case CONST_CLASS:
|
||||||
|
case CONST_CLASS_JUMBO:
|
||||||
verifyConstClass(analyzedInstruction);
|
verifyConstClass(analyzedInstruction);
|
||||||
return;
|
return;
|
||||||
case MONITOR_ENTER:
|
case MONITOR_ENTER:
|
||||||
@ -1148,15 +1205,18 @@ public class MethodAnalyzer {
|
|||||||
verifyMonitor(analyzedInstruction);
|
verifyMonitor(analyzedInstruction);
|
||||||
return;
|
return;
|
||||||
case CHECK_CAST:
|
case CHECK_CAST:
|
||||||
|
case CHECK_CAST_JUMBO:
|
||||||
verifyCheckCast(analyzedInstruction);
|
verifyCheckCast(analyzedInstruction);
|
||||||
return;
|
return;
|
||||||
case INSTANCE_OF:
|
case INSTANCE_OF:
|
||||||
|
case INSTANCE_OF_JUMBO:
|
||||||
verifyInstanceOf(analyzedInstruction);
|
verifyInstanceOf(analyzedInstruction);
|
||||||
return;
|
return;
|
||||||
case ARRAY_LENGTH:
|
case ARRAY_LENGTH:
|
||||||
verifyArrayLength(analyzedInstruction);
|
verifyArrayLength(analyzedInstruction);
|
||||||
return;
|
return;
|
||||||
case NEW_INSTANCE:
|
case NEW_INSTANCE:
|
||||||
|
case NEW_INSTANCE_JUMBO:
|
||||||
verifyNewInstance(analyzedInstruction);
|
verifyNewInstance(analyzedInstruction);
|
||||||
return;
|
return;
|
||||||
case NEW_ARRAY:
|
case NEW_ARRAY:
|
||||||
@ -1566,6 +1626,19 @@ public class MethodAnalyzer {
|
|||||||
case IPUT_OBJECT_VOLATILE:
|
case IPUT_OBJECT_VOLATILE:
|
||||||
case SGET_OBJECT_VOLATILE:
|
case SGET_OBJECT_VOLATILE:
|
||||||
case SPUT_OBJECT_VOLATILE:
|
case SPUT_OBJECT_VOLATILE:
|
||||||
|
case INVOKE_OBJECT_INIT_JUMBO:
|
||||||
|
case IGET_VOLATILE_JUMBO:
|
||||||
|
case IGET_WIDE_VOLATILE_JUMBO:
|
||||||
|
case IGET_OBJECT_VOLATILE_JUMBO:
|
||||||
|
case IPUT_VOLATILE_JUMBO:
|
||||||
|
case IPUT_WIDE_VOLATILE_JUMBO:
|
||||||
|
case IPUT_OBJECT_VOLATILE_JUMBO:
|
||||||
|
case SGET_VOLATILE_JUMBO:
|
||||||
|
case SGET_WIDE_VOLATILE_JUMBO:
|
||||||
|
case SGET_OBJECT_VOLATILE_JUMBO:
|
||||||
|
case SPUT_VOLATILE_JUMBO:
|
||||||
|
case SPUT_WIDE_VOLATILE_JUMBO:
|
||||||
|
case SPUT_OBJECT_VOLATILE_JUMBO:
|
||||||
//TODO: throw validation exception?
|
//TODO: throw validation exception?
|
||||||
default:
|
default:
|
||||||
assert false;
|
assert false;
|
||||||
@ -3622,12 +3695,23 @@ public class MethodAnalyzer {
|
|||||||
|
|
||||||
if (analyzedInstruction.instruction.opcode.isOdexedStaticVolatile()) {
|
if (analyzedInstruction.instruction.opcode.isOdexedStaticVolatile()) {
|
||||||
SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
|
SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
|
||||||
deodexedInstruction = new Instruction21c(opcode, (byte)instruction.getRegisterA(), fieldIdItem);
|
if (analyzedInstruction.instruction.opcode.format == Format.Format21c) {
|
||||||
|
deodexedInstruction = new Instruction21c(opcode, (byte)instruction.getRegisterA(), fieldIdItem);
|
||||||
|
} else {
|
||||||
|
assert(analyzedInstruction.instruction.opcode.format == Format.Format41c);
|
||||||
|
deodexedInstruction = new Instruction41c(opcode, (byte)instruction.getRegisterA(), fieldIdItem);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
|
TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
|
||||||
|
|
||||||
deodexedInstruction = new Instruction22c(opcode, (byte)instruction.getRegisterA(),
|
if (analyzedInstruction.instruction.opcode.format == Format.Format22c) {
|
||||||
(byte)instruction.getRegisterB(), fieldIdItem);
|
deodexedInstruction = new Instruction22c(opcode, (byte)instruction.getRegisterA(),
|
||||||
|
(byte)instruction.getRegisterB(), fieldIdItem);
|
||||||
|
} else {
|
||||||
|
assert(analyzedInstruction.instruction.opcode.format == Format.Format52c);
|
||||||
|
deodexedInstruction = new Instruction52c(opcode, (byte)instruction.getRegisterA(),
|
||||||
|
(byte)instruction.getRegisterB(), fieldIdItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
|
analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
|
||||||
@ -3638,6 +3722,17 @@ public class MethodAnalyzer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void analyzeInvokeObjectInitJumbo(AnalyzedInstruction analyzedInstruction) {
|
||||||
|
Instruction5rc instruction = (Instruction5rc)analyzedInstruction.instruction;
|
||||||
|
|
||||||
|
Instruction5rc deodexedInstruction = new Instruction5rc(Opcode.INVOKE_DIRECT_JUMBO,
|
||||||
|
instruction.getRegCount(), instruction.getStartRegister(), instruction.getReferencedItem());
|
||||||
|
|
||||||
|
analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
|
||||||
|
|
||||||
|
analyzeInstruction(analyzedInstruction);
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean checkArrayFieldAssignment(RegisterType.Category arrayFieldCategory,
|
private static boolean checkArrayFieldAssignment(RegisterType.Category arrayFieldCategory,
|
||||||
RegisterType.Category instructionCategory) {
|
RegisterType.Category instructionCategory) {
|
||||||
if (arrayFieldCategory == instructionCategory) {
|
if (arrayFieldCategory == instructionCategory) {
|
||||||
|
@ -178,6 +178,107 @@ public class OdexedFieldInstructionMapper {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static Opcode[][][][] jumboOpcodeMap = new Opcode[][][][] {
|
||||||
|
//get opcodes
|
||||||
|
new Opcode[][][] {
|
||||||
|
//iget volatile
|
||||||
|
new Opcode[][] {
|
||||||
|
//odexed
|
||||||
|
new Opcode[] {
|
||||||
|
/*Z*/ Opcode.IGET_VOLATILE_JUMBO,
|
||||||
|
/*B*/ Opcode.IGET_VOLATILE_JUMBO,
|
||||||
|
/*S*/ Opcode.IGET_VOLATILE_JUMBO,
|
||||||
|
/*C*/ Opcode.IGET_VOLATILE_JUMBO,
|
||||||
|
/*I,F*/ Opcode.IGET_VOLATILE_JUMBO,
|
||||||
|
/*J,D*/ Opcode.IGET_WIDE_VOLATILE_JUMBO,
|
||||||
|
/*L,[*/ Opcode.IGET_OBJECT_VOLATILE_JUMBO
|
||||||
|
},
|
||||||
|
//deodexed
|
||||||
|
new Opcode[] {
|
||||||
|
/*Z*/ Opcode.IGET_BOOLEAN_JUMBO,
|
||||||
|
/*B*/ Opcode.IGET_BYTE_JUMBO,
|
||||||
|
/*S*/ Opcode.IGET_SHORT_JUMBO,
|
||||||
|
/*C*/ Opcode.IGET_CHAR_JUMBO,
|
||||||
|
/*I,F*/ Opcode.IGET_JUMBO,
|
||||||
|
/*J,D*/ Opcode.IGET_WIDE_JUMBO,
|
||||||
|
/*L,[*/ Opcode.IGET_OBJECT_JUMBO
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//sget volatile
|
||||||
|
new Opcode[][] {
|
||||||
|
//odexed
|
||||||
|
new Opcode[] {
|
||||||
|
/*Z*/ Opcode.SGET_VOLATILE_JUMBO,
|
||||||
|
/*B*/ Opcode.SGET_VOLATILE_JUMBO,
|
||||||
|
/*S*/ Opcode.SGET_VOLATILE_JUMBO,
|
||||||
|
/*C*/ Opcode.SGET_VOLATILE_JUMBO,
|
||||||
|
/*I,F*/ Opcode.SGET_VOLATILE_JUMBO,
|
||||||
|
/*J,D*/ Opcode.SGET_WIDE_VOLATILE_JUMBO,
|
||||||
|
/*L,[*/ Opcode.SGET_OBJECT_VOLATILE_JUMBO
|
||||||
|
},
|
||||||
|
//deodexed
|
||||||
|
new Opcode[] {
|
||||||
|
/*Z*/ Opcode.SGET_BOOLEAN_JUMBO,
|
||||||
|
/*B*/ Opcode.SGET_BYTE_JUMBO,
|
||||||
|
/*S*/ Opcode.SGET_SHORT_JUMBO,
|
||||||
|
/*C*/ Opcode.SGET_CHAR_JUMBO,
|
||||||
|
/*I,F*/ Opcode.SGET_JUMBO,
|
||||||
|
/*J,D*/ Opcode.SGET_WIDE_JUMBO,
|
||||||
|
/*L,[*/ Opcode.SGET_OBJECT_JUMBO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//put opcodes
|
||||||
|
new Opcode[][][] {
|
||||||
|
//iput volatile
|
||||||
|
new Opcode[][] {
|
||||||
|
//odexed
|
||||||
|
new Opcode[] {
|
||||||
|
/*Z*/ Opcode.IPUT_VOLATILE_JUMBO,
|
||||||
|
/*B*/ Opcode.IPUT_VOLATILE_JUMBO,
|
||||||
|
/*S*/ Opcode.IPUT_VOLATILE_JUMBO,
|
||||||
|
/*C*/ Opcode.IPUT_VOLATILE_JUMBO,
|
||||||
|
/*I,F*/ Opcode.IPUT_VOLATILE_JUMBO,
|
||||||
|
/*J,D*/ Opcode.IPUT_WIDE_VOLATILE_JUMBO,
|
||||||
|
/*L,[*/ Opcode.IPUT_OBJECT_VOLATILE_JUMBO
|
||||||
|
},
|
||||||
|
//deodexed
|
||||||
|
new Opcode[] {
|
||||||
|
/*Z*/ Opcode.IPUT_BOOLEAN_JUMBO,
|
||||||
|
/*B*/ Opcode.IPUT_BYTE_JUMBO,
|
||||||
|
/*S*/ Opcode.IPUT_SHORT_JUMBO,
|
||||||
|
/*C*/ Opcode.IPUT_CHAR_JUMBO,
|
||||||
|
/*I,F*/ Opcode.IPUT_JUMBO,
|
||||||
|
/*J,D*/ Opcode.IPUT_WIDE_JUMBO,
|
||||||
|
/*L,[*/ Opcode.IPUT_OBJECT_JUMBO
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//sput volatile
|
||||||
|
new Opcode[][] {
|
||||||
|
//odexed
|
||||||
|
new Opcode[] {
|
||||||
|
/*Z*/ Opcode.SPUT_VOLATILE_JUMBO,
|
||||||
|
/*B*/ Opcode.SPUT_VOLATILE_JUMBO,
|
||||||
|
/*S*/ Opcode.SPUT_VOLATILE_JUMBO,
|
||||||
|
/*C*/ Opcode.SPUT_VOLATILE_JUMBO,
|
||||||
|
/*I,F*/ Opcode.SPUT_VOLATILE_JUMBO,
|
||||||
|
/*J,D*/ Opcode.SPUT_WIDE_VOLATILE_JUMBO,
|
||||||
|
/*L,[*/ Opcode.SPUT_OBJECT_VOLATILE_JUMBO
|
||||||
|
},
|
||||||
|
//deodexed
|
||||||
|
new Opcode[] {
|
||||||
|
/*Z*/ Opcode.SPUT_BOOLEAN_JUMBO,
|
||||||
|
/*B*/ Opcode.SPUT_BYTE_JUMBO,
|
||||||
|
/*S*/ Opcode.SPUT_SHORT_JUMBO,
|
||||||
|
/*C*/ Opcode.SPUT_CHAR_JUMBO,
|
||||||
|
/*I,F*/ Opcode.SPUT_JUMBO,
|
||||||
|
/*J,D*/ Opcode.SPUT_WIDE_JUMBO,
|
||||||
|
/*L,[*/ Opcode.SPUT_OBJECT_JUMBO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private static int getTypeIndex(char type) {
|
private static int getTypeIndex(char type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'Z':
|
case 'Z':
|
||||||
@ -214,14 +315,20 @@ public class OdexedFieldInstructionMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Opcode getAndCheckDeodexedOpcodeForOdexedOpcode(String fieldType, Opcode odexedOpcode) {
|
static Opcode getAndCheckDeodexedOpcodeForOdexedOpcode(String fieldType, Opcode odexedOpcode) {
|
||||||
|
boolean jumbo = odexedOpcode.isJumboOpcode();
|
||||||
int opcodeType = odexedOpcode.setsRegister()?0:1;
|
int opcodeType = odexedOpcode.setsRegister()?0:1;
|
||||||
int opcodeSubType = getOpcodeSubtype(odexedOpcode);
|
int opcodeSubType = getOpcodeSubtype(odexedOpcode);
|
||||||
int typeIndex = getTypeIndex(fieldType.charAt(0));
|
int typeIndex = getTypeIndex(fieldType.charAt(0));
|
||||||
|
|
||||||
Opcode correctOdexedOpcode, deodexedOpcode;
|
Opcode correctOdexedOpcode, deodexedOpcode;
|
||||||
|
|
||||||
correctOdexedOpcode = opcodeMap[opcodeType][opcodeSubType][0][typeIndex];
|
if (jumbo) {
|
||||||
deodexedOpcode = opcodeMap[opcodeType][opcodeSubType][1][typeIndex];
|
correctOdexedOpcode = jumboOpcodeMap[opcodeType][opcodeSubType-1][0][typeIndex];
|
||||||
|
deodexedOpcode = jumboOpcodeMap[opcodeType][opcodeSubType-1][1][typeIndex];
|
||||||
|
} else {
|
||||||
|
correctOdexedOpcode = opcodeMap[opcodeType][opcodeSubType][0][typeIndex];
|
||||||
|
deodexedOpcode = opcodeMap[opcodeType][opcodeSubType][1][typeIndex];
|
||||||
|
}
|
||||||
|
|
||||||
if (correctOdexedOpcode != odexedOpcode) {
|
if (correctOdexedOpcode != odexedOpcode) {
|
||||||
throw new ValidationException(String.format("Incorrect field type \"%s\" for %s", fieldType,
|
throw new ValidationException(String.format("Incorrect field type \"%s\" for %s", fieldType,
|
||||||
|
@ -90,7 +90,11 @@ public class SyntheticAccessorResolver {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
InstructionWithReference instruction = (InstructionWithReference)instructions[0];
|
InstructionWithReference instruction = (InstructionWithReference)instructions[0];
|
||||||
MethodIdItem referencedMethodIdItem = (MethodIdItem)instruction.getReferencedItem();
|
Item referencedItem = instruction.getReferencedItem();
|
||||||
|
if (!(referencedItem instanceof MethodIdItem)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
MethodIdItem referencedMethodIdItem = (MethodIdItem)referencedItem;
|
||||||
|
|
||||||
accessedMember = new AccessedMember(METHOD, referencedMethodIdItem);
|
accessedMember = new AccessedMember(METHOD, referencedMethodIdItem);
|
||||||
resolvedAccessors.put(methodIdItem, accessedMember);
|
resolvedAccessors.put(methodIdItem, accessedMember);
|
||||||
@ -102,9 +106,15 @@ public class SyntheticAccessorResolver {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Instruction22c instruction = (Instruction22c)instructions[0];
|
Instruction22c instruction = (Instruction22c)instructions[0];
|
||||||
FieldIdItem referencedFieldIdItem = (FieldIdItem)instruction.getReferencedItem();
|
Item referencedItem = instruction.getReferencedItem();
|
||||||
|
if (!(referencedItem instanceof FieldIdItem)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
FieldIdItem referencedFieldIdItem = (FieldIdItem)referencedItem;
|
||||||
|
|
||||||
if (instruction.opcode.setsRegister() || instruction.opcode.setsWideRegister()) {
|
if (instruction.opcode.setsRegister() || instruction.opcode.setsWideRegister()) {
|
||||||
|
//If the instruction sets a register, that means it is a getter - it gets the field value and
|
||||||
|
//stores it in the register
|
||||||
accessedMember = new AccessedMember(GETTER, referencedFieldIdItem);
|
accessedMember = new AccessedMember(GETTER, referencedFieldIdItem);
|
||||||
} else {
|
} else {
|
||||||
accessedMember = new AccessedMember(SETTER, referencedFieldIdItem);
|
accessedMember = new AccessedMember(SETTER, referencedFieldIdItem);
|
||||||
@ -119,20 +129,12 @@ public class SyntheticAccessorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class AccessedMember {
|
public static class AccessedMember {
|
||||||
private final int accessedMemberType;
|
public final int accessedMemberType;
|
||||||
private final Item accessedMember;
|
public final Item accessedMember;
|
||||||
|
|
||||||
public AccessedMember(int accessedMemberType, Item accessedMember) {
|
public AccessedMember(int accessedMemberType, Item accessedMember) {
|
||||||
this.accessedMemberType = accessedMemberType;
|
this.accessedMemberType = accessedMemberType;
|
||||||
this.accessedMember = accessedMember;
|
this.accessedMember = accessedMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAccessedMemberType() {
|
|
||||||
return accessedMemberType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Item getAccessedMember() {
|
|
||||||
return accessedMember;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,10 @@ public enum Format {
|
|||||||
Format3rc(Instruction3rc.Factory, 6),
|
Format3rc(Instruction3rc.Factory, 6),
|
||||||
Format3rmi(Instruction3rmi.Factory, 6),
|
Format3rmi(Instruction3rmi.Factory, 6),
|
||||||
Format3rms(Instruction3rms.Factory, 6),
|
Format3rms(Instruction3rms.Factory, 6),
|
||||||
|
Format41c(Instruction41c.Factory, 8),
|
||||||
Format51l(Instruction51l.Factory, 10),
|
Format51l(Instruction51l.Factory, 10),
|
||||||
|
Format52c(Instruction52c.Factory, 10),
|
||||||
|
Format5rc(Instruction5rc.Factory, 10),
|
||||||
ArrayData(null, -1, true),
|
ArrayData(null, -1, true),
|
||||||
PackedSwitchData(null, -1, true),
|
PackedSwitchData(null, -1, true),
|
||||||
SparseSwitchData(null, -1, true),
|
SparseSwitchData(null, -1, true),
|
||||||
|
@ -100,7 +100,11 @@ public class Instruction21c extends InstructionWithReference implements SingleRe
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Instruction31c(jumboOpcode, (short)getRegisterA(), getReferencedItem());
|
if (jumboOpcode.format == Format.Format31c) {
|
||||||
|
return new Instruction31c(jumboOpcode, (short)getRegisterA(), getReferencedItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Instruction41c(jumboOpcode, getRegisterA(), getReferencedItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Factory implements Instruction.InstructionFactory {
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
@ -37,7 +37,8 @@ import org.jf.dexlib.Item;
|
|||||||
import org.jf.dexlib.Util.AnnotatedOutput;
|
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||||
import org.jf.dexlib.Util.NumberUtils;
|
import org.jf.dexlib.Util.NumberUtils;
|
||||||
|
|
||||||
public class Instruction22c extends InstructionWithReference implements TwoRegisterInstruction {
|
public class Instruction22c extends InstructionWithReference implements TwoRegisterInstruction,
|
||||||
|
InstructionWithJumboVariant {
|
||||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
private byte regA;
|
private byte regA;
|
||||||
private byte regB;
|
private byte regB;
|
||||||
@ -88,6 +89,15 @@ public class Instruction22c extends InstructionWithReference implements TwoRegis
|
|||||||
return regB;
|
return regB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Instruction makeJumbo() {
|
||||||
|
Opcode jumboOpcode = opcode.getJumboOpcode();
|
||||||
|
if (jumboOpcode == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Instruction52c(jumboOpcode, getRegisterA(), getRegisterB(), getReferencedItem());
|
||||||
|
}
|
||||||
|
|
||||||
private static class Factory implements Instruction.InstructionFactory {
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
return new Instruction22c(dexFile, opcode, buffer, bufferIndex);
|
return new Instruction22c(dexFile, opcode, buffer, bufferIndex);
|
||||||
|
@ -41,7 +41,8 @@ import org.jf.dexlib.Util.NumberUtils;
|
|||||||
|
|
||||||
import static org.jf.dexlib.Code.Opcode.*;
|
import static org.jf.dexlib.Code.Opcode.*;
|
||||||
|
|
||||||
public class Instruction3rc extends InstructionWithReference implements RegisterRangeInstruction {
|
public class Instruction3rc extends InstructionWithReference implements RegisterRangeInstruction,
|
||||||
|
InstructionWithJumboVariant {
|
||||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
private byte regCount;
|
private byte regCount;
|
||||||
private short startReg;
|
private short startReg;
|
||||||
@ -130,6 +131,15 @@ public class Instruction3rc extends InstructionWithReference implements Register
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Instruction makeJumbo() {
|
||||||
|
Opcode jumboOpcode = opcode.getJumboOpcode();
|
||||||
|
if (jumboOpcode == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Instruction5rc(jumboOpcode, getRegCount(), getStartRegister(), getReferencedItem());
|
||||||
|
}
|
||||||
|
|
||||||
private static class Factory implements Instruction.InstructionFactory {
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
return new Instruction3rc(dexFile, opcode, buffer, bufferIndex);
|
return new Instruction3rc(dexFile, opcode, buffer, bufferIndex);
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* 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.Instruction;
|
||||||
|
import org.jf.dexlib.Code.InstructionWithReference;
|
||||||
|
import org.jf.dexlib.Code.Opcode;
|
||||||
|
import org.jf.dexlib.Code.SingleRegisterInstruction;
|
||||||
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.Item;
|
||||||
|
import org.jf.dexlib.TypeIdItem;
|
||||||
|
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||||
|
import org.jf.dexlib.Util.NumberUtils;
|
||||||
|
|
||||||
|
public class Instruction41c extends InstructionWithJumboReference implements SingleRegisterInstruction {
|
||||||
|
public static final InstructionFactory Factory = new Factory();
|
||||||
|
private short regA;
|
||||||
|
|
||||||
|
public Instruction41c(Opcode opcode, int regA, Item referencedItem) {
|
||||||
|
super(opcode, referencedItem);
|
||||||
|
|
||||||
|
if (regA >= 1 << 16) {
|
||||||
|
throw new RuntimeException("The register number must be less than v65536");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opcode == Opcode.NEW_INSTANCE_JUMBO) {
|
||||||
|
assert referencedItem instanceof TypeIdItem;
|
||||||
|
if (((TypeIdItem)referencedItem).getTypeDescriptor().charAt(0) != 'L') {
|
||||||
|
throw new RuntimeException("Only class references can be used with the new-instance/jumbo opcode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.regA = (short)regA;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction41c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
|
super(dexFile, opcode, buffer, bufferIndex);
|
||||||
|
|
||||||
|
if (opcode == Opcode.NEW_INSTANCE_JUMBO &&
|
||||||
|
((TypeIdItem)this.getReferencedItem()).getTypeDescriptor().charAt(0) != 'L') {
|
||||||
|
|
||||||
|
throw new RuntimeException("Only class references can be used with the new-instance/jumbo opcode");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.regA = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) {
|
||||||
|
out.writeByte(0xFF);
|
||||||
|
out.writeByte(opcode.value);
|
||||||
|
out.writeInt(getReferencedItem().getIndex());
|
||||||
|
out.writeShort(getRegisterA());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format41c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRegisterA() {
|
||||||
|
return regA & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
|
return new Instruction41c(dexFile, opcode, buffer, bufferIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* 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.Instruction;
|
||||||
|
import org.jf.dexlib.Code.Opcode;
|
||||||
|
import org.jf.dexlib.Code.TwoRegisterInstruction;
|
||||||
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.Item;
|
||||||
|
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||||
|
import org.jf.dexlib.Util.NumberUtils;
|
||||||
|
|
||||||
|
public class Instruction52c extends InstructionWithJumboReference implements TwoRegisterInstruction {
|
||||||
|
public static final InstructionFactory Factory = new Factory();
|
||||||
|
private short regA;
|
||||||
|
private short regB;
|
||||||
|
|
||||||
|
public Instruction52c(Opcode opcode, int regA, int regB, Item referencedItem) {
|
||||||
|
super(opcode, referencedItem);
|
||||||
|
|
||||||
|
if (regA >= 1 << 16) {
|
||||||
|
throw new RuntimeException("The register number must be less than v65536");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regB >= 1 << 16) {
|
||||||
|
throw new RuntimeException("The register number must be less than v65536");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.regA = (short)regA;
|
||||||
|
this.regB = (short)regB;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction52c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
|
super(dexFile, opcode, buffer, bufferIndex);
|
||||||
|
|
||||||
|
this.regA = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 6);
|
||||||
|
this.regB = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) {
|
||||||
|
out.writeByte(0xFF);
|
||||||
|
out.writeByte(opcode.value);
|
||||||
|
out.writeInt(getReferencedItem().getIndex());
|
||||||
|
out.writeShort(getRegisterA());
|
||||||
|
out.writeShort(getRegisterB());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format52c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRegisterA() {
|
||||||
|
return regA & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRegisterB() {
|
||||||
|
return regB & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
|
return new Instruction52c(dexFile, opcode, buffer, bufferIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* 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.Instruction;
|
||||||
|
import org.jf.dexlib.Code.InstructionWithReference;
|
||||||
|
import org.jf.dexlib.Code.Opcode;
|
||||||
|
import org.jf.dexlib.Code.RegisterRangeInstruction;
|
||||||
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.Item;
|
||||||
|
import org.jf.dexlib.MethodIdItem;
|
||||||
|
import org.jf.dexlib.TypeIdItem;
|
||||||
|
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||||
|
import org.jf.dexlib.Util.NumberUtils;
|
||||||
|
|
||||||
|
import static org.jf.dexlib.Code.Opcode.*;
|
||||||
|
|
||||||
|
public class Instruction5rc extends InstructionWithJumboReference implements RegisterRangeInstruction {
|
||||||
|
public static final InstructionFactory Factory = new Factory();
|
||||||
|
private short regCount;
|
||||||
|
private short startReg;
|
||||||
|
|
||||||
|
public Instruction5rc(Opcode opcode, int regCount, int startReg, Item referencedItem) {
|
||||||
|
super(opcode, referencedItem);
|
||||||
|
|
||||||
|
if (regCount >= 1 << 16) {
|
||||||
|
throw new RuntimeException("regCount must be less than 65536");
|
||||||
|
}
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.regCount = (short)regCount;
|
||||||
|
this.startReg = (short)startReg;
|
||||||
|
|
||||||
|
checkItem(opcode, referencedItem, regCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction5rc(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
|
super(dexFile, opcode, buffer, bufferIndex);
|
||||||
|
|
||||||
|
this.regCount = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 6);
|
||||||
|
this.startReg = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 8);
|
||||||
|
|
||||||
|
checkItem(opcode, getReferencedItem(), getRegCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) {
|
||||||
|
out.writeByte(0xff);
|
||||||
|
out.writeByte(opcode.value);
|
||||||
|
out.writeInt(this.getReferencedItem().getIndex());
|
||||||
|
out.writeShort(regCount);
|
||||||
|
out.writeShort(startReg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format5rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRegCount() {
|
||||||
|
return regCount & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStartRegister() {
|
||||||
|
return startReg & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkItem(Opcode opcode, Item item, int regCount) {
|
||||||
|
if (opcode == FILLED_NEW_ARRAY_JUMBO) {
|
||||||
|
//check data for filled-new-array/jumbo opcode
|
||||||
|
String type = ((TypeIdItem) item).getTypeDescriptor();
|
||||||
|
if (type.charAt(0) != '[') {
|
||||||
|
throw new RuntimeException("The type must be an array type");
|
||||||
|
}
|
||||||
|
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
|
||||||
|
throw new RuntimeException("The type cannot be an array of longs or doubles");
|
||||||
|
}
|
||||||
|
} else if (opcode.value >= INVOKE_VIRTUAL_JUMBO.value && opcode.value <= INVOKE_INTERFACE_JUMBO.value ||
|
||||||
|
opcode == INVOKE_OBJECT_INIT_JUMBO) {
|
||||||
|
//check data for invoke-*/range opcodes
|
||||||
|
MethodIdItem methodIdItem = (MethodIdItem) item;
|
||||||
|
int parameterRegisterCount = methodIdItem.getPrototype().getParameterRegisterCount();
|
||||||
|
if (opcode != INVOKE_STATIC_JUMBO) {
|
||||||
|
parameterRegisterCount++;
|
||||||
|
}
|
||||||
|
if (parameterRegisterCount != regCount) {
|
||||||
|
throw new RuntimeException("regCount does not match the number of arguments of the method");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
|
return new Instruction5rc(dexFile, opcode, buffer, bufferIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -62,16 +62,16 @@ public enum Opcode
|
|||||||
CONST_WIDE_HIGH16((short)0x19, "const-wide/high16", ReferenceType.none, Format.Format21h, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
CONST_WIDE_HIGH16((short)0x19, "const-wide/high16", ReferenceType.none, Format.Format21h, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||||
CONST_STRING((short)0x1a, "const-string", ReferenceType.string, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0x1b),
|
CONST_STRING((short)0x1a, "const-string", ReferenceType.string, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0x1b),
|
||||||
CONST_STRING_JUMBO((short)0x1b, "const-string/jumbo", ReferenceType.string, Format.Format31c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
CONST_STRING_JUMBO((short)0x1b, "const-string/jumbo", ReferenceType.string, Format.Format31c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||||
CONST_CLASS((short)0x1c, "const-class", ReferenceType.type, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
CONST_CLASS((short)0x1c, "const-class", ReferenceType.type, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff00),
|
||||||
MONITOR_ENTER((short)0x1d, "monitor-enter", ReferenceType.none, Format.Format11x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
MONITOR_ENTER((short)0x1d, "monitor-enter", ReferenceType.none, Format.Format11x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||||
MONITOR_EXIT((short)0x1e, "monitor-exit", ReferenceType.none, Format.Format11x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
MONITOR_EXIT((short)0x1e, "monitor-exit", ReferenceType.none, Format.Format11x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||||
CHECK_CAST((short)0x1f, "check-cast", ReferenceType.type, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
CHECK_CAST((short)0x1f, "check-cast", ReferenceType.type, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff01),
|
||||||
INSTANCE_OF((short)0x20, "instance-of", ReferenceType.type, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
INSTANCE_OF((short)0x20, "instance-of", ReferenceType.type, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff02),
|
||||||
ARRAY_LENGTH((short)0x21, "array-length", ReferenceType.none, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
ARRAY_LENGTH((short)0x21, "array-length", ReferenceType.none, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||||
NEW_INSTANCE((short)0x22, "new-instance", ReferenceType.type, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
NEW_INSTANCE((short)0x22, "new-instance", ReferenceType.type, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff03),
|
||||||
NEW_ARRAY((short)0x23, "new-array", ReferenceType.type, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
NEW_ARRAY((short)0x23, "new-array", ReferenceType.type, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff04),
|
||||||
FILLED_NEW_ARRAY((short)0x24, "filled-new-array", ReferenceType.type, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
FILLED_NEW_ARRAY((short)0x24, "filled-new-array", ReferenceType.type, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||||
FILLED_NEW_ARRAY_RANGE((short)0x25, "filled-new-array/range", ReferenceType.type, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
FILLED_NEW_ARRAY_RANGE((short)0x25, "filled-new-array/range", ReferenceType.type, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT, (short)0xff05),
|
||||||
FILL_ARRAY_DATA((short)0x26, "fill-array-data", ReferenceType.none, Format.Format31t, Opcode.CAN_CONTINUE),
|
FILL_ARRAY_DATA((short)0x26, "fill-array-data", ReferenceType.none, Format.Format31t, Opcode.CAN_CONTINUE),
|
||||||
THROW((short)0x27, "throw", ReferenceType.none, Format.Format11x, Opcode.CAN_THROW),
|
THROW((short)0x27, "throw", ReferenceType.none, Format.Format11x, Opcode.CAN_THROW),
|
||||||
GOTO((short)0x28, "goto", ReferenceType.none, Format.Format10t),
|
GOTO((short)0x28, "goto", ReferenceType.none, Format.Format10t),
|
||||||
@ -110,44 +110,44 @@ public enum Opcode
|
|||||||
APUT_BYTE((short)0x4f, "aput-byte", ReferenceType.none, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
APUT_BYTE((short)0x4f, "aput-byte", ReferenceType.none, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||||
APUT_CHAR((short)0x50, "aput-char", ReferenceType.none, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
APUT_CHAR((short)0x50, "aput-char", ReferenceType.none, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||||
APUT_SHORT((short)0x51, "aput-short", ReferenceType.none, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
APUT_SHORT((short)0x51, "aput-short", ReferenceType.none, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||||
IGET((short)0x52, "iget", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
IGET((short)0x52, "iget", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff06),
|
||||||
IGET_WIDE((short)0x53, "iget-wide", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
IGET_WIDE((short)0x53, "iget-wide", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER, (short)0xff07),
|
||||||
IGET_OBJECT((short)0x54, "iget-object", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
IGET_OBJECT((short)0x54, "iget-object", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff08),
|
||||||
IGET_BOOLEAN((short)0x55, "iget-boolean", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
IGET_BOOLEAN((short)0x55, "iget-boolean", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff09),
|
||||||
IGET_BYTE((short)0x56, "iget-byte", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
IGET_BYTE((short)0x56, "iget-byte", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff0a),
|
||||||
IGET_CHAR((short)0x57, "iget-char", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
IGET_CHAR((short)0x57, "iget-char", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff0b),
|
||||||
IGET_SHORT((short)0x58, "iget-short", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
IGET_SHORT((short)0x58, "iget-short", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff0c),
|
||||||
IPUT((short)0x59, "iput", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
IPUT((short)0x59, "iput", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff0d),
|
||||||
IPUT_WIDE((short)0x5a, "iput-wide", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
IPUT_WIDE((short)0x5a, "iput-wide", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff0e),
|
||||||
IPUT_OBJECT((short)0x5b, "iput-object", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
IPUT_OBJECT((short)0x5b, "iput-object", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff0f),
|
||||||
IPUT_BOOLEAN((short)0x5c, "iput-boolean", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
IPUT_BOOLEAN((short)0x5c, "iput-boolean", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff10),
|
||||||
IPUT_BYTE((short)0x5d, "iput-byte", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
IPUT_BYTE((short)0x5d, "iput-byte", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff11),
|
||||||
IPUT_CHAR((short)0x5e, "iput-char", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
IPUT_CHAR((short)0x5e, "iput-char", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff12),
|
||||||
IPUT_SHORT((short)0x5f, "iput-short", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
IPUT_SHORT((short)0x5f, "iput-short", ReferenceType.field, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff13),
|
||||||
SGET((short)0x60, "sget", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
SGET((short)0x60, "sget", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff14),
|
||||||
SGET_WIDE((short)0x61, "sget-wide", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
SGET_WIDE((short)0x61, "sget-wide", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER, (short)0xff15),
|
||||||
SGET_OBJECT((short)0x62, "sget-object", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
SGET_OBJECT((short)0x62, "sget-object", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff16),
|
||||||
SGET_BOOLEAN((short)0x63, "sget-boolean", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
SGET_BOOLEAN((short)0x63, "sget-boolean", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff17),
|
||||||
SGET_BYTE((short)0x64, "sget-byte", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
SGET_BYTE((short)0x64, "sget-byte", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff18),
|
||||||
SGET_CHAR((short)0x65, "sget-char", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
SGET_CHAR((short)0x65, "sget-char", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff19),
|
||||||
SGET_SHORT((short)0x66, "sget-short", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
SGET_SHORT((short)0x66, "sget-short", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0xff1a),
|
||||||
SPUT((short)0x67, "sput", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
SPUT((short)0x67, "sput", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff1b),
|
||||||
SPUT_WIDE((short)0x68, "sput-wide", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
SPUT_WIDE((short)0x68, "sput-wide", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff1c),
|
||||||
SPUT_OBJECT((short)0x69, "sput-object", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
SPUT_OBJECT((short)0x69, "sput-object", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff1d),
|
||||||
SPUT_BOOLEAN((short)0x6a, "sput-boolean", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
SPUT_BOOLEAN((short)0x6a, "sput-boolean", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff1e),
|
||||||
SPUT_BYTE((short)0x6b, "sput-byte", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
SPUT_BYTE((short)0x6b, "sput-byte", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff1f),
|
||||||
SPUT_CHAR((short)0x6c, "sput-char", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
SPUT_CHAR((short)0x6c, "sput-char", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff20),
|
||||||
SPUT_SHORT((short)0x6d, "sput-short", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
SPUT_SHORT((short)0x6d, "sput-short", ReferenceType.field, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE, (short)0xff21),
|
||||||
INVOKE_VIRTUAL((short)0x6e, "invoke-virtual", ReferenceType.method, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
INVOKE_VIRTUAL((short)0x6e, "invoke-virtual", ReferenceType.method, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||||
INVOKE_SUPER((short)0x6f, "invoke-super", ReferenceType.method, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
INVOKE_SUPER((short)0x6f, "invoke-super", ReferenceType.method, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||||
INVOKE_DIRECT((short)0x70, "invoke-direct", ReferenceType.method, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
|
INVOKE_DIRECT((short)0x70, "invoke-direct", ReferenceType.method, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
|
||||||
INVOKE_STATIC((short)0x71, "invoke-static", ReferenceType.method, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
INVOKE_STATIC((short)0x71, "invoke-static", ReferenceType.method, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||||
INVOKE_INTERFACE((short)0x72, "invoke-interface", ReferenceType.method, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
INVOKE_INTERFACE((short)0x72, "invoke-interface", ReferenceType.method, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||||
INVOKE_VIRTUAL_RANGE((short)0x74, "invoke-virtual/range", ReferenceType.method, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
INVOKE_VIRTUAL_RANGE((short)0x74, "invoke-virtual/range", ReferenceType.method, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT, (short)0xff22),
|
||||||
INVOKE_SUPER_RANGE((short)0x75, "invoke-super/range", ReferenceType.method, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
INVOKE_SUPER_RANGE((short)0x75, "invoke-super/range", ReferenceType.method, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT, (short)0xff23),
|
||||||
INVOKE_DIRECT_RANGE((short)0x76, "invoke-direct/range", ReferenceType.method, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
|
INVOKE_DIRECT_RANGE((short)0x76, "invoke-direct/range", ReferenceType.method, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE, (short)0xff24),
|
||||||
INVOKE_STATIC_RANGE((short)0x77, "invoke-static/range", ReferenceType.method, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
INVOKE_STATIC_RANGE((short)0x77, "invoke-static/range", ReferenceType.method, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT, (short)0xff25),
|
||||||
INVOKE_INTERFACE_RANGE((short)0x78, "invoke-interface/range", ReferenceType.method, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
INVOKE_INTERFACE_RANGE((short)0x78, "invoke-interface/range", ReferenceType.method, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT, (short)0xff26),
|
||||||
NEG_INT((short)0x7b, "neg-int", ReferenceType.none, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
NEG_INT((short)0x7b, "neg-int", ReferenceType.none, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||||
NOT_INT((short)0x7c, "not-int", ReferenceType.none, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
NOT_INT((short)0x7c, "not-int", ReferenceType.none, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||||
NEG_LONG((short)0x7d, "neg-long", ReferenceType.none, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
NEG_LONG((short)0x7d, "neg-long", ReferenceType.none, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||||
@ -282,7 +282,61 @@ public enum Opcode
|
|||||||
|
|
||||||
IPUT_OBJECT_VOLATILE((short)0xfc, "iput-object-volatile", ReferenceType.field, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
IPUT_OBJECT_VOLATILE((short)0xfc, "iput-object-volatile", ReferenceType.field, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||||
SGET_OBJECT_VOLATILE((short)0xfd, "sget-object-volatile", ReferenceType.field, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
SGET_OBJECT_VOLATILE((short)0xfd, "sget-object-volatile", ReferenceType.field, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||||
SPUT_OBJECT_VOLATILE((short)0xfe, "sput-object-volatile", ReferenceType.field, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE);
|
SPUT_OBJECT_VOLATILE((short)0xfe, "sput-object-volatile", ReferenceType.field, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||||
|
|
||||||
|
CONST_CLASS_JUMBO((short)0xff00, "const-class/jumbo", ReferenceType.type, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
CHECK_CAST_JUMBO((short)0xff01, "check-cast/jumbo", ReferenceType.type, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
INSTANCE_OF_JUMBO((short)0xff02, "instance-of/jumbo", ReferenceType.type, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
NEW_INSTANCE_JUMBO((short)0xff03, "new-instance/jumbo", ReferenceType.type, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
NEW_ARRAY_JUMBO((short)0xff04, "new-array/jumbo", ReferenceType.type, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
FILLED_NEW_ARRAY_JUMBO((short)0xff05, "filled-new-array/jumbo", ReferenceType.type, Format.Format5rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.JUMBO_OPCODE),
|
||||||
|
IGET_JUMBO((short)0xff06, "iget/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
IGET_WIDE_JUMBO((short)0xff07, "iget-wide/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
IGET_OBJECT_JUMBO((short)0xff08, "iget-object/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
IGET_BOOLEAN_JUMBO((short)0xff09, "iget-boolean/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
IGET_BYTE_JUMBO((short)0xff0a, "iget-byte/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
IGET_CHAR_JUMBO((short)0xff0b, "iget-char/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
IGET_SHORT_JUMBO((short)0xff0c, "iget-short/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
IPUT_JUMBO((short)0xff0d, "iput/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
IPUT_WIDE_JUMBO((short)0xff0e, "iput-wide/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
IPUT_OBJECT_JUMBO((short)0xff0f, "iput-object/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
IPUT_BOOLEAN_JUMBO((short)0xff10, "iput-boolean/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
IPUT_BYTE_JUMBO((short)0xff11, "iput-byte/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
IPUT_CHAR_JUMBO((short)0xff12, "iput-char/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
IPUT_SHORT_JUMBO((short)0xff13, "iput-short/jumbo", ReferenceType.field, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
SGET_JUMBO((short)0xff14, "sget/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
SGET_WIDE_JUMBO((short)0xff15, "sget-wide/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
SGET_OBJECT_JUMBO((short)0xff16, "sget-object/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
SGET_BOOLEAN_JUMBO((short)0xff17, "sget-boolean/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
SGET_BYTE_JUMBO((short)0xff18, "sget-byte/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
SGET_CHAR_JUMBO((short)0xff19, "sget-char/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
SGET_SHORT_JUMBO((short)0xff1a, "sget-short/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
SPUT_JUMBO((short)0xff1b, "sput/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
SPUT_WIDE_JUMBO((short)0xff1c, "sput-wide/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
SPUT_OBJECT_JUMBO((short)0xff1d, "sput-object/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
SPUT_BOOLEAN_JUMBO((short)0xff1e, "sput-boolean/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
SPUT_BYTE_JUMBO((short)0xff1f, "sput-byte/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
SPUT_CHAR_JUMBO((short)0xff20, "sput-char/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
SPUT_SHORT_JUMBO((short)0xff21, "sput-short/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
INVOKE_VIRTUAL_JUMBO((short)0xff22, "invoke-virtual/jumbo", ReferenceType.method, Format.Format5rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.JUMBO_OPCODE),
|
||||||
|
INVOKE_SUPER_JUMBO((short)0xff23, "invoke-super/jumbo", ReferenceType.method, Format.Format5rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.JUMBO_OPCODE),
|
||||||
|
INVOKE_DIRECT_JUMBO((short)0xff24, "invoke-direct/jumbo", ReferenceType.method, Format.Format5rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.JUMBO_OPCODE | Opcode.CAN_INITIALIZE_REFERENCE),
|
||||||
|
INVOKE_STATIC_JUMBO((short)0xff25, "invoke-static/jumbo", ReferenceType.method, Format.Format5rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.JUMBO_OPCODE),
|
||||||
|
INVOKE_INTERFACE_JUMBO((short)0xff26, "invoke-interface/jumbo", ReferenceType.method, Format.Format5rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.JUMBO_OPCODE),
|
||||||
|
|
||||||
|
INVOKE_OBJECT_INIT_JUMBO((short)0xfff2, "invoke-object-init/jumbo", ReferenceType.method, Format.Format5rc, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.JUMBO_OPCODE | Opcode.CAN_INITIALIZE_REFERENCE),
|
||||||
|
IGET_VOLATILE_JUMBO((short)0xfff3, "iget-volatile/jumbo", ReferenceType.field, Format.Format52c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
IGET_WIDE_VOLATILE_JUMBO((short)0xfff4, "iget-wide-volatile/jumbo", ReferenceType.field, Format.Format52c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
IGET_OBJECT_VOLATILE_JUMBO((short)0xfff5, "iget-object-volatile/jumbo", ReferenceType.field, Format.Format52c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
IPUT_VOLATILE_JUMBO((short)0xfff6, "iput-volatile/jumbo", ReferenceType.field, Format.Format52c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
IPUT_WIDE_VOLATILE_JUMBO((short)0xfff7, "iput-wide-volatile/jumbo", ReferenceType.field, Format.Format52c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
IPUT_OBJECT_VOLATILE_JUMBO((short)0xfff8, "iput-object-volatile/jumbo", ReferenceType.field, Format.Format52c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
SGET_VOLATILE_JUMBO((short)0xfff9, "sget-volatile/jumbo", ReferenceType.field, Format.Format41c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
SGET_WIDE_VOLATILE_JUMBO((short)0xfffa, "sget-wide-volatile/jumbo", ReferenceType.field, Format.Format41c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
SGET_OBJECT_VOLATILE_JUMBO((short)0xfffb, "sget-object-volatile/jumbo", ReferenceType.field, Format.Format41c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
|
||||||
|
SPUT_VOLATILE_JUMBO((short)0xfffc, "sput-volatile/jumbo", ReferenceType.field, Format.Format41c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
SPUT_WIDE_VOLATILE_JUMBO((short)0xfffd, "sput-wide-volatile/jumbo", ReferenceType.field, Format.Format41c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
|
||||||
|
SPUT_OBJECT_VOLATILE_JUMBO((short)0xfffe, "sput-object-volatile/jumbo", ReferenceType.field, Format.Format41c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE);
|
||||||
|
|
||||||
private static Opcode[] opcodesByValue;
|
private static Opcode[] opcodesByValue;
|
||||||
private static Opcode[] expandedOpcodesByValue;
|
private static Opcode[] expandedOpcodesByValue;
|
||||||
@ -372,7 +426,7 @@ public enum Opcode
|
|||||||
* based on the idiosyncrasies of that api level
|
* based on the idiosyncrasies of that api level
|
||||||
* @param apiLevel
|
* @param apiLevel
|
||||||
*/
|
*/
|
||||||
public static void updateMapsForApiLevel(int apiLevel) {
|
public static void updateMapsForApiLevel(int apiLevel, boolean includeJumbo) {
|
||||||
if (apiLevel < 5) {
|
if (apiLevel < 5) {
|
||||||
removeOpcodes(THROW_VERIFICATION_ERROR);
|
removeOpcodes(THROW_VERIFICATION_ERROR);
|
||||||
}
|
}
|
||||||
@ -391,6 +445,21 @@ public enum Opcode
|
|||||||
removeOpcodes(INVOKE_OBJECT_INIT_RANGE);
|
removeOpcodes(INVOKE_OBJECT_INIT_RANGE);
|
||||||
addOpcodes(INVOKE_DIRECT_EMPTY);
|
addOpcodes(INVOKE_DIRECT_EMPTY);
|
||||||
}
|
}
|
||||||
|
if (apiLevel < 14 || !includeJumbo) {
|
||||||
|
removeOpcodes(CONST_CLASS_JUMBO, CHECK_CAST_JUMBO, INSTANCE_OF_JUMBO, NEW_INSTANCE_JUMBO,
|
||||||
|
NEW_ARRAY_JUMBO, FILLED_NEW_ARRAY_JUMBO, IGET_JUMBO, IGET_WIDE_JUMBO, IGET_OBJECT_JUMBO,
|
||||||
|
IGET_BOOLEAN_JUMBO, IGET_BYTE_JUMBO, IGET_CHAR_JUMBO, IGET_SHORT_JUMBO, IPUT_JUMBO, IPUT_WIDE_JUMBO,
|
||||||
|
IPUT_OBJECT_JUMBO, IPUT_BOOLEAN_JUMBO, IPUT_BYTE_JUMBO, IPUT_CHAR_JUMBO, IPUT_SHORT_JUMBO,
|
||||||
|
SGET_JUMBO, SGET_WIDE_JUMBO, SGET_OBJECT_JUMBO, SGET_BOOLEAN_JUMBO, SGET_BYTE_JUMBO,
|
||||||
|
SGET_CHAR_JUMBO, SGET_SHORT_JUMBO, SPUT_JUMBO, SPUT_WIDE_JUMBO, SPUT_OBJECT_JUMBO,
|
||||||
|
SPUT_BOOLEAN_JUMBO, SPUT_BYTE_JUMBO, SPUT_CHAR_JUMBO, SPUT_SHORT_JUMBO, INVOKE_VIRTUAL_JUMBO,
|
||||||
|
INVOKE_SUPER_JUMBO, INVOKE_DIRECT_JUMBO, INVOKE_STATIC_JUMBO, INVOKE_INTERFACE_JUMBO,
|
||||||
|
INVOKE_OBJECT_INIT_JUMBO, IGET_VOLATILE_JUMBO, IGET_WIDE_VOLATILE_JUMBO,
|
||||||
|
IGET_OBJECT_VOLATILE_JUMBO, IPUT_VOLATILE_JUMBO, IPUT_WIDE_VOLATILE_JUMBO,
|
||||||
|
IPUT_OBJECT_VOLATILE_JUMBO, SGET_VOLATILE_JUMBO, SGET_WIDE_VOLATILE_JUMBO,
|
||||||
|
SGET_OBJECT_VOLATILE_JUMBO, SPUT_VOLATILE_JUMBO, SPUT_WIDE_VOLATILE_JUMBO,
|
||||||
|
SPUT_OBJECT_VOLATILE_JUMBO);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final short value;
|
public final short value;
|
||||||
|
@ -253,7 +253,13 @@ tokens {
|
|||||||
I_STATEMENT_FORMAT35c_TYPE;
|
I_STATEMENT_FORMAT35c_TYPE;
|
||||||
I_STATEMENT_FORMAT3rc_METHOD;
|
I_STATEMENT_FORMAT3rc_METHOD;
|
||||||
I_STATEMENT_FORMAT3rc_TYPE;
|
I_STATEMENT_FORMAT3rc_TYPE;
|
||||||
|
I_STATEMENT_FORMAT41c_TYPE;
|
||||||
|
I_STATEMENT_FORMAT41c_FIELD;
|
||||||
I_STATEMENT_FORMAT51l;
|
I_STATEMENT_FORMAT51l;
|
||||||
|
I_STATEMENT_FORMAT52c_TYPE;
|
||||||
|
I_STATEMENT_FORMAT52c_FIELD;
|
||||||
|
I_STATEMENT_FORMAT5rc_METHOD;
|
||||||
|
I_STATEMENT_FORMAT5rc_TYPE;
|
||||||
I_STATEMENT_ARRAY_DATA;
|
I_STATEMENT_ARRAY_DATA;
|
||||||
I_STATEMENT_PACKED_SWITCH;
|
I_STATEMENT_PACKED_SWITCH;
|
||||||
I_STATEMENT_SPARSE_SWITCH;
|
I_STATEMENT_SPARSE_SWITCH;
|
||||||
@ -858,7 +864,16 @@ instruction returns [int size]
|
|||||||
| insn_format3rc_type { $size = $insn_format3rc_type.size; }
|
| insn_format3rc_type { $size = $insn_format3rc_type.size; }
|
||||||
| insn_format3rmi_method { $size = $insn_format3rmi_method.size; }
|
| insn_format3rmi_method { $size = $insn_format3rmi_method.size; }
|
||||||
| insn_format3rms_method { $size = $insn_format3rms_method.size; }
|
| insn_format3rms_method { $size = $insn_format3rms_method.size; }
|
||||||
|
| insn_format41c_type { $size = $insn_format41c_type.size; }
|
||||||
|
| insn_format41c_field { $size = $insn_format41c_field.size; }
|
||||||
|
| insn_format41c_field_odex { $size = $insn_format41c_field_odex.size; }
|
||||||
| insn_format51l { $size = $insn_format51l.size; }
|
| insn_format51l { $size = $insn_format51l.size; }
|
||||||
|
| insn_format52c_type { $size = $insn_format52c_type.size; }
|
||||||
|
| insn_format52c_field { $size = $insn_format52c_field.size; }
|
||||||
|
| insn_format52c_field_odex { $size = $insn_format52c_field_odex.size; }
|
||||||
|
| insn_format5rc_method { $size = $insn_format5rc_method.size; }
|
||||||
|
| insn_format5rc_method_odex { $size = $insn_format5rc_method_odex.size; }
|
||||||
|
| insn_format5rc_type { $size = $insn_format5rc_type.size; }
|
||||||
| insn_array_data_directive { $size = $insn_array_data_directive.size; }
|
| insn_array_data_directive { $size = $insn_array_data_directive.size; }
|
||||||
| insn_packed_switch_directive { $size = $insn_packed_switch_directive.size; }
|
| insn_packed_switch_directive { $size = $insn_packed_switch_directive.size; }
|
||||||
| insn_sparse_switch_directive { $size = $insn_sparse_switch_directive.size; };
|
| insn_sparse_switch_directive { $size = $insn_sparse_switch_directive.size; };
|
||||||
@ -1106,11 +1121,62 @@ insn_format3rms_method returns [int size]
|
|||||||
throwOdexedInstructionException(input, $INSTRUCTION_FORMAT3rms_METHOD.text);
|
throwOdexedInstructionException(input, $INSTRUCTION_FORMAT3rms_METHOD.text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
insn_format41c_type returns [int size]
|
||||||
|
: //e.g. const-class/jumbo v2, Lorg/jf/HelloWorld2/HelloWorld2;
|
||||||
|
INSTRUCTION_FORMAT41c_TYPE REGISTER COMMA reference_type_descriptor {$size = Format.Format41c.size;}
|
||||||
|
-> ^(I_STATEMENT_FORMAT41c_TYPE[$start, "I_STATEMENT_FORMAT41c"] INSTRUCTION_FORMAT41c_TYPE REGISTER reference_type_descriptor);
|
||||||
|
|
||||||
|
insn_format41c_field returns [int size]
|
||||||
|
: //e.g. sget-object/jumbo v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD REGISTER COMMA fully_qualified_field {$size = Format.Format41c.size;}
|
||||||
|
-> ^(I_STATEMENT_FORMAT41c_FIELD[$start, "I_STATEMENT_FORMAT41c_FIELD"] INSTRUCTION_FORMAT41c_FIELD REGISTER fully_qualified_field);
|
||||||
|
|
||||||
|
insn_format41c_field_odex returns [int size]
|
||||||
|
: //e.g. sget-object-volatile/jumbo v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD_ODEX REGISTER COMMA fully_qualified_field {$size = Format.Format41c.size;}
|
||||||
|
{
|
||||||
|
throwOdexedInstructionException(input, $INSTRUCTION_FORMAT41c_FIELD_ODEX.text);
|
||||||
|
};
|
||||||
|
|
||||||
insn_format51l returns [int size]
|
insn_format51l returns [int size]
|
||||||
: //e.g. const-wide v0, 5000000000L
|
: //e.g. const-wide v0, 5000000000L
|
||||||
INSTRUCTION_FORMAT51l REGISTER COMMA fixed_literal {$size = Format.Format51l.size;}
|
INSTRUCTION_FORMAT51l REGISTER COMMA fixed_literal {$size = Format.Format51l.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT51l[$start, "I_STATEMENT_FORMAT51l"] INSTRUCTION_FORMAT51l REGISTER fixed_literal);
|
-> ^(I_STATEMENT_FORMAT51l[$start, "I_STATEMENT_FORMAT51l"] INSTRUCTION_FORMAT51l REGISTER fixed_literal);
|
||||||
|
|
||||||
|
insn_format52c_type returns [int size]
|
||||||
|
: //e.g. instance-of/jumbo v0, v1, Ljava/lang/String;
|
||||||
|
INSTRUCTION_FORMAT52c_TYPE REGISTER COMMA REGISTER COMMA nonvoid_type_descriptor {$size = Format.Format52c.size;}
|
||||||
|
-> ^(I_STATEMENT_FORMAT52c_TYPE[$start, "I_STATEMENT_FORMAT52c_TYPE"] INSTRUCTION_FORMAT52c_TYPE REGISTER REGISTER nonvoid_type_descriptor);
|
||||||
|
|
||||||
|
insn_format52c_field returns [int size]
|
||||||
|
: //e.g. iput-object/jumbo v1, v0 Lorg/jf/HelloWorld2/HelloWorld2;->helloWorld:Ljava/lang/String;
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD REGISTER COMMA REGISTER COMMA fully_qualified_field {$size = Format.Format52c.size;}
|
||||||
|
-> ^(I_STATEMENT_FORMAT52c_FIELD[$start, "I_STATEMENT_FORMAT52c_FIELD"] INSTRUCTION_FORMAT52c_FIELD REGISTER REGISTER fully_qualified_field);
|
||||||
|
|
||||||
|
insn_format52c_field_odex returns [int size]
|
||||||
|
: //e.g. iput-object-volatile/jumbo v1, v0 Lorg/jf/HelloWorld2/HelloWorld2;->helloWorld:Ljava/lang/String;
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD_ODEX REGISTER COMMA REGISTER COMMA fully_qualified_field {$size = Format.Format52c.size;}
|
||||||
|
{
|
||||||
|
throwOdexedInstructionException(input, $INSTRUCTION_FORMAT52c_FIELD_ODEX.text);
|
||||||
|
};
|
||||||
|
|
||||||
|
insn_format5rc_method returns [int size]
|
||||||
|
: //e.g. invoke-virtual/jumbo {v25..v26}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
INSTRUCTION_FORMAT5rc_METHOD OPEN_BRACE register_range CLOSE_BRACE COMMA fully_qualified_method {$size = Format.Format5rc.size;}
|
||||||
|
-> ^(I_STATEMENT_FORMAT5rc_METHOD[$start, "I_STATEMENT_FORMAT5rc_METHOD"] INSTRUCTION_FORMAT5rc_METHOD register_range fully_qualified_method);
|
||||||
|
|
||||||
|
insn_format5rc_method_odex returns [int size]
|
||||||
|
: //e.g. invoke-object-init/jumbo {v25}, Ljava/lang/Object-><init>()V
|
||||||
|
INSTRUCTION_FORMAT5rc_METHOD_ODEX OPEN_BRACE register_range CLOSE_BRACE COMMA fully_qualified_method {$size = Format.Format5rc.size;}
|
||||||
|
{
|
||||||
|
throwOdexedInstructionException(input, $INSTRUCTION_FORMAT5rc_METHOD_ODEX.text);
|
||||||
|
};
|
||||||
|
|
||||||
|
insn_format5rc_type returns [int size]
|
||||||
|
: //e.g. filled-new-array/jumbo {v0..v6}, I
|
||||||
|
INSTRUCTION_FORMAT5rc_TYPE OPEN_BRACE register_range CLOSE_BRACE COMMA nonvoid_type_descriptor {$size = Format.Format5rc.size;}
|
||||||
|
-> ^(I_STATEMENT_FORMAT5rc_TYPE[$start, "I_STATEMENT_FORMAT5rc_TYPE"] INSTRUCTION_FORMAT5rc_TYPE register_range nonvoid_type_descriptor);
|
||||||
|
|
||||||
insn_array_data_directive returns [int size]
|
insn_array_data_directive returns [int size]
|
||||||
@init {boolean needsNop = false;}
|
@init {boolean needsNop = false;}
|
||||||
: ARRAY_DATA_DIRECTIVE
|
: ARRAY_DATA_DIRECTIVE
|
||||||
|
@ -938,7 +938,13 @@ instruction[int totalMethodRegisters, int methodParameterRegisters, List<Instruc
|
|||||||
| insn_format35c_type[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format35c_type.outRegisters; }
|
| insn_format35c_type[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format35c_type.outRegisters; }
|
||||||
| insn_format3rc_method[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format3rc_method.outRegisters; }
|
| insn_format3rc_method[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format3rc_method.outRegisters; }
|
||||||
| insn_format3rc_type[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format3rc_type.outRegisters; }
|
| insn_format3rc_type[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format3rc_type.outRegisters; }
|
||||||
|
| insn_format41c_type[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format41c_type.outRegisters; }
|
||||||
|
| insn_format41c_field[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format41c_field.outRegisters; }
|
||||||
| insn_format51l_type[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format51l_type.outRegisters; }
|
| insn_format51l_type[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format51l_type.outRegisters; }
|
||||||
|
| insn_format52c_type[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format52c_type.outRegisters; }
|
||||||
|
| insn_format52c_field[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format52c_field.outRegisters; }
|
||||||
|
| insn_format5rc_method[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format5rc_method.outRegisters; }
|
||||||
|
| insn_format5rc_type[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_format5rc_type.outRegisters; }
|
||||||
| insn_array_data_directive[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_array_data_directive.outRegisters; }
|
| insn_array_data_directive[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_array_data_directive.outRegisters; }
|
||||||
| insn_packed_switch_directive[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_packed_switch_directive.outRegisters; }
|
| insn_packed_switch_directive[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_packed_switch_directive.outRegisters; }
|
||||||
| insn_sparse_switch_directive[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_sparse_switch_directive.outRegisters; };
|
| insn_sparse_switch_directive[$totalMethodRegisters, $methodParameterRegisters, $instructions] { $outRegisters = $insn_sparse_switch_directive.outRegisters; };
|
||||||
@ -1320,6 +1326,30 @@ insn_format3rc_type[int totalMethodRegisters, int methodParameterRegisters, List
|
|||||||
$instructions.add(new Instruction3rc(opcode, (short)registerCount, startRegister, typeIdItem));
|
$instructions.add(new Instruction3rc(opcode, (short)registerCount, startRegister, typeIdItem));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
insn_format41c_type[int totalMethodRegisters, int methodParameterRegisters, List<Instruction> instructions] returns[int outRegisters]
|
||||||
|
: //e.g. const-class/jumbo v2, org/jf/HelloWorld2/HelloWorld2
|
||||||
|
^(I_STATEMENT_FORMAT41c_TYPE INSTRUCTION_FORMAT41c_TYPE REGISTER reference_type_descriptor)
|
||||||
|
{
|
||||||
|
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT41c_TYPE.text);
|
||||||
|
int regA = parseRegister_short($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
|
|
||||||
|
TypeIdItem typeIdItem = $reference_type_descriptor.type;
|
||||||
|
|
||||||
|
$instructions.add(new Instruction41c(opcode, regA, typeIdItem));
|
||||||
|
};
|
||||||
|
|
||||||
|
insn_format41c_field[int totalMethodRegisters, int methodParameterRegisters, List<Instruction> instructions] returns[int outRegisters]
|
||||||
|
: //e.g. sget-object/jumbo v0, Ljava/lang/System;->out:LJava/io/PrintStream;
|
||||||
|
^(I_STATEMENT_FORMAT41c_FIELD INSTRUCTION_FORMAT41c_FIELD REGISTER fully_qualified_field)
|
||||||
|
{
|
||||||
|
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT41c_FIELD.text);
|
||||||
|
int regA = parseRegister_short($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
|
|
||||||
|
FieldIdItem fieldIdItem = $fully_qualified_field.fieldIdItem;
|
||||||
|
|
||||||
|
$instructions.add(new Instruction41c(opcode, regA, fieldIdItem));
|
||||||
|
};
|
||||||
|
|
||||||
insn_format51l_type[int totalMethodRegisters, int methodParameterRegisters, List<Instruction> instructions] returns[int outRegisters]
|
insn_format51l_type[int totalMethodRegisters, int methodParameterRegisters, List<Instruction> instructions] returns[int outRegisters]
|
||||||
: //e.g. const-wide v0, 5000000000L
|
: //e.g. const-wide v0, 5000000000L
|
||||||
^(I_STATEMENT_FORMAT51l INSTRUCTION_FORMAT51l REGISTER fixed_64bit_literal)
|
^(I_STATEMENT_FORMAT51l INSTRUCTION_FORMAT51l REGISTER fixed_64bit_literal)
|
||||||
@ -1332,6 +1362,64 @@ insn_format51l_type[int totalMethodRegisters, int methodParameterRegisters, List
|
|||||||
$instructions.add(new Instruction51l(opcode, regA, litB));
|
$instructions.add(new Instruction51l(opcode, regA, litB));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
insn_format52c_type[int totalMethodRegisters, int methodParameterRegisters, List<Instruction> instructions] returns[int outRegisters]
|
||||||
|
: //e.g. instance-of/jumbo v0, v1, Ljava/lang/String;
|
||||||
|
^(I_STATEMENT_FORMAT52c_TYPE INSTRUCTION_FORMAT52c_TYPE registerA=REGISTER registerB=REGISTER nonvoid_type_descriptor)
|
||||||
|
{
|
||||||
|
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT52c_TYPE.text);
|
||||||
|
int regA = parseRegister_short($registerA.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
|
int regB = parseRegister_short($registerB.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
|
|
||||||
|
TypeIdItem typeIdItem = $nonvoid_type_descriptor.type;
|
||||||
|
|
||||||
|
$instructions.add(new Instruction52c(opcode, regA, regB, typeIdItem));
|
||||||
|
};
|
||||||
|
|
||||||
|
insn_format52c_field[int totalMethodRegisters, int methodParameterRegisters, List<Instruction> instructions] returns[int outRegisters]
|
||||||
|
: //e.g. iput-object/jumbo v1, v0, Lorg/jf/HelloWorld2/HelloWorld2;->helloWorld:Ljava/lang/String;
|
||||||
|
^(I_STATEMENT_FORMAT52c_FIELD INSTRUCTION_FORMAT52c_FIELD registerA=REGISTER registerB=REGISTER fully_qualified_field)
|
||||||
|
{
|
||||||
|
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT52c_FIELD.text);
|
||||||
|
int regA = parseRegister_short($registerA.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
|
int regB = parseRegister_short($registerB.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
|
|
||||||
|
FieldIdItem fieldIdItem = $fully_qualified_field.fieldIdItem;
|
||||||
|
|
||||||
|
$instructions.add(new Instruction52c(opcode, regA, regB, fieldIdItem));
|
||||||
|
};
|
||||||
|
|
||||||
|
insn_format5rc_method[int totalMethodRegisters, int methodParameterRegisters, List<Instruction> instructions] returns[int outRegisters]
|
||||||
|
: //e.g. invoke-virtual/jumbo {v25..v26} java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
^(I_STATEMENT_FORMAT5rc_METHOD INSTRUCTION_FORMAT5rc_METHOD register_range[$totalMethodRegisters, $methodParameterRegisters] fully_qualified_method)
|
||||||
|
{
|
||||||
|
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT5rc_METHOD.text);
|
||||||
|
int startRegister = $register_range.startRegister;
|
||||||
|
int endRegister = $register_range.endRegister;
|
||||||
|
|
||||||
|
int registerCount = endRegister-startRegister+1;
|
||||||
|
$outRegisters = registerCount;
|
||||||
|
|
||||||
|
MethodIdItem methodIdItem = $fully_qualified_method.methodIdItem;
|
||||||
|
|
||||||
|
$instructions.add(new Instruction5rc(opcode, registerCount, startRegister, methodIdItem));
|
||||||
|
};
|
||||||
|
|
||||||
|
insn_format5rc_type[int totalMethodRegisters, int methodParameterRegisters, List<Instruction> instructions] returns[int outRegisters]
|
||||||
|
: //e.g. filled-new-array/jumbo {v0..v6} I
|
||||||
|
^(I_STATEMENT_FORMAT5rc_TYPE INSTRUCTION_FORMAT5rc_TYPE register_range[$totalMethodRegisters, $methodParameterRegisters] nonvoid_type_descriptor)
|
||||||
|
{
|
||||||
|
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT5rc_TYPE.text);
|
||||||
|
int startRegister = $register_range.startRegister;
|
||||||
|
int endRegister = $register_range.endRegister;
|
||||||
|
|
||||||
|
int registerCount = endRegister-startRegister+1;
|
||||||
|
$outRegisters = registerCount;
|
||||||
|
|
||||||
|
TypeIdItem typeIdItem = $nonvoid_type_descriptor.type;
|
||||||
|
|
||||||
|
$instructions.add(new Instruction5rc(opcode, registerCount, startRegister, typeIdItem));
|
||||||
|
};
|
||||||
|
|
||||||
insn_array_data_directive[int totalMethodRegisters, int methodParameterRegisters, List<Instruction> instructions] returns[int outRegisters]
|
insn_array_data_directive[int totalMethodRegisters, int methodParameterRegisters, List<Instruction> instructions] returns[int outRegisters]
|
||||||
: //e.g. .array-data 4 1000000 .end array-data
|
: //e.g. .array-data 4 1000000 .end array-data
|
||||||
^(I_STATEMENT_ARRAY_DATA ^(I_ARRAY_ELEMENT_SIZE short_integral_literal) array_elements)
|
^(I_STATEMENT_ARRAY_DATA ^(I_ARRAY_ELEMENT_SIZE short_integral_literal) array_elements)
|
||||||
|
@ -100,7 +100,7 @@ public class main {
|
|||||||
|
|
||||||
boolean allowOdex = false;
|
boolean allowOdex = false;
|
||||||
boolean sort = false;
|
boolean sort = false;
|
||||||
boolean fixJumbo = true;
|
boolean jumboInstructions = false;
|
||||||
boolean fixGoto = true;
|
boolean fixGoto = true;
|
||||||
boolean verboseErrors = false;
|
boolean verboseErrors = false;
|
||||||
boolean printTokens = false;
|
boolean printTokens = false;
|
||||||
@ -149,7 +149,7 @@ public class main {
|
|||||||
sort = true;
|
sort = true;
|
||||||
break;
|
break;
|
||||||
case 'J':
|
case 'J':
|
||||||
fixJumbo = false;
|
jumboInstructions = true;
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
fixGoto = false;
|
fixGoto = false;
|
||||||
@ -187,7 +187,7 @@ public class main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Opcode.updateMapsForApiLevel(apiLevel);
|
Opcode.updateMapsForApiLevel(apiLevel, jumboInstructions);
|
||||||
|
|
||||||
DexFile dexFile = new DexFile();
|
DexFile dexFile = new DexFile();
|
||||||
|
|
||||||
@ -212,8 +212,8 @@ public class main {
|
|||||||
dexFile.setSortAllItems(true);
|
dexFile.setSortAllItems(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fixJumbo || fixGoto) {
|
if (fixGoto) {
|
||||||
fixInstructions(dexFile, fixJumbo, fixGoto);
|
fixInstructions(dexFile, true, fixGoto);
|
||||||
}
|
}
|
||||||
|
|
||||||
dexFile.place();
|
dexFile.place();
|
||||||
@ -399,8 +399,11 @@ public class main {
|
|||||||
.withDescription("sort the items in the dex file into a canonical order before writing")
|
.withDescription("sort the items in the dex file into a canonical order before writing")
|
||||||
.create("S");
|
.create("S");
|
||||||
|
|
||||||
Option noFixJumboOption = OptionBuilder.withLongOpt("no-fix-jumbo")
|
Option jumboInstructionsOption = OptionBuilder.withLongOpt("jumbo-instructions")
|
||||||
.withDescription("Don't automatically instructions with the /jumbo variant where appropriate")
|
.withDescription("adds support for the jumbo opcodes that were temporarily available around the" +
|
||||||
|
" ics timeframe. Note that support for these opcodes was removed from newer version of" +
|
||||||
|
" dalvik. You shouldn't use this option unless you know the dex file will only be used on a" +
|
||||||
|
" device that supports these opcodes.")
|
||||||
.create("J");
|
.create("J");
|
||||||
|
|
||||||
Option noFixGotoOption = OptionBuilder.withLongOpt("no-fix-goto")
|
Option noFixGotoOption = OptionBuilder.withLongOpt("no-fix-goto")
|
||||||
@ -423,7 +426,7 @@ public class main {
|
|||||||
|
|
||||||
debugOptions.addOption(dumpOption);
|
debugOptions.addOption(dumpOption);
|
||||||
debugOptions.addOption(sortOption);
|
debugOptions.addOption(sortOption);
|
||||||
debugOptions.addOption(noFixJumboOption);
|
debugOptions.addOption(jumboInstructionsOption);
|
||||||
debugOptions.addOption(noFixGotoOption);
|
debugOptions.addOption(noFixGotoOption);
|
||||||
debugOptions.addOption(verboseErrorsOption);
|
debugOptions.addOption(verboseErrorsOption);
|
||||||
debugOptions.addOption(printTokensOption);
|
debugOptions.addOption(printTokensOption);
|
||||||
|
@ -574,9 +574,52 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayDescriptor}
|
|||||||
return newToken(INSTRUCTION_FORMAT3rms_METHOD);
|
return newToken(INSTRUCTION_FORMAT3rms_METHOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"check-cast/jumbo" | "new-instance/jumbo" | "const-class/jumbo" {
|
||||||
|
return newToken(INSTRUCTION_FORMAT41c_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
"sget/jumbo" | "sget-wide/jumbo" | "sget-object/jumbo" | "sget-boolean/jumbo" | "sget-byte/jumbo" |
|
||||||
|
"sget-char/jumbo" | "sget-short/jumbo" | "sput/jumbo" | "sput-wide/jumbo" | "sput-object/jumbo" |
|
||||||
|
"sput-boolean/jumbo" | "sput-byte/jumbo" | "sput-char/jumbo" | "sput-short/jumbo" {
|
||||||
|
return newToken(INSTRUCTION_FORMAT41c_FIELD);
|
||||||
|
}
|
||||||
|
|
||||||
|
"sget-volatile/jumbo" | "sget-wide-volatile/jumbo" | "sget-object-volatile/jumbo" | "sput-volatile/jumbo" |
|
||||||
|
"sput-wide-volatile/jumbo" | "sput-object-volatile/jumbo" {
|
||||||
|
return newToken(INSTRUCTION_FORMAT41c_FIELD_ODEX);
|
||||||
|
}
|
||||||
|
|
||||||
"const-wide" {
|
"const-wide" {
|
||||||
return newToken(INSTRUCTION_FORMAT51l);
|
return newToken(INSTRUCTION_FORMAT51l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"instance-of/jumbo" | "new-array/jumbo" {
|
||||||
|
return newToken(INSTRUCTION_FORMAT52c_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
"iget/jumbo" | "iget-wide/jumbo" | "iget-object/jumbo" | "iget-boolean/jumbo" | "iget-byte/jumbo" |
|
||||||
|
"iget-char/jumbo" | "iget-short/jumbo" | "iput/jumbo" | "iput-wide/jumbo" | "iput-object/jumbo" |
|
||||||
|
"iput-boolean/jumbo" | "iput-byte/jumbo" | "iput-char/jumbo" | "iput-short/jumbo" {
|
||||||
|
return newToken(INSTRUCTION_FORMAT52c_FIELD);
|
||||||
|
}
|
||||||
|
|
||||||
|
"iget-volatile/jumbo" | "iget-wide-volatile/jumbo" | "iget-object-volatile/jumbo" | "iput-volatile/jumbo" |
|
||||||
|
"iput-wide-volatile/jumbo" | "iput-object-volatile/jumbo" {
|
||||||
|
return newToken(INSTRUCTION_FORMAT52c_FIELD_ODEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
"invoke-virtual/jumbo" | "invoke-super/jumbo" | "invoke-direct/jumbo" | "invoke-static/jumbo" |
|
||||||
|
"invoke-interface/jumbo" {
|
||||||
|
return newToken(INSTRUCTION_FORMAT5rc_METHOD);
|
||||||
|
}
|
||||||
|
|
||||||
|
"invoke-object-init/jumbo" {
|
||||||
|
return newToken(INSTRUCTION_FORMAT5rc_METHOD_ODEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
"filled-new-array/jumbo" {
|
||||||
|
return newToken(INSTRUCTION_FORMAT5rc_TYPE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Types*/
|
/*Types*/
|
||||||
|
@ -1 +1 @@
|
|||||||
application.version=1.4.0
|
application.version=1.4.1
|
||||||
|
2
brut.apktool.smali/smali/src/test/resources/LexerTest/.gitattributes
vendored
Normal file
2
brut.apktool.smali/smali/src/test/resources/LexerTest/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Prevent newlines from being normalized on windows
|
||||||
|
*.smali -text
|
@ -225,4 +225,56 @@ filled-new-array/range
|
|||||||
execute-inline/range
|
execute-inline/range
|
||||||
invoke-virtual-quick/range
|
invoke-virtual-quick/range
|
||||||
invoke-super-quick/range
|
invoke-super-quick/range
|
||||||
|
check-cast/jumbo
|
||||||
|
new-instance/jumbo
|
||||||
|
const-class/jumbo
|
||||||
|
sget/jumbo
|
||||||
|
sget-wide/jumbo
|
||||||
|
sget-object/jumbo
|
||||||
|
sget-boolean/jumbo
|
||||||
|
sget-byte/jumbo
|
||||||
|
sget-char/jumbo
|
||||||
|
sget-short/jumbo
|
||||||
|
sput/jumbo
|
||||||
|
sput-wide/jumbo
|
||||||
|
sput-object/jumbo
|
||||||
|
sput-boolean/jumbo
|
||||||
|
sput-byte/jumbo
|
||||||
|
sput-char/jumbo
|
||||||
|
sput-short/jumbo
|
||||||
const-wide
|
const-wide
|
||||||
|
instance-of/jumbo
|
||||||
|
new-array/jumbo
|
||||||
|
iget/jumbo
|
||||||
|
iget-wide/jumbo
|
||||||
|
iget-object/jumbo
|
||||||
|
iget-boolean/jumbo
|
||||||
|
iget-byte/jumbo
|
||||||
|
iget-char/jumbo
|
||||||
|
iget-short/jumbo
|
||||||
|
iput/jumbo
|
||||||
|
iput-wide/jumbo
|
||||||
|
iput-object/jumbo
|
||||||
|
iput-boolean/jumbo
|
||||||
|
iput-byte/jumbo
|
||||||
|
iput-char/jumbo
|
||||||
|
iput-short/jumbo
|
||||||
|
invoke-virtual/jumbo
|
||||||
|
invoke-super/jumbo
|
||||||
|
invoke-direct/jumbo
|
||||||
|
invoke-static/jumbo
|
||||||
|
invoke-interface/jumbo
|
||||||
|
filled-new-array/jumbo
|
||||||
|
invoke-object-init/jumbo
|
||||||
|
iget-volatile/jumbo
|
||||||
|
iget-wide-volatile/jumbo
|
||||||
|
iget-object-volatile/jumbo
|
||||||
|
iput-volatile/jumbo
|
||||||
|
iput-wide-volatile/jumbo
|
||||||
|
iput-object-volatile/jumbo
|
||||||
|
sget-volatile/jumbo
|
||||||
|
sget-wide-volatile/jumbo
|
||||||
|
sget-object-volatile/jumbo
|
||||||
|
sput-volatile/jumbo
|
||||||
|
sput-wide-volatile/jumbo
|
||||||
|
sput-object-volatile/jumbo
|
||||||
|
@ -225,4 +225,56 @@ INSTRUCTION_FORMAT3rc_TYPE("filled-new-array/range")
|
|||||||
INSTRUCTION_FORMAT3rmi_METHOD("execute-inline/range")
|
INSTRUCTION_FORMAT3rmi_METHOD("execute-inline/range")
|
||||||
INSTRUCTION_FORMAT3rms_METHOD("invoke-virtual-quick/range")
|
INSTRUCTION_FORMAT3rms_METHOD("invoke-virtual-quick/range")
|
||||||
INSTRUCTION_FORMAT3rms_METHOD("invoke-super-quick/range")
|
INSTRUCTION_FORMAT3rms_METHOD("invoke-super-quick/range")
|
||||||
INSTRUCTION_FORMAT51l("const-wide")
|
INSTRUCTION_FORMAT41c_TYPE("check-cast/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_TYPE("new-instance/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_TYPE("const-class/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sget/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sget-wide/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sget-object/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sget-boolean/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sget-byte/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sget-char/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sget-short/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sput/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sput-wide/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sput-object/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sput-boolean/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sput-byte/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sput-char/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD("sput-short/jumbo")
|
||||||
|
INSTRUCTION_FORMAT51l("const-wide")
|
||||||
|
INSTRUCTION_FORMAT52c_TYPE("instance-of/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_TYPE("new-array/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iget/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iget-wide/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iget-object/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iget-boolean/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iget-byte/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iget-char/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iget-short/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iput/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iput-wide/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iput-object/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iput-boolean/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iput-byte/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iput-char/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD("iput-short/jumbo")
|
||||||
|
INSTRUCTION_FORMAT5rc_METHOD("invoke-virtual/jumbo")
|
||||||
|
INSTRUCTION_FORMAT5rc_METHOD("invoke-super/jumbo")
|
||||||
|
INSTRUCTION_FORMAT5rc_METHOD("invoke-direct/jumbo")
|
||||||
|
INSTRUCTION_FORMAT5rc_METHOD("invoke-static/jumbo")
|
||||||
|
INSTRUCTION_FORMAT5rc_METHOD("invoke-interface/jumbo")
|
||||||
|
INSTRUCTION_FORMAT5rc_TYPE("filled-new-array/jumbo")
|
||||||
|
INSTRUCTION_FORMAT5rc_METHOD_ODEX("invoke-object-init/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD_ODEX("iget-volatile/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD_ODEX("iget-wide-volatile/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD_ODEX("iget-object-volatile/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD_ODEX("iput-volatile/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD_ODEX("iput-wide-volatile/jumbo")
|
||||||
|
INSTRUCTION_FORMAT52c_FIELD_ODEX("iput-object-volatile/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD_ODEX("sget-volatile/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD_ODEX("sget-wide-volatile/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD_ODEX("sget-object-volatile/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD_ODEX("sput-volatile/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD_ODEX("sput-wide-volatile/jumbo")
|
||||||
|
INSTRUCTION_FORMAT41c_FIELD_ODEX("sput-object-volatile/jumbo")
|
||||||
|
Loading…
Reference in New Issue
Block a user