Coverage Report

Created: 2024-01-17 10:31

/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
}