forked from OSchip/llvm-project
llvm-isel-fuzzer: Handle a subset of backend flags in the executable name
Here we add a secondary option parser to llvm-isel-fuzzer (and provide it for use with other fuzzers). With this, you can copy the fuzzer to a name like llvm-isel-fuzzer:aarch64-gisel for a fuzzer that fuzzer AArch64 with GlobalISel enabled, or fuzzer:x86_64 to fuzz x86, with no flags required. This should be useful for running these in OSS-Fuzz. Note that this handrolls a subset of cl::opts to recognize, rather than embedding a complete command parser for argv[0]. If we find we really need the flexibility of handling arbitrary options at some point we can rethink this. llvm-svn: 315545
This commit is contained in:
parent
fd5b2a0806
commit
a5969ce15f
|
@ -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
|
||||
-----------------------
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
|
@ -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:
|
|
@ -150,6 +150,7 @@ extern "C" LLVM_ATTRIBUTE_USED int LLVMFuzzerInitialize(int *argc,
|
|||
InitializeAllAsmPrinters();
|
||||
InitializeAllAsmParsers();
|
||||
|
||||
handleExecNameEncodedBEOpts(*argv[0]);
|
||||
parseFuzzerCLOpts(*argc, *argv);
|
||||
|
||||
if (TargetTriple.empty()) {
|
||||
|
|
Loading…
Reference in New Issue