brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · 22d33e1 Raw
154 lines · cpp
1//===--- llvm-isel-fuzzer.cpp - Fuzzer for instruction selection ----------===//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// Tool to fuzz instruction selection using libFuzzer.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/ADT/StringRef.h"14#include "llvm/Analysis/TargetLibraryInfo.h"15#include "llvm/Bitcode/BitcodeReader.h"16#include "llvm/Bitcode/BitcodeWriter.h"17#include "llvm/CodeGen/CommandFlags.h"18#include "llvm/FuzzMutate/FuzzerCLI.h"19#include "llvm/FuzzMutate/IRMutator.h"20#include "llvm/FuzzMutate/Operations.h"21#include "llvm/IR/Constants.h"22#include "llvm/IR/LLVMContext.h"23#include "llvm/IR/LegacyPassManager.h"24#include "llvm/IR/Module.h"25#include "llvm/IR/Verifier.h"26#include "llvm/IRReader/IRReader.h"27#include "llvm/MC/TargetRegistry.h"28#include "llvm/Support/CommandLine.h"29#include "llvm/Support/DataTypes.h"30#include "llvm/Support/Debug.h"31#include "llvm/Support/SourceMgr.h"32#include "llvm/Support/TargetSelect.h"33#include "llvm/Target/TargetMachine.h"34 35#define DEBUG_TYPE "isel-fuzzer"36 37using namespace llvm;38 39static codegen::RegisterCodeGenFlags CGF;40 41static cl::opt<char>42    OptLevel("O",43             cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "44                      "(default = '-O2')"),45             cl::Prefix, cl::init('2'));46 47static cl::opt<std::string>48    TargetTriple("mtriple", cl::desc("Override target triple for module"));49 50static std::unique_ptr<TargetMachine> TM;51static std::unique_ptr<IRMutator> Mutator;52 53std::unique_ptr<IRMutator> createISelMutator() {54  std::vector<TypeGetter> Types{55      Type::getInt1Ty,  Type::getInt8Ty,  Type::getInt16Ty, Type::getInt32Ty,56      Type::getInt64Ty, Type::getFloatTy, Type::getDoubleTy};57 58  std::vector<std::unique_ptr<IRMutationStrategy>> Strategies;59  Strategies.emplace_back(60      new InjectorIRStrategy(InjectorIRStrategy::getDefaultOps()));61  Strategies.emplace_back(new InstDeleterIRStrategy());62 63  return std::make_unique<IRMutator>(std::move(Types), std::move(Strategies));64}65 66extern "C" LLVM_ATTRIBUTE_USED size_t LLVMFuzzerCustomMutator(67    uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed) {68  LLVMContext Context;69  std::unique_ptr<Module> M;70  if (Size <= 1)71    // We get bogus data given an empty corpus - just create a new module.72    M.reset(new Module("M", Context));73  else74    M = parseModule(Data, Size, Context);75 76  Mutator->mutateModule(*M, Seed, MaxSize); // use max bitcode size as a guide77 78  return writeModule(*M, Data, MaxSize);79}80 81extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {82  if (Size <= 1)83    // We get bogus data given an empty corpus - ignore it.84    return 0;85 86  LLVMContext Context;87  auto M = parseAndVerify(Data, Size, Context);88  if (!M) {89    errs() << "error: input module is broken!\n";90    return 0;91  }92 93  // Set up the module to build for our target.94  M->setTargetTriple(TM->getTargetTriple());95  M->setDataLayout(TM->createDataLayout());96 97  // Build up a PM to do instruction selection.98  legacy::PassManager PM;99  TargetLibraryInfoImpl TLII(TM->getTargetTriple());100  PM.add(new TargetLibraryInfoWrapperPass(TLII));101  raw_null_ostream OS;102  TM->addPassesToEmitFile(PM, OS, nullptr, CodeGenFileType::Null);103  PM.run(*M);104 105  return 0;106}107 108static void handleLLVMFatalError(void *, const char *Message, bool) {109  // TODO: Would it be better to call into the fuzzer internals directly?110  dbgs() << "LLVM ERROR: " << Message << "\n"111         << "Aborting to trigger fuzzer exit handling.\n";112  abort();113}114 115extern "C" LLVM_ATTRIBUTE_USED int LLVMFuzzerInitialize(int *argc,116                                                        char ***argv) {117  EnableDebugBuffering = true;118  StringRef ExecName = *argv[0];119 120  InitializeAllTargets();121  InitializeAllTargetMCs();122  InitializeAllAsmPrinters();123  InitializeAllAsmParsers();124 125  handleExecNameEncodedBEOpts(ExecName);126  parseFuzzerCLOpts(*argc, *argv);127 128  if (TargetTriple.empty()) {129    errs() << ExecName << ": -mtriple must be specified\n";130    exit(1);131  }132 133  // Set up the pipeline like llc does.134 135  CodeGenOptLevel OLvl;136  if (auto Level = CodeGenOpt::parseLevel(OptLevel)) {137    OLvl = *Level;138  } else {139    errs() << ExecName << ": invalid optimization level.\n";140    return 1;141  }142  ExitOnError ExitOnErr(std::string(ExecName) + ": error:");143  TM = ExitOnErr(codegen::createTargetMachineForTriple(144      Triple::normalize(TargetTriple), OLvl));145  assert(TM && "Could not allocate target machine!");146 147  // Make sure we print the summary and the current unit when LLVM errors out.148  install_fatal_error_handler(handleLLVMFatalError, nullptr);149 150  // Finally, create our mutator.151  Mutator = createISelMutator();152  return 0;153}154