summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/dexfuzz/src/dexfuzz/DexFuzz.java32
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/Device.java8
-rw-r--r--tools/dexfuzz/src/dexfuzz/listeners/FinalStatusListener.java52
-rw-r--r--tools/dexfuzz/src/dexfuzz/program/CodeTranslator.java14
-rw-r--r--tools/dexfuzz/src/dexfuzz/program/mutators/TryBlockShifter.java13
-rw-r--r--tools/dexfuzz/src/dexfuzz/rawdex/DebugInfoItem.java7
-rw-r--r--tools/dexfuzz/src/dexfuzz/rawdex/MapList.java13
7 files changed, 112 insertions, 27 deletions
diff --git a/tools/dexfuzz/src/dexfuzz/DexFuzz.java b/tools/dexfuzz/src/dexfuzz/DexFuzz.java
index 7337ffc2b6..18db4c1f1a 100644
--- a/tools/dexfuzz/src/dexfuzz/DexFuzz.java
+++ b/tools/dexfuzz/src/dexfuzz/DexFuzz.java
@@ -21,9 +21,9 @@ import dexfuzz.fuzzers.FuzzerMultipleExecute;
import dexfuzz.fuzzers.FuzzerMultipleNoExecute;
import dexfuzz.fuzzers.FuzzerSingleExecute;
import dexfuzz.fuzzers.FuzzerSingleNoExecute;
-import dexfuzz.listeners.BaseListener;
import dexfuzz.listeners.BisectionSearchListener;
import dexfuzz.listeners.ConsoleLoggerListener;
+import dexfuzz.listeners.FinalStatusListener;
import dexfuzz.listeners.LogFileListener;
import dexfuzz.listeners.MultiplexerListener;
import dexfuzz.listeners.UniqueProgramTrackerListener;
@@ -52,12 +52,15 @@ public class DexFuzz {
Options.usage();
}
- // Create the Listener, which will listen for events and report them.
- BaseListener listener = null;
+
+ // Create a Listener that is responsible for multiple Listeners.
+ MultiplexerListener multipleListener = new MultiplexerListener();
+ multipleListener.setup();
+
+ FinalStatusListener statusListener = new FinalStatusListener();
+ multipleListener.addListener(statusListener);
+
if (Options.repeat > 1 && Options.execute) {
- // Create a Listener that is responsible for multiple Listeners.
- MultiplexerListener multipleListener = new MultiplexerListener();
- multipleListener.setup();
// Add the live updating listener, but only if we're not printing out lots of logs.
if (!Log.likelyToLog()) {
multipleListener.addListener(new UpdatingConsoleListener());
@@ -73,22 +76,21 @@ public class DexFuzz {
}
// Add the unique program tracker.
multipleListener.addListener(new UniqueProgramTrackerListener(Options.uniqueDatabaseFile));
- listener = multipleListener;
} else {
// Just use the basic listener.
- listener = new ConsoleLoggerListener();
+ multipleListener.addListener(new ConsoleLoggerListener());
}
// Create the Fuzzer that uses a particular strategy for fuzzing.
Fuzzer fuzzer = null;
if ((Options.repeat > 1) && Options.execute) {
- fuzzer = new FuzzerMultipleExecute(listener);
+ fuzzer = new FuzzerMultipleExecute(multipleListener);
} else if ((Options.repeat > 1) && !Options.execute) {
- fuzzer = new FuzzerMultipleNoExecute(listener);
+ fuzzer = new FuzzerMultipleNoExecute(multipleListener);
} else if ((Options.repeat == 1) && Options.execute) {
- fuzzer = new FuzzerSingleExecute(listener);
+ fuzzer = new FuzzerSingleExecute(multipleListener);
} else if ((Options.repeat == 1) && !Options.execute) {
- fuzzer = new FuzzerSingleNoExecute(listener);
+ fuzzer = new FuzzerSingleNoExecute(multipleListener);
} else {
Log.errorAndQuit("Invalid options provided, desired fuzzer unknown.");
}
@@ -101,6 +103,10 @@ public class DexFuzz {
fuzzer.shutdown();
// Cleanup the Listener.
- listener.shutdown();
+ multipleListener.shutdown();
+
+ if (!statusListener.isSuccessful()) {
+ System.exit(1);
+ }
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/executors/Device.java b/tools/dexfuzz/src/dexfuzz/executors/Device.java
index 72f73b88f5..ba1365eee0 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/Device.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/Device.java
@@ -272,7 +272,7 @@ public class Device {
}
public void cleanCodeCache(Architecture architecture, String testLocation, String programName) {
- String command = "rm -f " + getCacheLocation(architecture)
+ String command = getExecutionPrefixWithAdb("shell") + "rm -f " + getCacheLocation(architecture)
+ getOatFileName(testLocation, programName);
executeCommand(command, false);
}
@@ -280,7 +280,11 @@ public class Device {
public void pushProgramToDevice(String programName, String testLocation) {
assert(!isHost);
if (!programPushed) {
- executeCommand(getExecutionPrefixWithAdb("push") + programName + " " + testLocation, false);
+ String command = getExecutionPrefixWithAdb("push") + programName + " " + testLocation;
+ ExecutionResult result = executeCommand(command, false);
+ if (result.returnValue != 0) {
+ Log.errorAndQuit("Could not ADB PUSH program to device.");
+ }
programPushed = true;
}
}
diff --git a/tools/dexfuzz/src/dexfuzz/listeners/FinalStatusListener.java b/tools/dexfuzz/src/dexfuzz/listeners/FinalStatusListener.java
new file mode 100644
index 0000000000..0f85f620c8
--- /dev/null
+++ b/tools/dexfuzz/src/dexfuzz/listeners/FinalStatusListener.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dexfuzz.listeners;
+
+import java.util.List;
+import java.util.Map;
+
+import dexfuzz.executors.Executor;
+
+/**
+ * Counts divergences as they appear and checks if the testing was successful
+ * or not. Testing is successful if all divergences found are either self
+ * divergent or caused by differences in architectures.
+ */
+public class FinalStatusListener extends BaseListener {
+ private long divergence;
+ private long selfDivergent;
+ private long architectureSplit;
+
+ @Override
+ public void handleDivergences(Map<String, List<Executor>> outputMap) {
+ divergence++;
+ }
+
+ @Override
+ public void handleSelfDivergence() {
+ selfDivergent++;
+ }
+
+ @Override
+ public void handleArchitectureSplit() {
+ architectureSplit++;
+ }
+
+ public boolean isSuccessful() {
+ return (divergence - selfDivergent - architectureSplit) == 0;
+ }
+}
diff --git a/tools/dexfuzz/src/dexfuzz/program/CodeTranslator.java b/tools/dexfuzz/src/dexfuzz/program/CodeTranslator.java
index 650501be12..5335d1592d 100644
--- a/tools/dexfuzz/src/dexfuzz/program/CodeTranslator.java
+++ b/tools/dexfuzz/src/dexfuzz/program/CodeTranslator.java
@@ -259,8 +259,15 @@ public class CodeTranslator {
// Get the MInsns that form the start and end of the try block.
int startLocation = tryItem.startAddr;
mTryBlock.startInsn = insnLocationMap.get(startLocation);
- int endLocation = tryItem.startAddr + tryItem.insnCount;
+
+ // The instructions vary in size, so we have to find the last instruction in the block in a
+ // few tries.
+ int endLocation = tryItem.startAddr + tryItem.insnCount - 1;
mTryBlock.endInsn = insnLocationMap.get(endLocation);
+ while ((mTryBlock.endInsn == null) && (endLocation >= startLocation)) {
+ endLocation--;
+ mTryBlock.endInsn = insnLocationMap.get(endLocation);
+ }
// Sanity checks.
if (mTryBlock.startInsn == null) {
@@ -356,8 +363,9 @@ public class CodeTranslator {
TryItem tryItem = codeItem.tries[tryItemIdx];
tryItem.startAddr = mTryBlock.startInsn.location;
- tryItem.insnCount =
- (short) (mTryBlock.endInsn.location - mTryBlock.startInsn.location);
+ int insnCount = mTryBlock.endInsn.location - mTryBlock.startInsn.location +
+ mTryBlock.endInsn.insn.getSize();
+ tryItem.insnCount = (short) insnCount;
// Get the EncodedCatchHandler.
EncodedCatchHandler encodedCatchHandler =
diff --git a/tools/dexfuzz/src/dexfuzz/program/mutators/TryBlockShifter.java b/tools/dexfuzz/src/dexfuzz/program/mutators/TryBlockShifter.java
index 1bf64637cb..55e3e60312 100644
--- a/tools/dexfuzz/src/dexfuzz/program/mutators/TryBlockShifter.java
+++ b/tools/dexfuzz/src/dexfuzz/program/mutators/TryBlockShifter.java
@@ -81,12 +81,15 @@ public class TryBlockShifter extends CodeMutator {
@Override
protected boolean canMutate(MutatableCode mutatableCode) {
- if (mutatableCode.triesSize > 0) {
- return true;
+ if (mutatableCode.triesSize == 0) {
+ Log.debug("Method contains no tries.");
+ return false;
}
-
- Log.debug("Method contains no tries.");
- return false;
+ if (mutatableCode.getInstructionCount() <= 1) {
+ Log.debug("Not enough instructions to shift try block.");
+ return false;
+ }
+ return true;
}
@Override
diff --git a/tools/dexfuzz/src/dexfuzz/rawdex/DebugInfoItem.java b/tools/dexfuzz/src/dexfuzz/rawdex/DebugInfoItem.java
index 922ee5884d..561e9863a0 100644
--- a/tools/dexfuzz/src/dexfuzz/rawdex/DebugInfoItem.java
+++ b/tools/dexfuzz/src/dexfuzz/rawdex/DebugInfoItem.java
@@ -16,6 +16,8 @@
package dexfuzz.rawdex;
+import dexfuzz.Log;
+
import java.io.IOException;
// Right now we are not parsing debug_info_item, just take the raw size
@@ -32,6 +34,11 @@ public class DebugInfoItem implements RawDexObject {
file.getOffsetTracker().getNewOffsettable(file, this);
data = new byte[size];
file.read(data);
+
+ // Since we are not parsing the section, ensure that the last byte is DBG_END_SEQUENCE.
+ if (data[size - 1] != 0) {
+ Log.errorAndQuit("Error reading debug_info_item. The last byte is not DBG_END_SEQUENCE.");
+ }
}
@Override
diff --git a/tools/dexfuzz/src/dexfuzz/rawdex/MapList.java b/tools/dexfuzz/src/dexfuzz/rawdex/MapList.java
index 080b5a46bb..729aa715b5 100644
--- a/tools/dexfuzz/src/dexfuzz/rawdex/MapList.java
+++ b/tools/dexfuzz/src/dexfuzz/rawdex/MapList.java
@@ -162,10 +162,15 @@ public class MapList implements RawDexObject {
case MapItem.TYPE_DEBUG_INFO_ITEM:
{
// We aren't interested in updating the debug data, so just read it as a blob.
- int start = mapItem.offset.getOriginalOffset();
- int end = mapItems.get(mapItemIdx + 1).offset.getOriginalOffset();
- int size = end - start;
- rawDexFile.debugInfoItem = new DebugInfoItem(size);
+ long start = mapItem.offset.getOriginalOffset();
+ long end = 0;
+ if (mapItemIdx + 1 == mapItems.size()) {
+ end = file.length();
+ } else {
+ end = mapItems.get(mapItemIdx + 1).offset.getOriginalOffset();
+ }
+ long size = end - start;
+ rawDexFile.debugInfoItem = new DebugInfoItem((int)size);
rawDexFile.debugInfoItem.read(file);
break;
}