Remove the now-unused experimental opcodes flag/functionality

This commit is contained in:
Ben Gruver 2016-09-04 16:58:01 -07:00
parent 30bdb7fda9
commit d7d995cc2d
21 changed files with 39 additions and 87 deletions

View File

@ -66,11 +66,6 @@ public class AnalysisArguments {
@ExtendedParameter(argumentNames = "dir")
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 {
@Parameter(names = {"--check-package-private-access", "--package-private", "--checkpp", "--pp"},
description = "Use the package-private access check when calculating vtable indexes. This should " +

View File

@ -57,7 +57,6 @@ public class BaksmaliOptions {
public boolean accessorComments = true;
public boolean allowOdex = false;
public boolean deodex = false;
public boolean experimentalOpcodes = false;
public boolean implicitReferences = false;
public boolean normalizeVirtualMethods = false;

View File

@ -97,11 +97,10 @@ public abstract class DexInputCommand extends Command {
*
* @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 experimentalOpcodes whether experimental opcodes should be allowed
* @return The loaded DexBackedDexFile
*/
@Nonnull
protected DexBackedDexFile loadDexFile(@Nonnull String input, int apiLevel, boolean experimentalOpcodes) {
protected DexBackedDexFile loadDexFile(@Nonnull String input, int apiLevel) {
File file = new File(input);
while (file != null && !file.exists()) {
@ -128,13 +127,13 @@ public abstract class DexInputCommand extends Command {
try {
return DexFileFactory.loadDexEntry(dexFile, dexEntry, exactMatch,
Opcodes.forApi(apiLevel, experimentalOpcodes));
Opcodes.forApi(apiLevel));
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} else {
try {
return DexFileFactory.loadDexFile(dexFile, Opcodes.forApi(apiLevel, experimentalOpcodes));
return DexFileFactory.loadDexFile(dexFile, Opcodes.forApi(apiLevel));
} catch (IOException ex) {
throw new RuntimeException(ex);
}

View File

@ -154,7 +154,7 @@ public class DisassembleCommand extends DexInputCommand {
}
String input = inputList.get(0);
DexBackedDexFile dexFile = loadDexFile(input, 15, false);
DexBackedDexFile dexFile = loadDexFile(input, 15);
if (showDeodexWarning() && dexFile.hasOdexOpcodes()) {
StringWrapper.printWrappedString(System.err,
@ -195,8 +195,7 @@ public class DisassembleCommand extends DexInputCommand {
try {
options.classPath = ClassPath.loadClassPath(analysisArguments.classPathDirectories,
analysisArguments.bootClassPath, analysisArguments.classPath, dexFile,
analysisArguments.apiLevel, shouldCheckPackagePrivateAccess(),
analysisArguments.experimentalOpcodes);
analysisArguments.apiLevel, shouldCheckPackagePrivateAccess());
} catch (Exception ex) {
System.err.println("\n\nError occurred while loading class path files. Aborting.");
ex.printStackTrace(System.err);
@ -241,7 +240,6 @@ public class DisassembleCommand extends DexInputCommand {
options.debugInfo = debugInfo;
options.codeOffsets = codeOffsets;
options.accessorComments = accessorComments;
options.experimentalOpcodes = analysisArguments.experimentalOpcodes;
options.implicitReferences = implicitReferences;
options.normalizeVirtualMethods = normalizeVirtualMethods;

View File

@ -60,11 +60,6 @@ public class DumpCommand extends DexInputCommand {
@ExtendedParameter(argumentNames = "api")
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) {
super(commandAncestors);
}
@ -82,7 +77,7 @@ public class DumpCommand extends DexInputCommand {
}
String input = inputList.get(0);
DexBackedDexFile dexFile = loadDexFile(input, 15, false);
DexBackedDexFile dexFile = loadDexFile(input, 15);
try {
dump(dexFile, System.out, apiLevel);

View File

@ -69,7 +69,7 @@ public class ListClassesCommand extends DexInputCommand {
}
String input = inputList.get(0);
DexBackedDexFile dexFile = loadDexFile(input, 15, false);
DexBackedDexFile dexFile = loadDexFile(input, 15);
for (Reference reference: dexFile.getClasses()) {
System.out.println(ReferenceUtil.getReferenceString(reference));

View File

@ -80,7 +80,7 @@ public class ListFieldOffsetsCommand extends DexInputCommand {
}
String input = inputList.get(0);
DexBackedDexFile dexFile = loadDexFile(input, 15, false);
DexBackedDexFile dexFile = loadDexFile(input, 15);
BaksmaliOptions options = getOptions(dexFile);
try {
@ -110,15 +110,13 @@ public class ListFieldOffsetsCommand extends DexInputCommand {
try {
options.classPath = ClassPath.loadClassPath(analysisArguments.classPathDirectories,
analysisArguments.bootClassPath, analysisArguments.classPath, dexFile, analysisArguments.apiLevel,
false, analysisArguments.experimentalOpcodes);
false);
} catch (Exception ex) {
System.err.println("Error occurred while loading class path files.");
ex.printStackTrace(System.err);
System.exit(-1);
}
options.experimentalOpcodes = analysisArguments.experimentalOpcodes;
return options;
}
}

View File

@ -66,7 +66,7 @@ public abstract class ListReferencesCommand extends DexInputCommand {
}
String input = inputList.get(0);
DexBackedDexFile dexFile = loadDexFile(input, 15, false);
DexBackedDexFile dexFile = loadDexFile(input, 15);
for (Reference reference: dexFile.getReferences(referenceType)) {
System.out.println(ReferenceUtil.getReferenceString(reference));

View File

@ -91,7 +91,7 @@ public class ListVtablesCommand extends DexInputCommand {
}
String input = inputList.get(0);
DexBackedDexFile dexFile = loadDexFile(input, 15, false);
DexBackedDexFile dexFile = loadDexFile(input, 15);
BaksmaliOptions options = getOptions(dexFile);
if (options == null) {
@ -140,15 +140,13 @@ public class ListVtablesCommand extends DexInputCommand {
try {
options.classPath = ClassPath.loadClassPath(analysisArguments.classPathDirectories,
analysisArguments.bootClassPath, analysisArguments.classPath, dexFile, analysisArguments.apiLevel,
checkPackagePrivateArgument.checkPackagePrivateAccess, analysisArguments.experimentalOpcodes);
checkPackagePrivateArgument.checkPackagePrivateAccess);
} catch (Exception ex) {
System.err.println("Error occurred while loading class path files.");
ex.printStackTrace(System.err);
return null;
}
options.experimentalOpcodes = analysisArguments.experimentalOpcodes;
return options;
}
}

View File

@ -50,8 +50,7 @@ public class BaksmaliTestUtils {
public static void assertSmaliCompiledEquals(String source, String expected,
BaksmaliOptions options, boolean stripComments) throws IOException,
RecognitionException {
ClassDef classDef = SmaliTestUtils.compileSmali(source, options.apiLevel,
options.experimentalOpcodes);
ClassDef classDef = SmaliTestUtils.compileSmali(source, options.apiLevel);
// Remove unnecessary whitespace and optionally strip all comments from smali file
String normalizedActual = getNormalizedSmali(classDef, options, stripComments);

View File

@ -330,8 +330,6 @@ public enum Opcode
public static final int JUMBO_OPCODE = 0x200;
//if the instruction can initialize an uninitialized object reference
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;
@ -471,10 +469,6 @@ public enum Opcode
return (flags & CAN_INITIALIZE_REFERENCE) != 0;
}
public final boolean isExperimental() {
return (flags & EXPERIMENTAL) != 0;
}
private static class VersionConstraint {
@Nonnull public final Range<Integer> apiRange;
@Nonnull public final Range<Integer> artVersionRange;

View File

@ -52,35 +52,20 @@ public class Opcodes {
@Nonnull
public static Opcodes forApi(int api) {
return new Opcodes(api, VersionMap.mapApiToArtVersion(api), false);
}
@Nonnull
public static Opcodes forApi(int api, boolean experimental) {
return new Opcodes(api, VersionMap.mapApiToArtVersion(api), experimental);
return new Opcodes(api, VersionMap.mapApiToArtVersion(api));
}
@Nonnull
public static Opcodes forArtVersion(int artVersion) {
return forArtVersion(artVersion, false);
}
@Nonnull
public static Opcodes forArtVersion(int artVersion, boolean experimental) {
return new Opcodes(VersionMap.mapArtVersionToApi(artVersion), artVersion, experimental);
return new Opcodes(VersionMap.mapArtVersionToApi(artVersion), artVersion);
}
@Deprecated
public Opcodes(int api) {
this(api, false);
this(api, VersionMap.mapApiToArtVersion(api));
}
@Deprecated
public Opcodes(int api, boolean experimental) {
this(api, VersionMap.mapApiToArtVersion(api), experimental);
}
private Opcodes(int api, int artVersion, boolean experimental) {
private Opcodes(int api, int artVersion) {
this.api = api;
this.artVersion = artVersion;
@ -104,7 +89,7 @@ public class Opcodes {
}
Short opcodeValue = versionToValueMap.get(version);
if (opcodeValue != null && (!opcode.isExperimental() || experimental)) {
if (opcodeValue != null) {
if (!opcode.format.isPayloadFormat) {
opcodesByValue[opcodeValue] = opcode;
}

View File

@ -185,11 +185,10 @@ public class ClassPath {
* 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
* 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 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
*/
@ -197,7 +196,7 @@ public class ClassPath {
public static ClassPath loadClassPath(@Nonnull Iterable<String> classPathDirs,
@Nullable Iterable<String> bootClassPathEntries,
@Nonnull Iterable<String> extraClassPathEntries, @Nonnull DexFile dexFile,
int api, boolean experimental, boolean checkPackagePrivateAccess)
int api, boolean checkPackagePrivateAccess)
throws IOException {
List<ClassProvider> classProviders = Lists.newArrayList();
if (bootClassPathEntries == null) {
@ -232,7 +231,7 @@ public class ClassPath {
File bestMatch = Collections.max(files, new ClassPathEntryComparator(entry));
Iterable<? extends DexBackedDexFile> dexFiles =
DexFileFactory.loadAllDexFiles(bestMatch, Opcodes.forApi(api, experimental));
DexFileFactory.loadAllDexFiles(bestMatch, Opcodes.forApi(api));
for (DexFile loadedDexFile: dexFiles) {
classProviders.add(new DexClassProvider(loadedDexFile));
}

View File

@ -71,7 +71,7 @@ public class CustomMethodInlineTableTest {
DexFile dexFile = new ImmutableDexFile(Opcodes.forApi(19), ImmutableList.of(classDef));
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");
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));
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");
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));
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");
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false);

View File

@ -263,8 +263,8 @@ import org.jf.dexlib2.Opcodes;
this.allowOdex = allowOdex;
}
public void setApiLevel(int apiLevel, boolean experimental) {
this.opcodes = new Opcodes(apiLevel, experimental);
public void setApiLevel(int apiLevel) {
this.opcodes = Opcodes.forApi(apiLevel);
this.apiLevel = apiLevel;
}

View File

@ -85,8 +85,8 @@ import java.util.*;
this.dexBuilder = dexBuilder;
}
public void setApiLevel(int apiLevel, boolean experimental) {
this.opcodes = new Opcodes(apiLevel, experimental);
public void setApiLevel(int apiLevel) {
this.opcodes = Opcodes.forApi(apiLevel);
this.apiLevel = apiLevel;
}

View File

@ -69,11 +69,6 @@ public class AssembleCommand extends Command {
@ExtendedParameter(argumentNames = "file")
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",
description = "Generate verbose error messages.")
private boolean verbose = false;
@ -110,7 +105,6 @@ public class AssembleCommand extends Command {
options.jobs = jobs;
options.apiLevel = apiLevel;
options.outputDexFile = output;
options.experimentalOpcodes = experimentalOpcodes;
options.allowOdexOpcodes = allowOdexOpcodes;
options.verboseErrors = verbose;

View File

@ -92,7 +92,7 @@ public class Smali {
boolean errors = false;
final DexBuilder dexBuilder = DexBuilder.makeDexBuilder(
Opcodes.forApi(options.apiLevel, options.experimentalOpcodes));
Opcodes.forApi(options.apiLevel));
ExecutorService executor = Executors.newFixedThreadPool(options.jobs);
List<Future<Boolean>> tasks = Lists.newArrayList();
@ -177,7 +177,7 @@ public class Smali {
smaliParser parser = new smaliParser(tokens);
parser.setVerboseErrors(options.verboseErrors);
parser.setAllowOdex(options.allowOdexOpcodes);
parser.setApiLevel(options.apiLevel, options.experimentalOpcodes);
parser.setApiLevel(options.apiLevel);
smaliParser.smali_file_return result = parser.smali_file();
@ -195,7 +195,7 @@ public class Smali {
}
smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
dexGen.setApiLevel(options.apiLevel, options.experimentalOpcodes);
dexGen.setApiLevel(options.apiLevel);
dexGen.setVerboseErrors(options.verboseErrors);
dexGen.setDexBuilder(dexBuilder);

View File

@ -39,5 +39,4 @@ public class SmaliOptions {
public boolean allowOdexOpcodes = false;
public boolean verboseErrors = false;
public boolean printTokens = false;
public boolean experimentalOpcodes = false;
}

View File

@ -50,14 +50,14 @@ import java.io.StringReader;
public class SmaliTestUtils {
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 {
CommonTokenStream tokens;
LexerErrorInterface lexer;
DexBuilder dexBuilder = DexBuilder.makeDexBuilder(Opcodes.forApi(apiLevel, experimental));
DexBuilder dexBuilder = DexBuilder.makeDexBuilder(Opcodes.forApi(apiLevel));
Reader reader = new StringReader(smaliText);
@ -67,7 +67,7 @@ public class SmaliTestUtils {
smaliParser parser = new smaliParser(tokens);
parser.setVerboseErrors(true);
parser.setAllowOdex(false);
parser.setApiLevel(apiLevel, experimental);
parser.setApiLevel(apiLevel);
smaliParser.smali_file_return result = parser.smali_file();
@ -81,7 +81,7 @@ public class SmaliTestUtils {
treeStream.setTokenStream(tokens);
smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
dexGen.setApiLevel(apiLevel, experimental);
dexGen.setApiLevel(apiLevel);
dexGen.setVerboseErrors(true);
dexGen.setDexBuilder(dexBuilder);
dexGen.smali_file();
@ -94,7 +94,7 @@ public class SmaliTestUtils {
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);
}

View File

@ -76,7 +76,7 @@ public class SmaliInstruction extends SmaliCompositeElement {
assert instructionNode != null;
// 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 (instructionNode.getText().equals(".packed-switch")) {
return Opcode.PACKED_SWITCH_PAYLOAD;