summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorCalin Juravle <calin@google.com>2015-04-01 19:48:39 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-04-01 19:48:41 +0000
commit664e46167b12d2bf44fe530a94570f053bf15f91 (patch)
tree96a90b3d01251f9b9f107094680182d9977e6864 /tools
parent0c2ef744f2acc8f251766c0b0859070c2a7bb292 (diff)
parent807f17831e2749d5765599df1c9fbc58af3c6c7c (diff)
downloadart-664e46167b12d2bf44fe530a94570f053bf15f91.zip
art-664e46167b12d2bf44fe530a94570f053bf15f91.tar.gz
art-664e46167b12d2bf44fe530a94570f053bf15f91.tar.bz2
Merge "Adds host execution to dexfuzz."
Diffstat (limited to 'tools')
-rw-r--r--tools/dexfuzz/Android.mk2
-rw-r--r--tools/dexfuzz/README21
-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
26 files changed, 325 insertions, 418 deletions
diff --git a/tools/dexfuzz/Android.mk b/tools/dexfuzz/Android.mk
index d8f5582..1e4b4f5 100644
--- a/tools/dexfuzz/Android.mk
+++ b/tools/dexfuzz/Android.mk
@@ -31,7 +31,7 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE := dexfuzz
include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/dexfuzz $(ACP)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/dexfuzz $(ACP) $(HOST_CORE_IMG_OUTS)
@echo "Copy: $(PRIVATE_MODULE) ($@)"
$(copy-file-to-new-target)
$(hide) chmod 755 $@
diff --git a/tools/dexfuzz/README b/tools/dexfuzz/README
index c4795f2..a0658ec 100644
--- a/tools/dexfuzz/README
+++ b/tools/dexfuzz/README
@@ -21,7 +21,13 @@ resulting new tests on the Android device.
How to run DexFuzz
==================
-1. Build dexfuzz with mmm tools/dexfuzz from within art/.
+DexFuzz can run its test programs on either an ADB-connected device, or a host-build of
+ART locally.
+
+Execution on an ADB-connected device
+------------------------------------
+
+1. Build dexfuzz with mmma tools/dexfuzz from within art/.
2. Make sure you have an Android device connected via ADB, that is capable of
having DEX files pushed to it and executed with the dalvikvm command.
3. Make sure you're in the Android build environment!
@@ -63,6 +69,19 @@ Add in --device=<device name, e.g. device:generic> if you want to specify a devi
Add in --execute-dir=<dir on device> if you want to specify an execution directory.
(The default is /data/art-test/)
+Host Execution
+--------------
+
+DexFuzz now supports execution on your host machine.
+Follow steps 1, 3, 4, and 7 as above, but also observe the following:
+ - instead of specifying an ISA, use --host
+ - ANDROID_DATA must be set, pointing to a location where dex2oat will place
+ OAT files after compilation.
+ - Files will always be executed in the same directory where you are executing DexFuzz.
+
+Fuzzer Operation
+----------------
+
As the fuzzer works, you'll see output like:
|-----------------------------------------------------------------|
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;
}