mirror of
https://github.com/revanced/smali.git
synced 2025-05-02 07:34:28 +02:00
Remove the now-unused experimental opcodes flag/functionality
This commit is contained in:
parent
30bdb7fda9
commit
d7d995cc2d
@ -66,11 +66,6 @@ public class AnalysisArguments {
|
|||||||
@ExtendedParameter(argumentNames = "dir")
|
@ExtendedParameter(argumentNames = "dir")
|
||||||
public List<String> classPathDirectories = Lists.newArrayList(".");
|
public List<String> classPathDirectories = Lists.newArrayList(".");
|
||||||
|
|
||||||
@Parameter(names = "--experimental",
|
|
||||||
description = "Enable experimental opcodes to be disassembled, even if they aren't necessarily " +
|
|
||||||
"supported in the Android runtime yet.")
|
|
||||||
public boolean experimentalOpcodes = false;
|
|
||||||
|
|
||||||
public static class CheckPackagePrivateArgument {
|
public static class CheckPackagePrivateArgument {
|
||||||
@Parameter(names = {"--check-package-private-access", "--package-private", "--checkpp", "--pp"},
|
@Parameter(names = {"--check-package-private-access", "--package-private", "--checkpp", "--pp"},
|
||||||
description = "Use the package-private access check when calculating vtable indexes. This should " +
|
description = "Use the package-private access check when calculating vtable indexes. This should " +
|
||||||
|
@ -57,7 +57,6 @@ public class BaksmaliOptions {
|
|||||||
public boolean accessorComments = true;
|
public boolean accessorComments = true;
|
||||||
public boolean allowOdex = false;
|
public boolean allowOdex = false;
|
||||||
public boolean deodex = false;
|
public boolean deodex = false;
|
||||||
public boolean experimentalOpcodes = false;
|
|
||||||
public boolean implicitReferences = false;
|
public boolean implicitReferences = false;
|
||||||
public boolean normalizeVirtualMethods = false;
|
public boolean normalizeVirtualMethods = false;
|
||||||
|
|
||||||
|
@ -97,11 +97,10 @@ public abstract class DexInputCommand extends Command {
|
|||||||
*
|
*
|
||||||
* @param input The name of a dex, apk, odex or oat file/entry.
|
* @param input The name of a dex, apk, odex or oat file/entry.
|
||||||
* @param apiLevel The api level to load the dex file with
|
* @param apiLevel The api level to load the dex file with
|
||||||
* @param experimentalOpcodes whether experimental opcodes should be allowed
|
|
||||||
* @return The loaded DexBackedDexFile
|
* @return The loaded DexBackedDexFile
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
protected DexBackedDexFile loadDexFile(@Nonnull String input, int apiLevel, boolean experimentalOpcodes) {
|
protected DexBackedDexFile loadDexFile(@Nonnull String input, int apiLevel) {
|
||||||
File file = new File(input);
|
File file = new File(input);
|
||||||
|
|
||||||
while (file != null && !file.exists()) {
|
while (file != null && !file.exists()) {
|
||||||
@ -128,13 +127,13 @@ public abstract class DexInputCommand extends Command {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
return DexFileFactory.loadDexEntry(dexFile, dexEntry, exactMatch,
|
return DexFileFactory.loadDexEntry(dexFile, dexEntry, exactMatch,
|
||||||
Opcodes.forApi(apiLevel, experimentalOpcodes));
|
Opcodes.forApi(apiLevel));
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
return DexFileFactory.loadDexFile(dexFile, Opcodes.forApi(apiLevel, experimentalOpcodes));
|
return DexFileFactory.loadDexFile(dexFile, Opcodes.forApi(apiLevel));
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ public class DisassembleCommand extends DexInputCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String input = inputList.get(0);
|
String input = inputList.get(0);
|
||||||
DexBackedDexFile dexFile = loadDexFile(input, 15, false);
|
DexBackedDexFile dexFile = loadDexFile(input, 15);
|
||||||
|
|
||||||
if (showDeodexWarning() && dexFile.hasOdexOpcodes()) {
|
if (showDeodexWarning() && dexFile.hasOdexOpcodes()) {
|
||||||
StringWrapper.printWrappedString(System.err,
|
StringWrapper.printWrappedString(System.err,
|
||||||
@ -195,8 +195,7 @@ public class DisassembleCommand extends DexInputCommand {
|
|||||||
try {
|
try {
|
||||||
options.classPath = ClassPath.loadClassPath(analysisArguments.classPathDirectories,
|
options.classPath = ClassPath.loadClassPath(analysisArguments.classPathDirectories,
|
||||||
analysisArguments.bootClassPath, analysisArguments.classPath, dexFile,
|
analysisArguments.bootClassPath, analysisArguments.classPath, dexFile,
|
||||||
analysisArguments.apiLevel, shouldCheckPackagePrivateAccess(),
|
analysisArguments.apiLevel, shouldCheckPackagePrivateAccess());
|
||||||
analysisArguments.experimentalOpcodes);
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
System.err.println("\n\nError occurred while loading class path files. Aborting.");
|
System.err.println("\n\nError occurred while loading class path files. Aborting.");
|
||||||
ex.printStackTrace(System.err);
|
ex.printStackTrace(System.err);
|
||||||
@ -241,7 +240,6 @@ public class DisassembleCommand extends DexInputCommand {
|
|||||||
options.debugInfo = debugInfo;
|
options.debugInfo = debugInfo;
|
||||||
options.codeOffsets = codeOffsets;
|
options.codeOffsets = codeOffsets;
|
||||||
options.accessorComments = accessorComments;
|
options.accessorComments = accessorComments;
|
||||||
options.experimentalOpcodes = analysisArguments.experimentalOpcodes;
|
|
||||||
options.implicitReferences = implicitReferences;
|
options.implicitReferences = implicitReferences;
|
||||||
options.normalizeVirtualMethods = normalizeVirtualMethods;
|
options.normalizeVirtualMethods = normalizeVirtualMethods;
|
||||||
|
|
||||||
|
@ -60,11 +60,6 @@ public class DumpCommand extends DexInputCommand {
|
|||||||
@ExtendedParameter(argumentNames = "api")
|
@ExtendedParameter(argumentNames = "api")
|
||||||
private int apiLevel = 15;
|
private int apiLevel = 15;
|
||||||
|
|
||||||
@Parameter(names = "--experimental",
|
|
||||||
description = "Enable experimental opcodes to be disassembled, even if they aren't necessarily " +
|
|
||||||
"supported in the Android runtime yet.")
|
|
||||||
private boolean experimentalOpcodes = false;
|
|
||||||
|
|
||||||
public DumpCommand(@Nonnull List<JCommander> commandAncestors) {
|
public DumpCommand(@Nonnull List<JCommander> commandAncestors) {
|
||||||
super(commandAncestors);
|
super(commandAncestors);
|
||||||
}
|
}
|
||||||
@ -82,7 +77,7 @@ public class DumpCommand extends DexInputCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String input = inputList.get(0);
|
String input = inputList.get(0);
|
||||||
DexBackedDexFile dexFile = loadDexFile(input, 15, false);
|
DexBackedDexFile dexFile = loadDexFile(input, 15);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dump(dexFile, System.out, apiLevel);
|
dump(dexFile, System.out, apiLevel);
|
||||||
|
@ -69,7 +69,7 @@ public class ListClassesCommand extends DexInputCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String input = inputList.get(0);
|
String input = inputList.get(0);
|
||||||
DexBackedDexFile dexFile = loadDexFile(input, 15, false);
|
DexBackedDexFile dexFile = loadDexFile(input, 15);
|
||||||
|
|
||||||
for (Reference reference: dexFile.getClasses()) {
|
for (Reference reference: dexFile.getClasses()) {
|
||||||
System.out.println(ReferenceUtil.getReferenceString(reference));
|
System.out.println(ReferenceUtil.getReferenceString(reference));
|
||||||
|
@ -80,7 +80,7 @@ public class ListFieldOffsetsCommand extends DexInputCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String input = inputList.get(0);
|
String input = inputList.get(0);
|
||||||
DexBackedDexFile dexFile = loadDexFile(input, 15, false);
|
DexBackedDexFile dexFile = loadDexFile(input, 15);
|
||||||
BaksmaliOptions options = getOptions(dexFile);
|
BaksmaliOptions options = getOptions(dexFile);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -110,15 +110,13 @@ public class ListFieldOffsetsCommand extends DexInputCommand {
|
|||||||
try {
|
try {
|
||||||
options.classPath = ClassPath.loadClassPath(analysisArguments.classPathDirectories,
|
options.classPath = ClassPath.loadClassPath(analysisArguments.classPathDirectories,
|
||||||
analysisArguments.bootClassPath, analysisArguments.classPath, dexFile, analysisArguments.apiLevel,
|
analysisArguments.bootClassPath, analysisArguments.classPath, dexFile, analysisArguments.apiLevel,
|
||||||
false, analysisArguments.experimentalOpcodes);
|
false);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
System.err.println("Error occurred while loading class path files.");
|
System.err.println("Error occurred while loading class path files.");
|
||||||
ex.printStackTrace(System.err);
|
ex.printStackTrace(System.err);
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
options.experimentalOpcodes = analysisArguments.experimentalOpcodes;
|
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ public abstract class ListReferencesCommand extends DexInputCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String input = inputList.get(0);
|
String input = inputList.get(0);
|
||||||
DexBackedDexFile dexFile = loadDexFile(input, 15, false);
|
DexBackedDexFile dexFile = loadDexFile(input, 15);
|
||||||
|
|
||||||
for (Reference reference: dexFile.getReferences(referenceType)) {
|
for (Reference reference: dexFile.getReferences(referenceType)) {
|
||||||
System.out.println(ReferenceUtil.getReferenceString(reference));
|
System.out.println(ReferenceUtil.getReferenceString(reference));
|
||||||
|
@ -91,7 +91,7 @@ public class ListVtablesCommand extends DexInputCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String input = inputList.get(0);
|
String input = inputList.get(0);
|
||||||
DexBackedDexFile dexFile = loadDexFile(input, 15, false);
|
DexBackedDexFile dexFile = loadDexFile(input, 15);
|
||||||
|
|
||||||
BaksmaliOptions options = getOptions(dexFile);
|
BaksmaliOptions options = getOptions(dexFile);
|
||||||
if (options == null) {
|
if (options == null) {
|
||||||
@ -140,15 +140,13 @@ public class ListVtablesCommand extends DexInputCommand {
|
|||||||
try {
|
try {
|
||||||
options.classPath = ClassPath.loadClassPath(analysisArguments.classPathDirectories,
|
options.classPath = ClassPath.loadClassPath(analysisArguments.classPathDirectories,
|
||||||
analysisArguments.bootClassPath, analysisArguments.classPath, dexFile, analysisArguments.apiLevel,
|
analysisArguments.bootClassPath, analysisArguments.classPath, dexFile, analysisArguments.apiLevel,
|
||||||
checkPackagePrivateArgument.checkPackagePrivateAccess, analysisArguments.experimentalOpcodes);
|
checkPackagePrivateArgument.checkPackagePrivateAccess);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
System.err.println("Error occurred while loading class path files.");
|
System.err.println("Error occurred while loading class path files.");
|
||||||
ex.printStackTrace(System.err);
|
ex.printStackTrace(System.err);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
options.experimentalOpcodes = analysisArguments.experimentalOpcodes;
|
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,8 +50,7 @@ public class BaksmaliTestUtils {
|
|||||||
public static void assertSmaliCompiledEquals(String source, String expected,
|
public static void assertSmaliCompiledEquals(String source, String expected,
|
||||||
BaksmaliOptions options, boolean stripComments) throws IOException,
|
BaksmaliOptions options, boolean stripComments) throws IOException,
|
||||||
RecognitionException {
|
RecognitionException {
|
||||||
ClassDef classDef = SmaliTestUtils.compileSmali(source, options.apiLevel,
|
ClassDef classDef = SmaliTestUtils.compileSmali(source, options.apiLevel);
|
||||||
options.experimentalOpcodes);
|
|
||||||
|
|
||||||
// Remove unnecessary whitespace and optionally strip all comments from smali file
|
// Remove unnecessary whitespace and optionally strip all comments from smali file
|
||||||
String normalizedActual = getNormalizedSmali(classDef, options, stripComments);
|
String normalizedActual = getNormalizedSmali(classDef, options, stripComments);
|
||||||
|
@ -330,8 +330,6 @@ public enum Opcode
|
|||||||
public static final int JUMBO_OPCODE = 0x200;
|
public static final int JUMBO_OPCODE = 0x200;
|
||||||
//if the instruction can initialize an uninitialized object reference
|
//if the instruction can initialize an uninitialized object reference
|
||||||
public static final int CAN_INITIALIZE_REFERENCE = 0x400;
|
public static final int CAN_INITIALIZE_REFERENCE = 0x400;
|
||||||
//if the instruction is experimental (not potentially supported by Android runtime yet)
|
|
||||||
public static final int EXPERIMENTAL = 0x800;
|
|
||||||
|
|
||||||
private static final int ALL_APIS = 0xFFFF0000;
|
private static final int ALL_APIS = 0xFFFF0000;
|
||||||
|
|
||||||
@ -471,10 +469,6 @@ public enum Opcode
|
|||||||
return (flags & CAN_INITIALIZE_REFERENCE) != 0;
|
return (flags & CAN_INITIALIZE_REFERENCE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isExperimental() {
|
|
||||||
return (flags & EXPERIMENTAL) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class VersionConstraint {
|
private static class VersionConstraint {
|
||||||
@Nonnull public final Range<Integer> apiRange;
|
@Nonnull public final Range<Integer> apiRange;
|
||||||
@Nonnull public final Range<Integer> artVersionRange;
|
@Nonnull public final Range<Integer> artVersionRange;
|
||||||
|
@ -52,35 +52,20 @@ public class Opcodes {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static Opcodes forApi(int api) {
|
public static Opcodes forApi(int api) {
|
||||||
return new Opcodes(api, VersionMap.mapApiToArtVersion(api), false);
|
return new Opcodes(api, VersionMap.mapApiToArtVersion(api));
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public static Opcodes forApi(int api, boolean experimental) {
|
|
||||||
return new Opcodes(api, VersionMap.mapApiToArtVersion(api), experimental);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static Opcodes forArtVersion(int artVersion) {
|
public static Opcodes forArtVersion(int artVersion) {
|
||||||
return forArtVersion(artVersion, false);
|
return new Opcodes(VersionMap.mapArtVersionToApi(artVersion), artVersion);
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public static Opcodes forArtVersion(int artVersion, boolean experimental) {
|
|
||||||
return new Opcodes(VersionMap.mapArtVersionToApi(artVersion), artVersion, experimental);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Opcodes(int api) {
|
public Opcodes(int api) {
|
||||||
this(api, false);
|
this(api, VersionMap.mapApiToArtVersion(api));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
private Opcodes(int api, int artVersion) {
|
||||||
public Opcodes(int api, boolean experimental) {
|
|
||||||
this(api, VersionMap.mapApiToArtVersion(api), experimental);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Opcodes(int api, int artVersion, boolean experimental) {
|
|
||||||
this.api = api;
|
this.api = api;
|
||||||
this.artVersion = artVersion;
|
this.artVersion = artVersion;
|
||||||
|
|
||||||
@ -104,7 +89,7 @@ public class Opcodes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Short opcodeValue = versionToValueMap.get(version);
|
Short opcodeValue = versionToValueMap.get(version);
|
||||||
if (opcodeValue != null && (!opcode.isExperimental() || experimental)) {
|
if (opcodeValue != null) {
|
||||||
if (!opcode.format.isPayloadFormat) {
|
if (!opcode.format.isPayloadFormat) {
|
||||||
opcodesByValue[opcodeValue] = opcode;
|
opcodesByValue[opcodeValue] = opcode;
|
||||||
}
|
}
|
||||||
|
@ -185,11 +185,10 @@ public class ClassPath {
|
|||||||
* If null, it will attempt to use the correct defaults based on the inputs.
|
* If null, it will attempt to use the correct defaults based on the inputs.
|
||||||
* @param extraClassPathEntries Additional class path entries. The same sorts of naming mechanisms as for
|
* @param extraClassPathEntries Additional class path entries. The same sorts of naming mechanisms as for
|
||||||
* bootClassPathEntries are allowed
|
* bootClassPathEntries are allowed
|
||||||
* @param checkPackagePrivateAccess Whether checkPackagePrivateAccess is needed, enabled for ONLY early API 17 by
|
|
||||||
* default
|
|
||||||
* @param dexFile The dex file that will be analyzed. It can be a dex, odex or oat file.
|
* @param dexFile The dex file that will be analyzed. It can be a dex, odex or oat file.
|
||||||
* @param api The api level of the device that these dex files come from.
|
* @param api The api level of the device that these dex files come from.
|
||||||
* @param experimental Whether to allow experimental opcodes
|
* @param checkPackagePrivateAccess Whether checkPackagePrivateAccess is needed, enabled for ONLY early API 17 by
|
||||||
|
* default
|
||||||
*
|
*
|
||||||
* @return A ClassPath object
|
* @return A ClassPath object
|
||||||
*/
|
*/
|
||||||
@ -197,7 +196,7 @@ public class ClassPath {
|
|||||||
public static ClassPath loadClassPath(@Nonnull Iterable<String> classPathDirs,
|
public static ClassPath loadClassPath(@Nonnull Iterable<String> classPathDirs,
|
||||||
@Nullable Iterable<String> bootClassPathEntries,
|
@Nullable Iterable<String> bootClassPathEntries,
|
||||||
@Nonnull Iterable<String> extraClassPathEntries, @Nonnull DexFile dexFile,
|
@Nonnull Iterable<String> extraClassPathEntries, @Nonnull DexFile dexFile,
|
||||||
int api, boolean experimental, boolean checkPackagePrivateAccess)
|
int api, boolean checkPackagePrivateAccess)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
List<ClassProvider> classProviders = Lists.newArrayList();
|
List<ClassProvider> classProviders = Lists.newArrayList();
|
||||||
if (bootClassPathEntries == null) {
|
if (bootClassPathEntries == null) {
|
||||||
@ -232,7 +231,7 @@ public class ClassPath {
|
|||||||
|
|
||||||
File bestMatch = Collections.max(files, new ClassPathEntryComparator(entry));
|
File bestMatch = Collections.max(files, new ClassPathEntryComparator(entry));
|
||||||
Iterable<? extends DexBackedDexFile> dexFiles =
|
Iterable<? extends DexBackedDexFile> dexFiles =
|
||||||
DexFileFactory.loadAllDexFiles(bestMatch, Opcodes.forApi(api, experimental));
|
DexFileFactory.loadAllDexFiles(bestMatch, Opcodes.forApi(api));
|
||||||
for (DexFile loadedDexFile: dexFiles) {
|
for (DexFile loadedDexFile: dexFiles) {
|
||||||
classProviders.add(new DexClassProvider(loadedDexFile));
|
classProviders.add(new DexClassProvider(loadedDexFile));
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ public class CustomMethodInlineTableTest {
|
|||||||
DexFile dexFile = new ImmutableDexFile(Opcodes.forApi(19), ImmutableList.of(classDef));
|
DexFile dexFile = new ImmutableDexFile(Opcodes.forApi(19), ImmutableList.of(classDef));
|
||||||
|
|
||||||
ClassPath classPath = ClassPath.loadClassPath(ImmutableList.<String>of(),
|
ClassPath classPath = ClassPath.loadClassPath(ImmutableList.<String>of(),
|
||||||
ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile, 15, false, false);
|
ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile, 15, false);
|
||||||
|
|
||||||
InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V");
|
InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V");
|
||||||
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false);
|
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false);
|
||||||
@ -99,7 +99,7 @@ public class CustomMethodInlineTableTest {
|
|||||||
DexFile dexFile = new ImmutableDexFile(Opcodes.forApi(19), ImmutableList.of(classDef));
|
DexFile dexFile = new ImmutableDexFile(Opcodes.forApi(19), ImmutableList.of(classDef));
|
||||||
|
|
||||||
ClassPath classPath = ClassPath.loadClassPath(ImmutableList.<String>of(),
|
ClassPath classPath = ClassPath.loadClassPath(ImmutableList.<String>of(),
|
||||||
ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile, 15, false, false);
|
ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile, 15, false);
|
||||||
InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V");
|
InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V");
|
||||||
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false);
|
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false);
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ public class CustomMethodInlineTableTest {
|
|||||||
DexFile dexFile = new ImmutableDexFile(Opcodes.forApi(19), ImmutableList.of(classDef));
|
DexFile dexFile = new ImmutableDexFile(Opcodes.forApi(19), ImmutableList.of(classDef));
|
||||||
|
|
||||||
ClassPath classPath = ClassPath.loadClassPath(ImmutableList.<String>of(),
|
ClassPath classPath = ClassPath.loadClassPath(ImmutableList.<String>of(),
|
||||||
ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile, 15, false, false);
|
ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile, 15, false);
|
||||||
InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V");
|
InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V");
|
||||||
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false);
|
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false);
|
||||||
|
|
||||||
|
@ -263,8 +263,8 @@ import org.jf.dexlib2.Opcodes;
|
|||||||
this.allowOdex = allowOdex;
|
this.allowOdex = allowOdex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setApiLevel(int apiLevel, boolean experimental) {
|
public void setApiLevel(int apiLevel) {
|
||||||
this.opcodes = new Opcodes(apiLevel, experimental);
|
this.opcodes = Opcodes.forApi(apiLevel);
|
||||||
this.apiLevel = apiLevel;
|
this.apiLevel = apiLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,8 +85,8 @@ import java.util.*;
|
|||||||
this.dexBuilder = dexBuilder;
|
this.dexBuilder = dexBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setApiLevel(int apiLevel, boolean experimental) {
|
public void setApiLevel(int apiLevel) {
|
||||||
this.opcodes = new Opcodes(apiLevel, experimental);
|
this.opcodes = Opcodes.forApi(apiLevel);
|
||||||
this.apiLevel = apiLevel;
|
this.apiLevel = apiLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,11 +69,6 @@ public class AssembleCommand extends Command {
|
|||||||
@ExtendedParameter(argumentNames = "file")
|
@ExtendedParameter(argumentNames = "file")
|
||||||
private String output = "out.dex";
|
private String output = "out.dex";
|
||||||
|
|
||||||
@Parameter(names = "--experimental",
|
|
||||||
description = "Enable experimental opcodes to be assembled, even if they aren't necessarily " +
|
|
||||||
"supported in the Android runtime yet.")
|
|
||||||
private boolean experimentalOpcodes = false;
|
|
||||||
|
|
||||||
@Parameter(names = "--verbose",
|
@Parameter(names = "--verbose",
|
||||||
description = "Generate verbose error messages.")
|
description = "Generate verbose error messages.")
|
||||||
private boolean verbose = false;
|
private boolean verbose = false;
|
||||||
@ -110,7 +105,6 @@ public class AssembleCommand extends Command {
|
|||||||
options.jobs = jobs;
|
options.jobs = jobs;
|
||||||
options.apiLevel = apiLevel;
|
options.apiLevel = apiLevel;
|
||||||
options.outputDexFile = output;
|
options.outputDexFile = output;
|
||||||
options.experimentalOpcodes = experimentalOpcodes;
|
|
||||||
options.allowOdexOpcodes = allowOdexOpcodes;
|
options.allowOdexOpcodes = allowOdexOpcodes;
|
||||||
options.verboseErrors = verbose;
|
options.verboseErrors = verbose;
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ public class Smali {
|
|||||||
boolean errors = false;
|
boolean errors = false;
|
||||||
|
|
||||||
final DexBuilder dexBuilder = DexBuilder.makeDexBuilder(
|
final DexBuilder dexBuilder = DexBuilder.makeDexBuilder(
|
||||||
Opcodes.forApi(options.apiLevel, options.experimentalOpcodes));
|
Opcodes.forApi(options.apiLevel));
|
||||||
|
|
||||||
ExecutorService executor = Executors.newFixedThreadPool(options.jobs);
|
ExecutorService executor = Executors.newFixedThreadPool(options.jobs);
|
||||||
List<Future<Boolean>> tasks = Lists.newArrayList();
|
List<Future<Boolean>> tasks = Lists.newArrayList();
|
||||||
@ -177,7 +177,7 @@ public class Smali {
|
|||||||
smaliParser parser = new smaliParser(tokens);
|
smaliParser parser = new smaliParser(tokens);
|
||||||
parser.setVerboseErrors(options.verboseErrors);
|
parser.setVerboseErrors(options.verboseErrors);
|
||||||
parser.setAllowOdex(options.allowOdexOpcodes);
|
parser.setAllowOdex(options.allowOdexOpcodes);
|
||||||
parser.setApiLevel(options.apiLevel, options.experimentalOpcodes);
|
parser.setApiLevel(options.apiLevel);
|
||||||
|
|
||||||
smaliParser.smali_file_return result = parser.smali_file();
|
smaliParser.smali_file_return result = parser.smali_file();
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ public class Smali {
|
|||||||
}
|
}
|
||||||
|
|
||||||
smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
|
smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
|
||||||
dexGen.setApiLevel(options.apiLevel, options.experimentalOpcodes);
|
dexGen.setApiLevel(options.apiLevel);
|
||||||
|
|
||||||
dexGen.setVerboseErrors(options.verboseErrors);
|
dexGen.setVerboseErrors(options.verboseErrors);
|
||||||
dexGen.setDexBuilder(dexBuilder);
|
dexGen.setDexBuilder(dexBuilder);
|
||||||
|
@ -39,5 +39,4 @@ public class SmaliOptions {
|
|||||||
public boolean allowOdexOpcodes = false;
|
public boolean allowOdexOpcodes = false;
|
||||||
public boolean verboseErrors = false;
|
public boolean verboseErrors = false;
|
||||||
public boolean printTokens = false;
|
public boolean printTokens = false;
|
||||||
public boolean experimentalOpcodes = false;
|
|
||||||
}
|
}
|
||||||
|
@ -50,14 +50,14 @@ import java.io.StringReader;
|
|||||||
public class SmaliTestUtils {
|
public class SmaliTestUtils {
|
||||||
|
|
||||||
public static ClassDef compileSmali(String smaliText) throws RecognitionException, IOException {
|
public static ClassDef compileSmali(String smaliText) throws RecognitionException, IOException {
|
||||||
return compileSmali(smaliText, 15, false);
|
return compileSmali(smaliText, 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClassDef compileSmali(String smaliText, int apiLevel, boolean experimental)
|
public static ClassDef compileSmali(String smaliText, int apiLevel)
|
||||||
throws RecognitionException, IOException {
|
throws RecognitionException, IOException {
|
||||||
CommonTokenStream tokens;
|
CommonTokenStream tokens;
|
||||||
LexerErrorInterface lexer;
|
LexerErrorInterface lexer;
|
||||||
DexBuilder dexBuilder = DexBuilder.makeDexBuilder(Opcodes.forApi(apiLevel, experimental));
|
DexBuilder dexBuilder = DexBuilder.makeDexBuilder(Opcodes.forApi(apiLevel));
|
||||||
|
|
||||||
Reader reader = new StringReader(smaliText);
|
Reader reader = new StringReader(smaliText);
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ public class SmaliTestUtils {
|
|||||||
smaliParser parser = new smaliParser(tokens);
|
smaliParser parser = new smaliParser(tokens);
|
||||||
parser.setVerboseErrors(true);
|
parser.setVerboseErrors(true);
|
||||||
parser.setAllowOdex(false);
|
parser.setAllowOdex(false);
|
||||||
parser.setApiLevel(apiLevel, experimental);
|
parser.setApiLevel(apiLevel);
|
||||||
|
|
||||||
smaliParser.smali_file_return result = parser.smali_file();
|
smaliParser.smali_file_return result = parser.smali_file();
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ public class SmaliTestUtils {
|
|||||||
treeStream.setTokenStream(tokens);
|
treeStream.setTokenStream(tokens);
|
||||||
|
|
||||||
smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
|
smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
|
||||||
dexGen.setApiLevel(apiLevel, experimental);
|
dexGen.setApiLevel(apiLevel);
|
||||||
dexGen.setVerboseErrors(true);
|
dexGen.setVerboseErrors(true);
|
||||||
dexGen.setDexBuilder(dexBuilder);
|
dexGen.setDexBuilder(dexBuilder);
|
||||||
dexGen.smali_file();
|
dexGen.smali_file();
|
||||||
@ -94,7 +94,7 @@ public class SmaliTestUtils {
|
|||||||
|
|
||||||
dexBuilder.writeTo(dataStore);
|
dexBuilder.writeTo(dataStore);
|
||||||
|
|
||||||
DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.forApi(apiLevel, experimental), dataStore.getData());
|
DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.forApi(apiLevel), dataStore.getData());
|
||||||
|
|
||||||
return Iterables.getFirst(dexFile.getClasses(), null);
|
return Iterables.getFirst(dexFile.getClasses(), null);
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ public class SmaliInstruction extends SmaliCompositeElement {
|
|||||||
assert instructionNode != null;
|
assert instructionNode != null;
|
||||||
|
|
||||||
// TODO: put a project level Opcodes instance with the appropriate api level somewhere
|
// TODO: put a project level Opcodes instance with the appropriate api level somewhere
|
||||||
opcode = new Opcodes(15, false).getOpcodeByName(instructionNode.getText());
|
opcode = Opcodes.forApi(15).getOpcodeByName(instructionNode.getText());
|
||||||
if (opcode == null) {
|
if (opcode == null) {
|
||||||
if (instructionNode.getText().equals(".packed-switch")) {
|
if (instructionNode.getText().equals(".packed-switch")) {
|
||||||
return Opcode.PACKED_SWITCH_PAYLOAD;
|
return Opcode.PACKED_SWITCH_PAYLOAD;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user