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
20 int ArgC, char *ArgV[]) {
21 std::vector<const char *> CLArgs;
22 CLArgs.push_back(ArgV[0]);
23
24 int I = 1;
25 while (I < ArgC)
26 if (StringRef(ArgV[I++]) == "-ignore_remaining_args=1")
27 break;
28 while (I < ArgC)
29 CLArgs.push_back(ArgV[I++]);
30
31 cl::parseCommandLineOptions(LibraryOptions, ToolOptions, CLArgs);
32}
33
35 cl::LibraryOptionsContext &LibraryOptions, StringRef ExecName) {
36 std::vector<std::string> Args{std::string(ExecName)};
37
38 auto NameAndArgs = ExecName.split("--");
39 if (NameAndArgs.second.empty())
40 return;
41
43 NameAndArgs.second.split(Opts, '-');
44 for (StringRef Opt : Opts) {
45 if (Opt == "gisel") {
46 Args.push_back("-global-isel");
47 // For now we default GlobalISel to -O0
48 Args.push_back("-O0");
49 } else if (Opt.starts_with("O")) {
50 Args.push_back("-" + Opt.str());
51 } else if (Triple(Opt).getArch()) {
52 Args.push_back("-mtriple=" + Opt.str());
53 } else {
54 errs() << ExecName << ": Unknown option: " << Opt << ".\n";
55 exit(1);
56 }
57 }
58 errs() << NameAndArgs.first << ": Injected args:";
59 for (int I = 1, E = Args.size(); I < E; ++I)
60 errs() << " " << Args[I];
61 errs() << "\n";
62
63 std::vector<const char *> CLArgs;
64 CLArgs.reserve(Args.size());
65 for (std::string &S : Args)
66 CLArgs.push_back(S.c_str());
67
68 cl::parseCommandLineOptions(LibraryOptions, CLArgs);
69}
70
72 cl::LibraryOptionsContext &LibraryOptions, StringRef ExecName) {
73 // TODO: Refactor parts common with the 'handleExecNameEncodedBEOpts'
74 std::vector<std::string> Args{std::string(ExecName)};
75
76 auto NameAndArgs = ExecName.split("--");
77 if (NameAndArgs.second.empty())
78 return;
79
81 NameAndArgs.second.split(Opts, '-');
82 for (StringRef Opt : Opts) {
83 if (Opt == "instcombine") {
84 Args.push_back("-passes=instcombine");
85 } else if (Opt == "earlycse") {
86 Args.push_back("-passes=early-cse");
87 } else if (Opt == "simplifycfg") {
88 Args.push_back("-passes=simplifycfg");
89 } else if (Opt == "gvn") {
90 Args.push_back("-passes=gvn");
91 } else if (Opt == "sccp") {
92 Args.push_back("-passes=sccp");
93 } else if (Opt == "loop_predication") {
94 Args.push_back("-passes=loop-predication");
95 } else if (Opt == "guard_widening") {
96 Args.push_back("-passes=guard-widening");
97 } else if (Opt == "loop_rotate") {
98 Args.push_back("-passes=loop-rotate");
99 } else if (Opt == "loop_unswitch") {
100 Args.push_back("-passes=loop(simple-loop-unswitch)");
101 } else if (Opt == "loop_unroll") {
102 Args.push_back("-passes=unroll");
103 } else if (Opt == "loop_vectorize") {
104 Args.push_back("-passes=loop-vectorize");
105 } else if (Opt == "licm") {
106 Args.push_back("-passes=licm");
107 } else if (Opt == "indvars") {
108 Args.push_back("-passes=indvars");
109 } else if (Opt == "strength_reduce") {
110 Args.push_back("-passes=loop-reduce");
111 } else if (Opt == "irce") {
112 Args.push_back("-passes=irce");
113 } else if (Opt == "dse") {
114 Args.push_back("-passes=dse");
115 } else if (Opt == "loop_idiom") {
116 Args.push_back("-passes=loop-idiom");
117 } else if (Opt == "reassociate") {
118 Args.push_back("-passes=reassociate");
119 } else if (Opt == "lower_matrix_intrinsics") {
120 Args.push_back("-passes=lower-matrix-intrinsics");
121 } else if (Opt == "memcpyopt") {
122 Args.push_back("-passes=memcpyopt");
123 } else if (Opt == "sroa") {
124 Args.push_back("-passes=sroa");
125 } else if (Triple(Opt).getArch()) {
126 Args.push_back("-mtriple=" + Opt.str());
127 } else {
128 errs() << ExecName << ": Unknown option: " << Opt << ".\n";
129 exit(1);
130 }
131 }
132
133 errs() << NameAndArgs.first << ": Injected args:";
134 for (int I = 1, E = Args.size(); I < E; ++I)
135 errs() << " " << Args[I];
136 errs() << "\n";
137
138 std::vector<const char *> CLArgs;
139 CLArgs.reserve(Args.size());
140 for (std::string &S : Args)
141 CLArgs.push_back(S.c_str());
142
143 cl::parseCommandLineOptions(LibraryOptions, CLArgs);
144}
145
146int llvm::runFuzzerOnInputs(int ArgC, char *ArgV[], FuzzerTestFun TestOne,
148 errs() << "*** This tool was not linked to libFuzzer.\n"
149 << "*** No fuzzing will be performed.\n";
150 if (int RC = Init(&ArgC, &ArgV)) {
151 errs() << "Initialization failed\n";
152 return RC;
153 }
154
155 for (int I = 1; I < ArgC; ++I) {
156 StringRef Arg(ArgV[I]);
157 if (Arg.starts_with("-")) {
158 if (Arg == "-ignore_remaining_args=1")
159 break;
160 continue;
161 }
162
163 auto BufOrErr = MemoryBuffer::getFile(Arg, /*IsText=*/false,
164 /*RequiresNullTerminator=*/false);
165 if (std::error_code EC = BufOrErr.getError()) {
166 errs() << "Error reading file: " << Arg << ": " << EC.message() << "\n";
167 return 1;
168 }
169 std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
170 errs() << "Running: " << Arg << " (" << Buf->getBufferSize() << " bytes)\n";
171 TestOne(reinterpret_cast<const uint8_t *>(Buf->getBufferStart()),
172 Buf->getBufferSize());
173 }
174 return 0;
175}
#define I(x, y, z)
Definition MD5.cpp:57
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
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 parseFuzzerCLOpts(cl::LibraryOptionsContext &LibraryOptions, ArrayRef< const cl::LibraryOptions * > ToolOptions, int ArgC, char *ArgV[])
Parse cl::opts from a fuzz target commandline.
Definition FuzzerCLI.cpp:18
LLVM_ABI void handleExecNameEncodedOptimizerOpts(cl::LibraryOptionsContext &LibraryOptions, StringRef ExecName)
Handle optimizer options which are encoded in the executable name.
Definition FuzzerCLI.cpp:71
int(*)(const uint8_t *Data, size_t Size) FuzzerTestFun
Definition FuzzerCLI.h:57
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:34
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:58