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