LLVM 24.0.0git
FuzzerCLI.cpp
Go to the documentation of this file.
1//===-- FuzzerCLI.cpp -----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "llvm/ADT/StringRef.h"
15
16using namespace llvm;
17
19 int ArgC, char *ArgV[]) {
20 std::vector<const char *> CLArgs;
21 CLArgs.push_back(ArgV[0]);
22
23 int I = 1;
24 while (I < ArgC)
25 if (StringRef(ArgV[I++]) == "-ignore_remaining_args=1")
26 break;
27 while (I < ArgC)
28 CLArgs.push_back(ArgV[I++]);
29
30 cl::parseCommandLineOptions(LibraryOptions, CLArgs);
31}
32
34 cl::LibraryOptionsContext &LibraryOptions, StringRef ExecName) {
35 std::vector<std::string> Args{std::string(ExecName)};
36
37 auto NameAndArgs = ExecName.split("--");
38 if (NameAndArgs.second.empty())
39 return;
40
42 NameAndArgs.second.split(Opts, '-');
43 for (StringRef Opt : Opts) {
44 if (Opt == "gisel") {
45 Args.push_back("-global-isel");
46 // For now we default GlobalISel to -O0
47 Args.push_back("-O0");
48 } else if (Opt.starts_with("O")) {
49 Args.push_back("-" + Opt.str());
50 } else if (Triple(Opt).getArch()) {
51 Args.push_back("-mtriple=" + Opt.str());
52 } else {
53 errs() << ExecName << ": Unknown option: " << Opt << ".\n";
54 exit(1);
55 }
56 }
57 errs() << NameAndArgs.first << ": Injected args:";
58 for (int I = 1, E = Args.size(); I < E; ++I)
59 errs() << " " << Args[I];
60 errs() << "\n";
61
62 std::vector<const char *> CLArgs;
63 CLArgs.reserve(Args.size());
64 for (std::string &S : Args)
65 CLArgs.push_back(S.c_str());
66
67 cl::parseCommandLineOptions(LibraryOptions, CLArgs);
68}
69
71 cl::LibraryOptionsContext &LibraryOptions, StringRef ExecName) {
72 // TODO: Refactor parts common with the 'handleExecNameEncodedBEOpts'
73 std::vector<std::string> Args{std::string(ExecName)};
74
75 auto NameAndArgs = ExecName.split("--");
76 if (NameAndArgs.second.empty())
77 return;
78
80 NameAndArgs.second.split(Opts, '-');
81 for (StringRef Opt : Opts) {
82 if (Opt == "instcombine") {
83 Args.push_back("-passes=instcombine");
84 } else if (Opt == "earlycse") {
85 Args.push_back("-passes=early-cse");
86 } else if (Opt == "simplifycfg") {
87 Args.push_back("-passes=simplifycfg");
88 } else if (Opt == "gvn") {
89 Args.push_back("-passes=gvn");
90 } else if (Opt == "sccp") {
91 Args.push_back("-passes=sccp");
92 } else if (Opt == "loop_predication") {
93 Args.push_back("-passes=loop-predication");
94 } else if (Opt == "guard_widening") {
95 Args.push_back("-passes=guard-widening");
96 } else if (Opt == "loop_rotate") {
97 Args.push_back("-passes=loop-rotate");
98 } else if (Opt == "loop_unswitch") {
99 Args.push_back("-passes=loop(simple-loop-unswitch)");
100 } else if (Opt == "loop_unroll") {
101 Args.push_back("-passes=unroll");
102 } else if (Opt == "loop_vectorize") {
103 Args.push_back("-passes=loop-vectorize");
104 } else if (Opt == "licm") {
105 Args.push_back("-passes=licm");
106 } else if (Opt == "indvars") {
107 Args.push_back("-passes=indvars");
108 } else if (Opt == "strength_reduce") {
109 Args.push_back("-passes=loop-reduce");
110 } else if (Opt == "irce") {
111 Args.push_back("-passes=irce");
112 } else if (Opt == "dse") {
113 Args.push_back("-passes=dse");
114 } else if (Opt == "loop_idiom") {
115 Args.push_back("-passes=loop-idiom");
116 } else if (Opt == "reassociate") {
117 Args.push_back("-passes=reassociate");
118 } else if (Opt == "lower_matrix_intrinsics") {
119 Args.push_back("-passes=lower-matrix-intrinsics");
120 } else if (Opt == "memcpyopt") {
121 Args.push_back("-passes=memcpyopt");
122 } else if (Opt == "sroa") {
123 Args.push_back("-passes=sroa");
124 } else if (Triple(Opt).getArch()) {
125 Args.push_back("-mtriple=" + Opt.str());
126 } else {
127 errs() << ExecName << ": Unknown option: " << Opt << ".\n";
128 exit(1);
129 }
130 }
131
132 errs() << NameAndArgs.first << ": Injected args:";
133 for (int I = 1, E = Args.size(); I < E; ++I)
134 errs() << " " << Args[I];
135 errs() << "\n";
136
137 std::vector<const char *> CLArgs;
138 CLArgs.reserve(Args.size());
139 for (std::string &S : Args)
140 CLArgs.push_back(S.c_str());
141
142 cl::parseCommandLineOptions(LibraryOptions, CLArgs);
143}
144
145int llvm::runFuzzerOnInputs(int ArgC, char *ArgV[], FuzzerTestFun TestOne,
147 errs() << "*** This tool was not linked to libFuzzer.\n"
148 << "*** No fuzzing will be performed.\n";
149 if (int RC = Init(&ArgC, &ArgV)) {
150 errs() << "Initialization failed\n";
151 return RC;
152 }
153
154 for (int I = 1; I < ArgC; ++I) {
155 StringRef Arg(ArgV[I]);
156 if (Arg.starts_with("-")) {
157 if (Arg == "-ignore_remaining_args=1")
158 break;
159 continue;
160 }
161
162 auto BufOrErr = MemoryBuffer::getFile(Arg, /*IsText=*/false,
163 /*RequiresNullTerminator=*/false);
164 if (std::error_code EC = BufOrErr.getError()) {
165 errs() << "Error reading file: " << Arg << ": " << EC.message() << "\n";
166 return 1;
167 }
168 std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
169 errs() << "Running: " << Arg << " (" << Buf->getBufferSize() << " bytes)\n";
170 TestOne(reinterpret_cast<const uint8_t *>(Buf->getBufferStart()),
171 Buf->getBufferSize());
172 }
173 return 0;
174}
#define I(x, y, z)
Definition MD5.cpp:57
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:736
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
LLVM_ABI bool parseCommandLineOptions(LibraryOptionsContext &Context, ArrayRef< const char * > Args, StringRef Overview="", raw_ostream *Errs=nullptr, vfs::FileSystem *VFS=nullptr, const char *EnvVar=nullptr)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void handleExecNameEncodedOptimizerOpts(cl::LibraryOptionsContext &LibraryOptions, StringRef ExecName)
Handle optimizer options which are encoded in the executable name.
Definition FuzzerCLI.cpp:70
int(*)(const uint8_t *Data, size_t Size) FuzzerTestFun
Definition FuzzerCLI.h:53
LLVM_ABI int runFuzzerOnInputs(int ArgC, char *ArgV[], FuzzerTestFun TestOne, FuzzerInitFun Init=[](int *, char ***) { return 0;})
Runs a fuzz target on the inputs specified on the command line.
LLVM_ABI void handleExecNameEncodedBEOpts(cl::LibraryOptionsContext &LibraryOptions, StringRef ExecName)
Handle backend options that are encoded in the executable name.
Definition FuzzerCLI.cpp:33
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
int(*)(int *argc, char ***argv) FuzzerInitFun
Definition FuzzerCLI.h:54
LLVM_ABI void parseFuzzerCLOpts(cl::LibraryOptionsContext &LibraryOptions, int ArgC, char *ArgV[])
Parse cl::opts from a fuzz target commandline.
Definition FuzzerCLI.cpp:18