summaryrefslogtreecommitdiffstats
path: root/tools/dexfuzz/src/dexfuzz
diff options
context:
space:
mode:
Diffstat (limited to 'tools/dexfuzz/src/dexfuzz')
-rw-r--r--tools/dexfuzz/src/dexfuzz/DexFuzz.java2
-rw-r--r--tools/dexfuzz/src/dexfuzz/Options.java34
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/Architecture.java26
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/Arm64InterpreterExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/Arm64OptimizingBackendExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/Arm64QuickBackendExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/ArmInterpreterExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/ArmOptimizingBackendExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/ArmQuickBackendExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/Device.java190
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/Executor.java159
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/Mips64InterpreterExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/Mips64OptimizingBackendExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/Mips64QuickBackendExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/MipsInterpreterExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/MipsOptimizingBackendExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/MipsQuickBackendExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/X86InterpreterExecutor.java19
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/X86OptimizingBackendExecutor.java19
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/X86QuickBackendExecutor.java19
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/X86_64InterpreterExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/X86_64OptimizingBackendExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/X86_64QuickBackendExecutor.java15
-rw-r--r--tools/dexfuzz/src/dexfuzz/fuzzers/Fuzzer.java27
24 files changed, 304 insertions, 416 deletions
diff --git a/tools/dexfuzz/src/dexfuzz/DexFuzz.java b/tools/dexfuzz/src/dexfuzz/DexFuzz.java
index 2fb9663..04bbbf8 100644
--- a/tools/dexfuzz/src/dexfuzz/DexFuzz.java
+++ b/tools/dexfuzz/src/dexfuzz/DexFuzz.java
@@ -33,7 +33,7 @@ import dexfuzz.listeners.UpdatingConsoleListener;
*/
public class DexFuzz {
private static int majorVersion = 1;
- private static int minorVersion = 0;
+ private static int minorVersion = 1;
private static int seedChangeVersion = 0;
/**
diff --git a/tools/dexfuzz/src/dexfuzz/Options.java b/tools/dexfuzz/src/dexfuzz/Options.java
index 1ae7b5e..2e929c8 100644
--- a/tools/dexfuzz/src/dexfuzz/Options.java
+++ b/tools/dexfuzz/src/dexfuzz/Options.java
@@ -58,7 +58,7 @@ public class Options {
// FLAG OPTIONS
public static boolean execute;
- public static boolean local;
+ public static boolean executeOnHost;
public static boolean noBootImage;
public static boolean useInterpreter;
public static boolean useQuick;
@@ -90,7 +90,7 @@ public class Options {
Log.always(" --output=<file> : Output DEX file to be produced");
Log.always("");
Log.always(" --execute : Execute the resulting fuzzed program");
- Log.always(" --local : Execute on host (Not available yet.)");
+ Log.always(" --host : Execute on host");
Log.always(" --device=<device> : Execute on an ADB-connected-device, where <device> is");
Log.always(" the argument given to adb -s. Default execution mode.");
Log.always(" --execute-dir=<dir> : Push tests to this directory to execute them.");
@@ -150,8 +150,8 @@ public class Options {
private static void handleFlagOption(String flag) {
if (flag.equals("execute")) {
execute = true;
- } else if (flag.equals("local")) {
- local = true;
+ } else if (flag.equals("host")) {
+ executeOnHost = true;
} else if (flag.equals("no-boot-image")) {
noBootImage = true;
} else if (flag.equals("skip-host-verify")) {
@@ -383,19 +383,25 @@ public class Options {
Log.error("Cannot use --max-methods that's smaller than --min-methods");
return false;
}
- if (local && usingSpecificDevice) {
- Log.error("Cannot use --local and --device!");
+ if (executeOnHost && usingSpecificDevice) {
+ Log.error("Cannot use --host and --device!");
return false;
}
if (execute) {
- if (!(useArchArm
- || useArchArm64
- || useArchX86
- || useArchX86_64
- || useArchMips
- || useArchMips64)) {
- Log.error("No architecture to execute on was specified!");
- return false;
+ // When host-execution mode is specified, we don't need to select an architecture.
+ if (!executeOnHost) {
+ if (!(useArchArm
+ || useArchArm64
+ || useArchX86
+ || useArchX86_64
+ || useArchMips
+ || useArchMips64)) {
+ Log.error("No architecture to execute on was specified!");
+ return false;
+ }
+ } else {
+ // TODO: Select the correct architecture. For now, just assume x86.
+ useArchX86 = true;
}
if ((useArchArm || useArchArm64) && (useArchX86 || useArchX86_64)) {
Log.error("Did you mean to specify ARM and x86?");
diff --git a/tools/dexfuzz/src/dexfuzz/executors/Architecture.java b/tools/dexfuzz/src/dexfuzz/executors/Architecture.java
index 5cdabc3..051d80e 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/Architecture.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/Architecture.java
@@ -17,15 +17,23 @@
package dexfuzz.executors;
/**
- * Every Executor must specify an Architecture. It is important that when reduced
- * to lower case, these match the ISA string that ART would produce. For example,
- * the architecture directory used for /data/dalvik-cache/${ISA}
+ * Every Executor must specify an Architecture.
*/
public enum Architecture {
- ARM,
- ARM64,
- X86,
- X86_64,
- MIPS,
- MIPS64
+ ARM("arm"),
+ ARM64("arm64"),
+ X86("x86"),
+ X86_64("x86_64"),
+ MIPS("mips"),
+ MIPS64("mips64");
+
+ private String archString = "";
+
+ private Architecture(String archString) {
+ this.archString = archString;
+ }
+
+ public String asString() {
+ return archString;
+ }
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/Arm64InterpreterExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/Arm64InterpreterExecutor.java
index a945283..227c698 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/Arm64InterpreterExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/Arm64InterpreterExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class Arm64InterpreterExecutor extends Executor {
public Arm64InterpreterExecutor(BaseListener listener, Device device) {
- super("ARM64 Interpreter", 30, listener, Architecture.ARM64, device);
+ super("ARM64 Interpreter", 30, listener, Architecture.ARM64, device, false);
}
@Override
@@ -33,17 +33,6 @@ public class Arm64InterpreterExecutor extends Executor {
}
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/arm64/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return false;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/Arm64OptimizingBackendExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/Arm64OptimizingBackendExecutor.java
index 2204ba8..bfa87b7 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/Arm64OptimizingBackendExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/Arm64OptimizingBackendExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class Arm64OptimizingBackendExecutor extends Executor {
public Arm64OptimizingBackendExecutor(BaseListener listener, Device device) {
- super("ARM64 Optimizing Backend", 5, listener, Architecture.ARM64, device);
+ super("ARM64 Optimizing Backend", 5, listener, Architecture.ARM64, device, true);
}
@Override
@@ -33,17 +33,6 @@ public class Arm64OptimizingBackendExecutor extends Executor {
}
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/arm64/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return true;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/Arm64QuickBackendExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/Arm64QuickBackendExecutor.java
index 55c9c7a..726a7a8 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/Arm64QuickBackendExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/Arm64QuickBackendExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class Arm64QuickBackendExecutor extends Executor {
public Arm64QuickBackendExecutor(BaseListener listener, Device device) {
- super("ARM64 Quick Backend", 5, listener, Architecture.ARM64, device);
+ super("ARM64 Quick Backend", 5, listener, Architecture.ARM64, device, true);
}
@Override
@@ -33,17 +33,6 @@ public class Arm64QuickBackendExecutor extends Executor {
}
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/arm64/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return true;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/ArmInterpreterExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/ArmInterpreterExecutor.java
index 68ce2e0..d17ea87 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/ArmInterpreterExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/ArmInterpreterExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class ArmInterpreterExecutor extends Executor {
public ArmInterpreterExecutor(BaseListener listener, Device device) {
- super("ARM Interpreter", 30, listener, Architecture.ARM, device);
+ super("ARM Interpreter", 30, listener, Architecture.ARM, device, false);
}
@Override
@@ -33,17 +33,6 @@ public class ArmInterpreterExecutor extends Executor {
}
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/arm/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return false;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/ArmOptimizingBackendExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/ArmOptimizingBackendExecutor.java
index 78cf652..947bb2f 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/ArmOptimizingBackendExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/ArmOptimizingBackendExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class ArmOptimizingBackendExecutor extends Executor {
public ArmOptimizingBackendExecutor(BaseListener listener, Device device) {
- super("ARM Optimizing Backend", 5, listener, Architecture.ARM, device);
+ super("ARM Optimizing Backend", 5, listener, Architecture.ARM, device, true);
}
@Override
@@ -33,17 +33,6 @@ public class ArmOptimizingBackendExecutor extends Executor {
}
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/arm/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return true;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/ArmQuickBackendExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/ArmQuickBackendExecutor.java
index 8f026b2..611270b 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/ArmQuickBackendExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/ArmQuickBackendExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class ArmQuickBackendExecutor extends Executor {
public ArmQuickBackendExecutor(BaseListener listener, Device device) {
- super("ARM Quick Backend", 5, listener, Architecture.ARM, device);
+ super("ARM Quick Backend", 5, listener, Architecture.ARM, device, true);
}
@Override
@@ -33,17 +33,6 @@ public class ArmQuickBackendExecutor extends Executor {
}
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/arm/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return true;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/Device.java b/tools/dexfuzz/src/dexfuzz/executors/Device.java
index 8c03103..736aaad 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/Device.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/Device.java
@@ -16,22 +16,36 @@
package dexfuzz.executors;
+import java.io.IOException;
+import java.util.Map;
+
+import dexfuzz.ExecutionResult;
+import dexfuzz.Log;
+import dexfuzz.Options;
+import dexfuzz.StreamConsumer;
+
/**
- * Handles execution either on a remote device, or locally.
- * Currently only remote execution, on an ADB-connected device, is supported.
+ * Handles execution either on a remote target device, or on a local host computer.
*/
public class Device {
- private boolean isLocal;
+ private boolean isHost;
private String deviceName;
private boolean usingSpecificDevice;
private boolean noBootImage;
+ private String androidHostOut;
+ private String androidProductOut;
+ private String androidData;
+
+ private boolean programPushed;
+
/**
- * The constructor for a local "device". Not yet supported.
+ * The constructor for a host "device".
*/
public Device() {
- this.isLocal = true;
- throw new UnsupportedOperationException("Currently local execution is not supported.");
+ this.isHost = true;
+ this.deviceName = "[HostDevice]";
+ setup();
}
/**
@@ -43,20 +57,68 @@ public class Device {
this.usingSpecificDevice = true;
}
this.noBootImage = noBootImage;
+ setup();
+ }
+
+ private String checkForEnvVar(Map<String, String> envVars, String key) {
+ if (!envVars.containsKey(key)) {
+ Log.errorAndQuit("Cannot run a fuzzed program if $" + key + " is not set!");
+ }
+ return envVars.get(key);
+ }
+
+ private void setup() {
+ programPushed = false;
+
+ Map<String, String> envVars = System.getenv();
+ androidProductOut = checkForEnvVar(envVars, "ANDROID_PRODUCT_OUT");
+ androidHostOut = checkForEnvVar(envVars, "ANDROID_HOST_OUT");
+
+ if (!isHost) {
+ // Create temporary consumers for the initial test.
+ StreamConsumer outputConsumer = new StreamConsumer();
+ outputConsumer.start();
+ StreamConsumer errorConsumer = new StreamConsumer();
+ errorConsumer.start();
+
+ // Check for ADB.
+ try {
+ ProcessBuilder pb = new ProcessBuilder();
+ pb.command("adb", "devices");
+ Process process = pb.start();
+ int exitValue = process.waitFor();
+ if (exitValue != 0) {
+ Log.errorAndQuit("Problem executing ADB - is it in your $PATH?");
+ }
+ } catch (IOException e) {
+ Log.errorAndQuit("IOException when executing ADB, is it working?");
+ } catch (InterruptedException e) {
+ Log.errorAndQuit("InterruptedException when executing ADB, is it working?");
+ }
+
+ // Check we can run something on ADB.
+ ExecutionResult result = executeCommand("true", true, outputConsumer, errorConsumer);
+ if (result.getFlattenedAll().contains("device not found")) {
+ Log.errorAndQuit("Couldn't connect to specified ADB device: " + deviceName);
+ }
+
+ outputConsumer.shutdown();
+ errorConsumer.shutdown();
+ } else {
+ androidData = checkForEnvVar(envVars, "ANDROID_DATA");
+ }
}
/**
* Get the name that would be provided to adb -s to communicate specifically with this device.
*/
public String getName() {
- if (isLocal) {
- return "LOCAL DEVICE";
- }
+ assert(!isHost);
return deviceName;
}
- public boolean isLocal() {
- return isLocal;
+ public boolean isHost() {
+ return isHost;
}
/**
@@ -72,20 +134,81 @@ public class Device {
* Get the command prefix for this device if we want to use adb shell.
*/
public String getExecutionShellPrefix() {
- if (isLocal) {
+ if (isHost) {
return "";
}
return getExecutionPrefixWithAdb("shell");
}
/**
- * Get the command prefix for this device if we want to use adb push.
+ * Get any extra flags required to execute ART on the host.
*/
- public String getExecutionPushPrefix() {
- if (isLocal) {
- return "";
+ public String getHostExecutionFlags() {
+ return String.format("-Xnorelocate -Ximage:%s/framework/core.art", androidHostOut);
+ }
+
+ public String getAndroidHostOut() {
+ return androidHostOut;
+ }
+
+ public String getAndroidProductOut() {
+ return androidProductOut;
+ }
+
+ public ExecutionResult executeCommand(String command, boolean captureOutput) {
+ assert(!captureOutput);
+ return executeCommand(command, captureOutput, null, null);
+ }
+
+ public ExecutionResult executeCommand(String command, boolean captureOutput,
+ StreamConsumer outputConsumer, StreamConsumer errorConsumer) {
+
+ ExecutionResult result = new ExecutionResult();
+
+ Log.info("Executing: " + command);
+
+ try {
+ ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
+ processBuilder.environment().put("ANDROID_ROOT", androidHostOut);
+ if (Options.executeOnHost) {
+ processBuilder.environment().put("ANDROID_DATA", androidData);
+ }
+ Process process = processBuilder.start();
+
+ if (captureOutput) {
+ // Give the streams to the StreamConsumers.
+ outputConsumer.giveStreamAndStartConsuming(process.getInputStream());
+ errorConsumer.giveStreamAndStartConsuming(process.getErrorStream());
+ }
+
+ // Wait until the process is done - the StreamConsumers will keep the
+ // buffers drained, so this shouldn't block indefinitely.
+ // Get the return value as well.
+ result.returnValue = process.waitFor();
+
+ Log.info("Return value: " + result.returnValue);
+
+ if (captureOutput) {
+ // Tell the StreamConsumers to stop consuming, and wait for them to finish
+ // so we know we have all of the output.
+ outputConsumer.processFinished();
+ errorConsumer.processFinished();
+ result.output = outputConsumer.getOutput();
+ result.error = errorConsumer.getOutput();
+
+ // Always explicitly indicate the return code in the text output now.
+ // NB: adb shell doesn't actually return exit codes currently, but this will
+ // be useful if/when it does.
+ result.output.add("RETURN CODE: " + result.returnValue);
+ }
+
+ } catch (IOException e) {
+ Log.errorAndQuit("ExecutionResult.execute() caught an IOException");
+ } catch (InterruptedException e) {
+ Log.errorAndQuit("ExecutionResult.execute() caught an InterruptedException");
}
- return getExecutionPrefixWithAdb("push");
+
+ return result;
}
private String getExecutionPrefixWithAdb(String command) {
@@ -95,4 +218,37 @@ public class Device {
return String.format("adb %s ", command);
}
}
+
+ private String getCacheLocation(Architecture architecture) {
+ String cacheLocation = "";
+ if (isHost) {
+ cacheLocation = androidData + "/dalvik-cache/" + architecture.asString() + "/";
+ } else {
+ cacheLocation = "/data/dalvik-cache/" + architecture.asString() + "/";
+ }
+ return cacheLocation;
+ }
+
+ private String getOatFileName(String testLocation, String programName) {
+ // Converts e.g. /data/art-test/file.dex to data@art-test@file.dex
+ return (testLocation.replace("/", "@").substring(1) + "@" + programName);
+ }
+
+ public void cleanCodeCache(Architecture architecture, String testLocation, String programName) {
+ String command = "rm -f " + getCacheLocation(architecture)
+ + getOatFileName(testLocation, programName);
+ executeCommand(command, false);
+ }
+
+ public void pushProgramToDevice(String programName, String testLocation) {
+ assert(!isHost);
+ if (!programPushed) {
+ executeCommand(getExecutionPrefixWithAdb("push") + programName + " " + testLocation, false);
+ programPushed = true;
+ }
+ }
+
+ public void resetProgramPushed() {
+ programPushed = false;
+ }
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/Executor.java b/tools/dexfuzz/src/dexfuzz/executors/Executor.java
index 7cc584d..1e5d4be 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/Executor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/Executor.java
@@ -17,21 +17,14 @@
package dexfuzz.executors;
import dexfuzz.ExecutionResult;
-import dexfuzz.Log;
import dexfuzz.Options;
import dexfuzz.StreamConsumer;
import dexfuzz.listeners.BaseListener;
-import java.io.IOException;
-import java.util.Map;
-
/**
* Base class containing the common methods for executing a particular backend of ART.
*/
public abstract class Executor {
- private String androidHostOut;
- private String androidProductOut;
-
private StreamConsumer outputConsumer;
private StreamConsumer errorConsumer;
@@ -45,9 +38,10 @@ public abstract class Executor {
protected String testLocation;
protected Architecture architecture;
protected Device device;
+ private boolean needsCleanCodeCache;
protected Executor(String name, int timeout, BaseListener listener, Architecture architecture,
- Device device) {
+ Device device, boolean needsCleanCodeCache) {
executeClass = Options.executeClass;
if (Options.shortTimeouts) {
@@ -60,106 +54,27 @@ public abstract class Executor {
this.listener = listener;
this.architecture = architecture;
this.device = device;
+ this.needsCleanCodeCache = needsCleanCodeCache;
- this.testLocation = Options.executeDirectory;
-
- Map<String, String> envVars = System.getenv();
- androidProductOut = checkForEnvVar(envVars, "ANDROID_PRODUCT_OUT");
- androidHostOut = checkForEnvVar(envVars, "ANDROID_HOST_OUT");
+ if (Options.executeOnHost) {
+ this.testLocation = System.getProperty("user.dir");
+ } else {
+ this.testLocation = Options.executeDirectory;
+ }
outputConsumer = new StreamConsumer();
outputConsumer.start();
errorConsumer = new StreamConsumer();
errorConsumer.start();
-
- if (!device.isLocal()) {
- // Check for ADB.
- try {
- ProcessBuilder pb = new ProcessBuilder();
- pb.command("adb", "devices");
- Process process = pb.start();
- int exitValue = process.waitFor();
- if (exitValue != 0) {
- Log.errorAndQuit("Problem executing ADB - is it in your $PATH?");
- }
- } catch (IOException e) {
- Log.errorAndQuit("IOException when executing ADB, is it working?");
- } catch (InterruptedException e) {
- Log.errorAndQuit("InterruptedException when executing ADB, is it working?");
- }
-
- // Check we can run something on ADB.
- ExecutionResult result = executeOnDevice("true", true);
- if (result.getFlattenedAll().contains("device not found")) {
- Log.errorAndQuit("Couldn't connect to specified ADB device: " + device.getName());
- }
- }
- }
-
- private String checkForEnvVar(Map<String, String> envVars, String key) {
- if (!envVars.containsKey(key)) {
- Log.errorAndQuit("Cannot run a fuzzed program if $" + key + " is not set!");
- }
- return envVars.get(key);
- }
-
- private ExecutionResult executeCommand(String command, boolean captureOutput) {
- ExecutionResult result = new ExecutionResult();
-
- Log.info("Executing: " + command);
-
- try {
- ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
- processBuilder.environment().put("ANDROID_ROOT", androidHostOut);
- Process process = processBuilder.start();
-
- if (captureOutput) {
- // Give the streams to the StreamConsumers.
- outputConsumer.giveStreamAndStartConsuming(process.getInputStream());
- errorConsumer.giveStreamAndStartConsuming(process.getErrorStream());
- }
-
- // Wait until the process is done - the StreamConsumers will keep the
- // buffers drained, so this shouldn't block indefinitely.
- // Get the return value as well.
- result.returnValue = process.waitFor();
-
- Log.info("Return value: " + result.returnValue);
-
- if (captureOutput) {
- // Tell the StreamConsumers to stop consuming, and wait for them to finish
- // so we know we have all of the output.
- outputConsumer.processFinished();
- errorConsumer.processFinished();
- result.output = outputConsumer.getOutput();
- result.error = errorConsumer.getOutput();
-
- // Always explicitly indicate the return code in the text output now.
- // NB: adb shell doesn't actually return exit codes currently, but this will
- // be useful if/when it does.
- result.output.add("RETURN CODE: " + result.returnValue);
- }
-
- } catch (IOException e) {
- Log.errorAndQuit("ExecutionResult.execute() caught an IOException");
- } catch (InterruptedException e) {
- Log.errorAndQuit("ExecutionResult.execute() caught an InterruptedException");
- }
-
- return result;
}
/**
* Called by subclass Executors in their execute() implementations.
*/
- protected ExecutionResult executeOnDevice(String command, boolean captureOutput) {
+ protected ExecutionResult executeCommandWithTimeout(String command, boolean captureOutput) {
String timeoutString = "timeout " + timeout + " ";
- return executeCommand(timeoutString + device.getExecutionShellPrefix() + command,
- captureOutput);
- }
-
- private ExecutionResult pushToDevice(String command) {
- return executeCommand(device.getExecutionPushPrefix() + command, false);
+ return device.executeCommand(timeoutString + device.getExecutionShellPrefix() + command,
+ captureOutput, outputConsumer, errorConsumer);
}
/**
@@ -184,13 +99,11 @@ public abstract class Executor {
StringBuilder commandBuilder = new StringBuilder();
commandBuilder.append("dex2oat ");
- // This assumes that the Architecture enum's name, when reduced to lower-case,
- // matches what dex2oat would expect.
- commandBuilder.append("--instruction-set=").append(architecture.toString().toLowerCase());
+ commandBuilder.append("--instruction-set=").append(architecture.asString());
commandBuilder.append(" --instruction-set-features=default ");
// Select the correct boot image.
- commandBuilder.append("--boot-image=").append(androidProductOut);
+ commandBuilder.append("--boot-image=").append(device.getAndroidProductOut());
if (device.noBootImageAvailable()) {
commandBuilder.append("/data/art-test/core.art ");
} else {
@@ -198,13 +111,14 @@ public abstract class Executor {
}
commandBuilder.append("--oat-file=output.oat ");
- commandBuilder.append("--android-root=").append(androidHostOut).append(" ");
+ commandBuilder.append("--android-root=").append(device.getAndroidHostOut()).append(" ");
commandBuilder.append("--runtime-arg -classpath ");
commandBuilder.append("--runtime-arg ").append(programName).append(" ");
commandBuilder.append("--dex-file=").append(programName).append(" ");
commandBuilder.append("--compiler-filter=interpret-only --runtime-arg -Xnorelocate ");
- ExecutionResult verificationResult = executeCommand(commandBuilder.toString(), true);
+ ExecutionResult verificationResult = device.executeCommand(commandBuilder.toString(), true,
+ outputConsumer, errorConsumer);
boolean success = true;
@@ -232,17 +146,23 @@ public abstract class Executor {
listener.handleFailedHostVerification(verificationResult);
}
- executeCommand("rm output.oat", false);
+ device.executeCommand("rm output.oat", false);
return success;
}
/**
* Called by the Fuzzer to upload the program to the target device.
- * TODO: Check if we're executing on a local device, and don't do this?
*/
- public void uploadToTarget(String programName) {
- pushToDevice(programName + " " + testLocation);
+ public void prepareProgramForExecution(String programName) {
+ if (!Options.executeOnHost) {
+ device.pushProgramToDevice(programName, testLocation);
+ }
+
+ if (needsCleanCodeCache) {
+ // Get the device to clean the code cache
+ device.cleanCodeCache(architecture, testLocation, programName);
+ }
}
/**
@@ -252,16 +172,6 @@ public abstract class Executor {
public abstract void execute(String programName);
/**
- * Executor subclasses need to override this, to delete their generated OAT file correctly.
- */
- public abstract void deleteGeneratedOatFile(String programName);
-
- /**
- * Executor subclasses need to override this, to report if they need a cleaned code cache.
- */
- public abstract boolean needsCleanCodeCache();
-
- /**
* Fuzzer.checkForArchitectureSplit() will use this determine the architecture of the Executor.
*/
public Architecture getArchitecture() {
@@ -269,14 +179,6 @@ public abstract class Executor {
}
/**
- * Used in each subclass of Executor's deleteGeneratedOatFile() method, to know what to delete.
- */
- protected String getOatFileName(String programName) {
- // Converts e.g. /data/art-test/file.dex to data@art-test@file.dex
- return (testLocation.replace("/", "@").substring(1) + "@" + programName);
- }
-
- /**
* Used by the Fuzzer to get result of execution.
*/
public ExecutionResult getResult() {
@@ -289,9 +191,10 @@ public abstract class Executor {
* a target verification failure, before doing anything else with the resulting output.
* Used by the Fuzzer.
*/
- public boolean verifyOnTarget() {
+ public boolean didTargetVerify() {
// TODO: Remove this once host-verification can be forced to always fail?
- if (executionResult.getFlattenedOutput().contains("VerifyError")) {
+ String output = executionResult.getFlattenedAll();
+ if (output.contains("VerifyError") || output.contains("Verification failed on class")) {
return false;
}
return true;
@@ -300,4 +203,8 @@ public abstract class Executor {
public String getName() {
return name;
}
+
+ public void finishedWithProgramOnDevice() {
+ device.resetProgramPushed();
+ }
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/Mips64InterpreterExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/Mips64InterpreterExecutor.java
index 9f27b5e..f319201 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/Mips64InterpreterExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/Mips64InterpreterExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class Mips64InterpreterExecutor extends Executor {
public Mips64InterpreterExecutor(BaseListener listener, Device device) {
- super("MIPS64 Interpreter", 30, listener, Architecture.MIPS64, device);
+ super("MIPS64 Interpreter", 30, listener, Architecture.MIPS64, device, false);
}
@Override
@@ -30,18 +30,7 @@ public class Mips64InterpreterExecutor extends Executor {
commandBuilder.append("dalvikvm64 -Xint ");
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/mips64/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return false;
- }
} \ No newline at end of file
diff --git a/tools/dexfuzz/src/dexfuzz/executors/Mips64OptimizingBackendExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/Mips64OptimizingBackendExecutor.java
index b30240d..a6784e6 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/Mips64OptimizingBackendExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/Mips64OptimizingBackendExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class Mips64OptimizingBackendExecutor extends Executor {
public Mips64OptimizingBackendExecutor(BaseListener listener, Device device) {
- super("MIPS64 Optimizing Backend", 5, listener, Architecture.MIPS64, device);
+ super("MIPS64 Optimizing Backend", 5, listener, Architecture.MIPS64, device, true);
}
@Override
@@ -30,17 +30,6 @@ public class Mips64OptimizingBackendExecutor extends Executor {
commandBuilder.append("dalvikvm64 -Xcompiler-option --compiler-backend=Optimizing ");
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/mips64/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return true;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/Mips64QuickBackendExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/Mips64QuickBackendExecutor.java
index 42ccd1e..bebf27c 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/Mips64QuickBackendExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/Mips64QuickBackendExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class Mips64QuickBackendExecutor extends Executor {
public Mips64QuickBackendExecutor(BaseListener listener, Device device) {
- super("MIPS64 Quick Backend", 5, listener, Architecture.MIPS64, device);
+ super("MIPS64 Quick Backend", 5, listener, Architecture.MIPS64, device, true);
}
@Override
@@ -30,17 +30,6 @@ public class Mips64QuickBackendExecutor extends Executor {
commandBuilder.append("dalvikvm64 ");
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/mips64/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return true;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/MipsInterpreterExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/MipsInterpreterExecutor.java
index 524eaa9..4268c76 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/MipsInterpreterExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/MipsInterpreterExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class MipsInterpreterExecutor extends Executor {
public MipsInterpreterExecutor(BaseListener listener, Device device) {
- super("MIPS Interpreter", 30, listener, Architecture.MIPS, device);
+ super("MIPS Interpreter", 30, listener, Architecture.MIPS, device, false);
}
@Override
@@ -30,17 +30,6 @@ public class MipsInterpreterExecutor extends Executor {
commandBuilder.append("dalvikvm32 -Xint ");
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/mips/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return false;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/MipsOptimizingBackendExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/MipsOptimizingBackendExecutor.java
index fcc92c8..d64b1ce 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/MipsOptimizingBackendExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/MipsOptimizingBackendExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class MipsOptimizingBackendExecutor extends Executor {
public MipsOptimizingBackendExecutor(BaseListener listener, Device device) {
- super("MIPS Optimizing Backend", 5, listener, Architecture.MIPS, device);
+ super("MIPS Optimizing Backend", 5, listener, Architecture.MIPS, device, true);
}
@Override
@@ -30,17 +30,6 @@ public class MipsOptimizingBackendExecutor extends Executor {
commandBuilder.append("dalvikvm32 -Xcompiler-option --compiler-backend=Optimizing ");
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/mips/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return true;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/MipsQuickBackendExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/MipsQuickBackendExecutor.java
index cb442f9..a534866 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/MipsQuickBackendExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/MipsQuickBackendExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class MipsQuickBackendExecutor extends Executor {
public MipsQuickBackendExecutor(BaseListener listener, Device device) {
- super("MIPS Quick Backend", 5, listener, Architecture.MIPS, device);
+ super("MIPS Quick Backend", 5, listener, Architecture.MIPS, device, true);
}
@Override
@@ -30,17 +30,6 @@ public class MipsQuickBackendExecutor extends Executor {
commandBuilder.append("dalvikvm32 ");
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/mips/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return true;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/X86InterpreterExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/X86InterpreterExecutor.java
index 93c14e9..510f0d0 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/X86InterpreterExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/X86InterpreterExecutor.java
@@ -16,31 +16,24 @@
package dexfuzz.executors;
+import dexfuzz.Options;
import dexfuzz.listeners.BaseListener;
public class X86InterpreterExecutor extends Executor {
public X86InterpreterExecutor(BaseListener listener, Device device) {
- super("x86 Interpreter", 30, listener, Architecture.X86, device);
+ super("x86 Interpreter", 30, listener, Architecture.X86, device, false);
}
@Override
public void execute(String programName) {
StringBuilder commandBuilder = new StringBuilder();
commandBuilder.append("dalvikvm32 -Xint ");
+ if (Options.executeOnHost) {
+ commandBuilder.append(device.getHostExecutionFlags()).append(" ");
+ }
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/x86/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return false;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/X86OptimizingBackendExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/X86OptimizingBackendExecutor.java
index b27d5ca..81d7285 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/X86OptimizingBackendExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/X86OptimizingBackendExecutor.java
@@ -16,31 +16,24 @@
package dexfuzz.executors;
+import dexfuzz.Options;
import dexfuzz.listeners.BaseListener;
public class X86OptimizingBackendExecutor extends Executor {
public X86OptimizingBackendExecutor(BaseListener listener, Device device) {
- super("x86 Optimizing Backend", 5, listener, Architecture.X86, device);
+ super("x86 Optimizing Backend", 5, listener, Architecture.X86, device, true);
}
@Override
public void execute(String programName) {
StringBuilder commandBuilder = new StringBuilder();
commandBuilder.append("dalvikvm32 -Xcompiler-option --compiler-backend=Optimizing ");
+ if (Options.executeOnHost) {
+ commandBuilder.append(device.getHostExecutionFlags()).append(" ");
+ }
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/x86/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return true;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/X86QuickBackendExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/X86QuickBackendExecutor.java
index d8ec217..4a68bde 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/X86QuickBackendExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/X86QuickBackendExecutor.java
@@ -16,31 +16,24 @@
package dexfuzz.executors;
+import dexfuzz.Options;
import dexfuzz.listeners.BaseListener;
public class X86QuickBackendExecutor extends Executor {
public X86QuickBackendExecutor(BaseListener listener, Device device) {
- super("x86 Quick Backend", 5, listener, Architecture.X86, device);
+ super("x86 Quick Backend", 5, listener, Architecture.X86, device, true);
}
@Override
public void execute(String programName) {
StringBuilder commandBuilder = new StringBuilder();
commandBuilder.append("dalvikvm32 ");
+ if (Options.executeOnHost) {
+ commandBuilder.append(device.getHostExecutionFlags()).append(" ");
+ }
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/x86/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return true;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/X86_64InterpreterExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/X86_64InterpreterExecutor.java
index 7497322..dc55a41 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/X86_64InterpreterExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/X86_64InterpreterExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class X86_64InterpreterExecutor extends Executor {
public X86_64InterpreterExecutor(BaseListener listener, Device device) {
- super("x86_64 Interpreter", 30, listener, Architecture.X86_64, device);
+ super("x86_64 Interpreter", 30, listener, Architecture.X86_64, device, false);
}
@Override
@@ -30,17 +30,6 @@ public class X86_64InterpreterExecutor extends Executor {
commandBuilder.append("dalvikvm64 -Xint ");
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/x86_64/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return false;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/X86_64OptimizingBackendExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/X86_64OptimizingBackendExecutor.java
index a978f73..2a01c6c 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/X86_64OptimizingBackendExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/X86_64OptimizingBackendExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class X86_64OptimizingBackendExecutor extends Executor {
public X86_64OptimizingBackendExecutor(BaseListener listener, Device device) {
- super("x86_64 Optimizing Backend", 5, listener, Architecture.X86_64, device);
+ super("x86_64 Optimizing Backend", 5, listener, Architecture.X86_64, device, true);
}
@Override
@@ -30,17 +30,6 @@ public class X86_64OptimizingBackendExecutor extends Executor {
commandBuilder.append("dalvikvm64 -Xcompiler-option --compiler-backend=Optimizing ");
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/x86_64/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return true;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/X86_64QuickBackendExecutor.java b/tools/dexfuzz/src/dexfuzz/executors/X86_64QuickBackendExecutor.java
index 85532d8..9579b76 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/X86_64QuickBackendExecutor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/X86_64QuickBackendExecutor.java
@@ -21,7 +21,7 @@ import dexfuzz.listeners.BaseListener;
public class X86_64QuickBackendExecutor extends Executor {
public X86_64QuickBackendExecutor(BaseListener listener, Device device) {
- super("x86_64 Quick Backend", 5, listener, Architecture.X86_64, device);
+ super("x86_64 Quick Backend", 5, listener, Architecture.X86_64, device, true);
}
@Override
@@ -30,17 +30,6 @@ public class X86_64QuickBackendExecutor extends Executor {
commandBuilder.append("dalvikvm64 ");
commandBuilder.append("-cp ").append(testLocation).append("/").append(programName).append(" ");
commandBuilder.append(executeClass);
- executionResult = executeOnDevice(commandBuilder.toString(), true);
- }
-
- @Override
- public void deleteGeneratedOatFile(String programName) {
- String command = "rm -f /data/dalvik-cache/x86_64/" + getOatFileName(programName);
- executeOnDevice(command, false);
- }
-
- @Override
- public boolean needsCleanCodeCache() {
- return true;
+ executionResult = executeCommandWithTimeout(commandBuilder.toString(), true);
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/fuzzers/Fuzzer.java b/tools/dexfuzz/src/dexfuzz/fuzzers/Fuzzer.java
index 4c1acdb..bc39d79 100644
--- a/tools/dexfuzz/src/dexfuzz/fuzzers/Fuzzer.java
+++ b/tools/dexfuzz/src/dexfuzz/fuzzers/Fuzzer.java
@@ -158,7 +158,7 @@ public abstract class Fuzzer {
protected void addExecutors() {
Device device = null;
- if (Options.local) {
+ if (Options.executeOnHost) {
device = new Device();
} else {
device = new Device(Options.deviceName, Options.noBootImage);
@@ -241,27 +241,22 @@ public abstract class Fuzzer {
String programName = getNextOutputFilename();
boolean verified = true;
- if (!Options.skipHostVerify) {
+
+ if (!Options.skipHostVerify && !Options.executeOnHost) {
verified = goldenExecutor.verifyOnHost(programName);
+ if (verified) {
+ listener.handleSuccessfulHostVerification();
+ }
}
+
if (verified) {
boolean skipAnalysis = false;
- boolean uploadedToTarget = false;
- if (!Options.skipHostVerify) {
- listener.handleSuccessfulHostVerification();
- }
+
for (Executor executor : executors) {
executor.reset();
- if (!uploadedToTarget) {
- executor.uploadToTarget(programName);
- } else {
- uploadedToTarget = true;
- }
- if (executor.needsCleanCodeCache()) {
- executor.deleteGeneratedOatFile(programName);
- }
+ executor.prepareProgramForExecution(programName);
executor.execute(programName);
- if (!executor.verifyOnTarget()) {
+ if (!executor.didTargetVerify()) {
listener.handleFailedTargetVerification();
skipAnalysis = true;
break;
@@ -275,6 +270,8 @@ public abstract class Fuzzer {
analyseResults(program, programName);
}
}
+
+ goldenExecutor.finishedWithProgramOnDevice();
mutatedSuccessfully = false;
savedSuccessfully = false;
}