summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/docs/FuzzingLLVM.rst7
-rw-r--r--llvm/include/llvm/FuzzMutate/FuzzerCLI.h12
-rw-r--r--llvm/lib/FuzzMutate/FuzzerCLI.cpp38
-rw-r--r--llvm/test/tools/llvm-isel-fuzzer/aarch64-execname-options.ll15
-rw-r--r--llvm/test/tools/llvm-isel-fuzzer/execname-options.ll15
-rw-r--r--llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp1
6 files changed, 87 insertions, 1 deletions
diff --git a/llvm/docs/FuzzingLLVM.rst b/llvm/docs/FuzzingLLVM.rst
index 6aa0be7d19f..279ea668e76 100644
--- a/llvm/docs/FuzzingLLVM.rst
+++ b/llvm/docs/FuzzingLLVM.rst
@@ -76,6 +76,13 @@ the following command would fuzz AArch64 with :doc:`GlobalISel`:
% bin/llvm-isel-fuzzer <corpus-dir> -ignore_remaining_args=1 -mtriple aarch64 -global-isel -O0
+Some flags can also be specified in the binary name itself in order to support
+OSS Fuzz, which has trouble with required arguments. To do this, you can copy
+or move ``llvm-isel-fuzzer`` to ``llvm-isel-fuzzer:x-y-z``, where x, y, and z
+are architecture names (``aarch64``, ``x86_64``), optimization levels (``O0``,
+``O2``), or specific keywords like ``gisel`` for enabling global instruction
+selection.
+
llvm-mc-assemble-fuzzer
-----------------------
diff --git a/llvm/include/llvm/FuzzMutate/FuzzerCLI.h b/llvm/include/llvm/FuzzMutate/FuzzerCLI.h
index 83c8356247e..4cb32cefc91 100644
--- a/llvm/include/llvm/FuzzMutate/FuzzerCLI.h
+++ b/llvm/include/llvm/FuzzMutate/FuzzerCLI.h
@@ -15,6 +15,7 @@
#ifndef LLVM_FUZZMUTATE_FUZZER_CLI_H
#define LLVM_FUZZMUTATE_FUZZER_CLI_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -24,6 +25,17 @@ namespace llvm {
/// This handles all arguments after -ignore_remaining_args=1 as cl::opts.
void parseFuzzerCLOpts(int ArgC, char *ArgV[]);
+/// Handle backend options that are encoded in the executable name.
+///
+/// Parses some common backend options out of a specially crafted executable
+/// name (argv[0]). For example, a name like llvm-foo-fuzzer:aarch64-gisel might
+/// set up an AArch64 triple and the Global ISel selector. This should be called
+/// *before* parseFuzzerCLOpts if calling both.
+///
+/// This is meant to be used for environments like OSS-Fuzz that aren't capable
+/// of passing in command line arguments in the normal way.
+void handleExecNameEncodedBEOpts(StringRef ExecName);
+
using FuzzerTestFun = int (*)(const uint8_t *Data, size_t Size);
using FuzzerInitFun = int (*)(int *argc, char ***argv);
diff --git a/llvm/lib/FuzzMutate/FuzzerCLI.cpp b/llvm/lib/FuzzMutate/FuzzerCLI.cpp
index 3b71cde5af7..144f1f579ea 100644
--- a/llvm/lib/FuzzMutate/FuzzerCLI.cpp
+++ b/llvm/lib/FuzzMutate/FuzzerCLI.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/FuzzMutate/FuzzerCLI.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
@@ -31,6 +31,42 @@ void llvm::parseFuzzerCLOpts(int ArgC, char *ArgV[]) {
cl::ParseCommandLineOptions(CLArgs.size(), CLArgs.data());
}
+void llvm::handleExecNameEncodedBEOpts(StringRef ExecName) {
+ std::vector<std::string> Args{ExecName};
+
+ auto NameAndArgs = ExecName.split(':');
+ if (NameAndArgs.second.empty())
+ return;
+
+ SmallVector<StringRef, 4> Opts;
+ NameAndArgs.second.split(Opts, '-');
+ for (StringRef Opt : Opts) {
+ if (Opt.equals("gisel")) {
+ Args.push_back("-global-isel");
+ // For now we default GlobalISel to -O0
+ Args.push_back("-O0");
+ } else if (Opt.startswith("O")) {
+ Args.push_back("-" + Opt.str());
+ } else if (auto Arch = Triple::getArchTypeForLLVMName(Opt)) {
+ Args.push_back("-mtriple=" + Opt.str());
+ } else {
+ errs() << ExecName << ": Unknown option: " << Opt << ".\n";
+ exit(1);
+ }
+ }
+ errs() << NameAndArgs.first << ": Injected args:";
+ for (int I = 1, E = Args.size(); I < E; ++I)
+ errs() << " " << Args[I];
+ errs() << "\n";
+
+ std::vector<const char *> CLArgs;
+ CLArgs.reserve(Args.size());
+ for (std::string &S : Args)
+ CLArgs.push_back(S.c_str());
+
+ cl::ParseCommandLineOptions(CLArgs.size(), CLArgs.data());
+}
+
int llvm::runFuzzerOnInputs(int ArgC, char *ArgV[], FuzzerTestFun TestOne,
FuzzerInitFun Init) {
errs() << "*** This tool was not linked to libFuzzer.\n"
diff --git a/llvm/test/tools/llvm-isel-fuzzer/aarch64-execname-options.ll b/llvm/test/tools/llvm-isel-fuzzer/aarch64-execname-options.ll
new file mode 100644
index 00000000000..e3974b54ca5
--- /dev/null
+++ b/llvm/test/tools/llvm-isel-fuzzer/aarch64-execname-options.ll
@@ -0,0 +1,15 @@
+; REQUIRES: aarch64-registered-target
+
+; RUN: echo > %t.input
+
+; RUN: cp llvm-isel-fuzzer %t.bin:aarch64
+; RUN: %t.bin:aarch64 %t.input 2>&1 | FileCheck -check-prefix=AARCH64 %s
+; AARCH64: Injected args: -mtriple=aarch64
+
+; RUN: mv %t.bin:aarch64 %t.bin:aarch64-O1
+; RUN: %t.bin:aarch64-O1 %t.input 2>&1 | FileCheck -check-prefix=OPT-AFTER %s
+; OPT-AFTER: Injected args: -mtriple=aarch64 -O1
+
+; RUN: mv %t.bin:aarch64-O1 %t.bin:O3-aarch64
+; RUN: %t.bin:O3-aarch64 %t.input 2>&1 | FileCheck -check-prefix=OPT-BEFORE %s
+; OPT-BEFORE: Injected args: -O3 -mtriple=aarch64
diff --git a/llvm/test/tools/llvm-isel-fuzzer/execname-options.ll b/llvm/test/tools/llvm-isel-fuzzer/execname-options.ll
new file mode 100644
index 00000000000..8ebc1e96ddc
--- /dev/null
+++ b/llvm/test/tools/llvm-isel-fuzzer/execname-options.ll
@@ -0,0 +1,15 @@
+; RUN: echo > %t.input
+
+; RUN: cp llvm-isel-fuzzer %t.bin:gisel
+; RUN: not %t.bin:gisel %t.input 2>&1 | FileCheck -check-prefix=GISEL %s
+; GISEL: Injected args: -global-isel -O0
+; GISEL: -mtriple must be specified
+
+; RUN: cp llvm-isel-fuzzer %t.bin:gisel-O2
+; RUN: not %t.bin:gisel-O2 %t.input 2>&1 | FileCheck -check-prefix=GISEL-O2 %s
+; GISEL-O2: Injected args: -global-isel -O0 -O2
+; GISEL-O2: -mtriple must be specified
+
+; RUN: cp llvm-isel-fuzzer %t.bin:unexist
+; RUN: not %t.bin:unexist %t.input 2>&1 | FileCheck -check-prefix=NO-OPT %s
+; NO-OPT: Unknown option:
diff --git a/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp b/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp
index 314acdb5087..164c85f9516 100644
--- a/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp
+++ b/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp
@@ -150,6 +150,7 @@ extern "C" LLVM_ATTRIBUTE_USED int LLVMFuzzerInitialize(int *argc,
InitializeAllAsmPrinters();
InitializeAllAsmParsers();
+ handleExecNameEncodedBEOpts(*argv[0]);
parseFuzzerCLOpts(*argc, *argv);
if (TargetTriple.empty()) {
OpenPOWER on IntegriCloud