/src/llvm-project/llvm/lib/FuzzMutate/FuzzerCLI.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | |
9 | | #include "llvm/FuzzMutate/FuzzerCLI.h" |
10 | | #include "llvm/ADT/StringRef.h" |
11 | | #include "llvm/Support/CommandLine.h" |
12 | | #include "llvm/Support/MemoryBuffer.h" |
13 | | #include "llvm/Support/raw_ostream.h" |
14 | | #include "llvm/TargetParser/Triple.h" |
15 | | |
16 | | using namespace llvm; |
17 | | |
18 | 62 | void llvm::parseFuzzerCLOpts(int ArgC, char *ArgV[]) { |
19 | 62 | std::vector<const char *> CLArgs; |
20 | 62 | CLArgs.push_back(ArgV[0]); |
21 | | |
22 | 62 | int I = 1; |
23 | 341 | while (I < ArgC) |
24 | 279 | if (StringRef(ArgV[I++]).equals("-ignore_remaining_args=1")) |
25 | 0 | break; |
26 | 62 | while (I < ArgC) |
27 | 0 | CLArgs.push_back(ArgV[I++]); |
28 | | |
29 | 62 | cl::ParseCommandLineOptions(CLArgs.size(), CLArgs.data()); |
30 | 62 | } |
31 | | |
32 | 24 | void llvm::handleExecNameEncodedBEOpts(StringRef ExecName) { |
33 | 24 | std::vector<std::string> Args{std::string(ExecName)}; |
34 | | |
35 | 24 | auto NameAndArgs = ExecName.split("--"); |
36 | 24 | if (NameAndArgs.second.empty()) |
37 | 0 | return; |
38 | | |
39 | 24 | SmallVector<StringRef, 4> Opts; |
40 | 24 | NameAndArgs.second.split(Opts, '-'); |
41 | 48 | for (StringRef Opt : Opts) { |
42 | 48 | if (Opt.equals("gisel")) { |
43 | 2 | Args.push_back("-global-isel"); |
44 | | // For now we default GlobalISel to -O0 |
45 | 2 | Args.push_back("-O0"); |
46 | 46 | } else if (Opt.starts_with("O")) { |
47 | 22 | Args.push_back("-" + Opt.str()); |
48 | 24 | } else if (Triple(Opt).getArch()) { |
49 | 24 | Args.push_back("-mtriple=" + Opt.str()); |
50 | 24 | } else { |
51 | 0 | errs() << ExecName << ": Unknown option: " << Opt << ".\n"; |
52 | 0 | exit(1); |
53 | 0 | } |
54 | 48 | } |
55 | 24 | errs() << NameAndArgs.first << ": Injected args:"; |
56 | 74 | for (int I = 1, E = Args.size(); I < E; ++I) |
57 | 50 | errs() << " " << Args[I]; |
58 | 24 | errs() << "\n"; |
59 | | |
60 | 24 | std::vector<const char *> CLArgs; |
61 | 24 | CLArgs.reserve(Args.size()); |
62 | 24 | for (std::string &S : Args) |
63 | 74 | CLArgs.push_back(S.c_str()); |
64 | | |
65 | 24 | cl::ParseCommandLineOptions(CLArgs.size(), CLArgs.data()); |
66 | 24 | } |
67 | | |
68 | 38 | void llvm::handleExecNameEncodedOptimizerOpts(StringRef ExecName) { |
69 | | // TODO: Refactor parts common with the 'handleExecNameEncodedBEOpts' |
70 | 38 | std::vector<std::string> Args{std::string(ExecName)}; |
71 | | |
72 | 38 | auto NameAndArgs = ExecName.split("--"); |
73 | 38 | if (NameAndArgs.second.empty()) |
74 | 0 | return; |
75 | | |
76 | 38 | SmallVector<StringRef, 4> Opts; |
77 | 38 | NameAndArgs.second.split(Opts, '-'); |
78 | 76 | for (StringRef Opt : Opts) { |
79 | 76 | if (Opt == "instcombine") { |
80 | 2 | Args.push_back("-passes=instcombine"); |
81 | 74 | } else if (Opt == "earlycse") { |
82 | 2 | Args.push_back("-passes=early-cse"); |
83 | 72 | } else if (Opt == "simplifycfg") { |
84 | 2 | Args.push_back("-passes=simplifycfg"); |
85 | 70 | } else if (Opt == "gvn") { |
86 | 2 | Args.push_back("-passes=gvn"); |
87 | 68 | } else if (Opt == "sccp") { |
88 | 2 | Args.push_back("-passes=sccp"); |
89 | 66 | } else if (Opt == "loop_predication") { |
90 | 2 | Args.push_back("-passes=loop-predication"); |
91 | 64 | } else if (Opt == "guard_widening") { |
92 | 2 | Args.push_back("-passes=guard-widening"); |
93 | 62 | } else if (Opt == "loop_rotate") { |
94 | 0 | Args.push_back("-passes=loop-rotate"); |
95 | 62 | } else if (Opt == "loop_unswitch") { |
96 | 2 | Args.push_back("-passes=loop(simple-loop-unswitch)"); |
97 | 60 | } else if (Opt == "loop_unroll") { |
98 | 0 | Args.push_back("-passes=unroll"); |
99 | 60 | } else if (Opt == "loop_vectorize") { |
100 | 2 | Args.push_back("-passes=loop-vectorize"); |
101 | 58 | } else if (Opt == "licm") { |
102 | 2 | Args.push_back("-passes=licm"); |
103 | 56 | } else if (Opt == "indvars") { |
104 | 2 | Args.push_back("-passes=indvars"); |
105 | 54 | } else if (Opt == "strength_reduce") { |
106 | 2 | Args.push_back("-passes=loop-reduce"); |
107 | 52 | } else if (Opt == "irce") { |
108 | 2 | Args.push_back("-passes=irce"); |
109 | 50 | } else if (Opt == "dse") { |
110 | 2 | Args.push_back("-passes=dse"); |
111 | 48 | } else if (Opt == "loop_idiom") { |
112 | 2 | Args.push_back("-passes=loop-idiom"); |
113 | 46 | } else if (Opt == "reassociate") { |
114 | 2 | Args.push_back("-passes=reassociate"); |
115 | 44 | } else if (Opt == "lower_matrix_intrinsics") { |
116 | 2 | Args.push_back("-passes=lower-matrix-intrinsics"); |
117 | 42 | } else if (Opt == "memcpyopt") { |
118 | 2 | Args.push_back("-passes=memcpyopt"); |
119 | 40 | } else if (Opt == "sroa") { |
120 | 2 | Args.push_back("-passes=sroa"); |
121 | 38 | } else if (Triple(Opt).getArch()) { |
122 | 38 | Args.push_back("-mtriple=" + Opt.str()); |
123 | 38 | } else { |
124 | 0 | errs() << ExecName << ": Unknown option: " << Opt << ".\n"; |
125 | 0 | exit(1); |
126 | 0 | } |
127 | 76 | } |
128 | | |
129 | 38 | errs() << NameAndArgs.first << ": Injected args:"; |
130 | 114 | for (int I = 1, E = Args.size(); I < E; ++I) |
131 | 76 | errs() << " " << Args[I]; |
132 | 38 | errs() << "\n"; |
133 | | |
134 | 38 | std::vector<const char *> CLArgs; |
135 | 38 | CLArgs.reserve(Args.size()); |
136 | 38 | for (std::string &S : Args) |
137 | 114 | CLArgs.push_back(S.c_str()); |
138 | | |
139 | 38 | cl::ParseCommandLineOptions(CLArgs.size(), CLArgs.data()); |
140 | 38 | } |
141 | | |
142 | | int llvm::runFuzzerOnInputs(int ArgC, char *ArgV[], FuzzerTestFun TestOne, |
143 | 0 | FuzzerInitFun Init) { |
144 | 0 | errs() << "*** This tool was not linked to libFuzzer.\n" |
145 | 0 | << "*** No fuzzing will be performed.\n"; |
146 | 0 | if (int RC = Init(&ArgC, &ArgV)) { |
147 | 0 | errs() << "Initialization failed\n"; |
148 | 0 | return RC; |
149 | 0 | } |
150 | | |
151 | 0 | for (int I = 1; I < ArgC; ++I) { |
152 | 0 | StringRef Arg(ArgV[I]); |
153 | 0 | if (Arg.starts_with("-")) { |
154 | 0 | if (Arg.equals("-ignore_remaining_args=1")) |
155 | 0 | break; |
156 | 0 | continue; |
157 | 0 | } |
158 | | |
159 | 0 | auto BufOrErr = MemoryBuffer::getFile(Arg, /*IsText=*/false, |
160 | 0 | /*RequiresNullTerminator=*/false); |
161 | 0 | if (std::error_code EC = BufOrErr.getError()) { |
162 | 0 | errs() << "Error reading file: " << Arg << ": " << EC.message() << "\n"; |
163 | 0 | return 1; |
164 | 0 | } |
165 | 0 | std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get()); |
166 | 0 | errs() << "Running: " << Arg << " (" << Buf->getBufferSize() << " bytes)\n"; |
167 | 0 | TestOne(reinterpret_cast<const uint8_t *>(Buf->getBufferStart()), |
168 | 0 | Buf->getBufferSize()); |
169 | 0 | } |
170 | 0 | return 0; |
171 | 0 | } |