From e714ef49afef7fc2d6f478974acf2c49860d05dc Mon Sep 17 00:00:00 2001 From: Igor Laevsky Date: Thu, 16 Nov 2017 15:23:08 +0000 Subject: [PATCH] [FuzzMutate] NFC. Move parseModule and writeModule from llvm-isel-fuzzer into FuzzMutate. This is to be able to reuse them in the llvm-opt-fuzzer. llvm-svn: 318407 --- llvm/include/llvm/FuzzMutate/FuzzerCLI.h | 18 ++++++++++ llvm/lib/FuzzMutate/FuzzerCLI.cpp | 36 +++++++++++++++++++ .../llvm-isel-fuzzer/llvm-isel-fuzzer.cpp | 27 -------------- .../tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp | 36 ------------------- 4 files changed, 54 insertions(+), 63 deletions(-) diff --git a/llvm/include/llvm/FuzzMutate/FuzzerCLI.h b/llvm/include/llvm/FuzzMutate/FuzzerCLI.h index c7350f6909e6..a775fdfb603e 100644 --- a/llvm/include/llvm/FuzzMutate/FuzzerCLI.h +++ b/llvm/include/llvm/FuzzMutate/FuzzerCLI.h @@ -16,6 +16,7 @@ #define LLVM_FUZZMUTATE_FUZZER_CLI_H #include "llvm/ADT/StringRef.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -50,6 +51,23 @@ using FuzzerInitFun = int (*)(int *argc, char ***argv); int runFuzzerOnInputs(int ArgC, char *ArgV[], FuzzerTestFun TestOne, FuzzerInitFun Init = [](int *, char ***) { return 0; }); +/// Fuzzer friendly interface for the llvm bitcode parser. +/// +/// \param Data Bitcode we are going to parse +/// \param Size Size of the 'Data' in bytes +/// \return New module or nullptr in case of error +std::unique_ptr parseModule(const uint8_t *Data, size_t Size, + LLVMContext &Context); + +/// Fuzzer friendly interface for the llvm bitcode printer. +/// +/// \param M Module to print +/// \param Dest Location to store serialized module +/// \param MaxSize Size of the destination buffer +/// \return Number of bytes that were written. When module size exceeds MaxSize +/// returns 0 and leaves Dest unchanged. +size_t writeModule(const Module &M, uint8_t *Dest, size_t MaxSize); + } // end llvm namespace #endif // LLVM_FUZZMUTATE_FUZZER_CLI_H diff --git a/llvm/lib/FuzzMutate/FuzzerCLI.cpp b/llvm/lib/FuzzMutate/FuzzerCLI.cpp index 906f7af393f1..158edf203895 100644 --- a/llvm/lib/FuzzMutate/FuzzerCLI.cpp +++ b/llvm/lib/FuzzMutate/FuzzerCLI.cpp @@ -9,10 +9,14 @@ #include "llvm/FuzzMutate/FuzzerCLI.h" #include "llvm/ADT/Triple.h" +#include "llvm/Bitcode/BitcodeReader.h" +#include "llvm/Bitcode/BitcodeWriter.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -131,3 +135,35 @@ int llvm::runFuzzerOnInputs(int ArgC, char *ArgV[], FuzzerTestFun TestOne, } return 0; } + +std::unique_ptr llvm::parseModule( + const uint8_t *Data, size_t Size, LLVMContext &Context) { + + if (Size <= 1) + // We get bogus data given an empty corpus - just create a new module. + return llvm::make_unique("M", Context); + + auto Buffer = MemoryBuffer::getMemBuffer( + StringRef(reinterpret_cast(Data), Size), "Fuzzer input", + /*RequiresNullTerminator=*/false); + + SMDiagnostic Err; + auto M = parseBitcodeFile(Buffer->getMemBufferRef(), Context); + if (Error E = M.takeError()) { + errs() << toString(std::move(E)) << "\n"; + return nullptr; + } + return std::move(M.get()); +} + +size_t llvm::writeModule(const Module &M, uint8_t *Dest, size_t MaxSize) { + std::string Buf; + { + raw_string_ostream OS(Buf); + WriteBitcodeToFile(&M, OS); + } + if (Buf.size() > MaxSize) + return 0; + memcpy(Dest, Buf.data(), Buf.size()); + return Buf.size(); +} diff --git a/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp b/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp index cc886adeb787..f0a963b98d85 100644 --- a/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp +++ b/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp @@ -52,33 +52,6 @@ TargetTriple("mtriple", cl::desc("Override target triple for module")); static std::unique_ptr TM; static std::unique_ptr Mutator; -static std::unique_ptr parseModule(const uint8_t *Data, size_t Size, - LLVMContext &Context) { - auto Buffer = MemoryBuffer::getMemBuffer( - StringRef(reinterpret_cast(Data), Size), "Fuzzer input", - /*RequiresNullTerminator=*/false); - - SMDiagnostic Err; - auto M = parseBitcodeFile(Buffer->getMemBufferRef(), Context); - if (Error E = M.takeError()) { - errs() << toString(std::move(E)) << "\n"; - return nullptr; - } - return std::move(M.get()); -} - -static size_t writeModule(const Module &M, uint8_t *Dest, size_t MaxSize) { - std::string Buf; - { - raw_string_ostream OS(Buf); - WriteBitcodeToFile(&M, OS); - } - if (Buf.size() > MaxSize) - return 0; - memcpy(Dest, Buf.data(), Buf.size()); - return Buf.size(); -} - std::unique_ptr createISelMutator() { std::vector Types{ Type::getInt1Ty, Type::getInt8Ty, Type::getInt16Ty, Type::getInt32Ty, diff --git a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp index 1bbfa5b148b7..7ca1d93d70d3 100644 --- a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp +++ b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp @@ -37,42 +37,6 @@ static cl::opt PassPipeline( static std::unique_ptr Mutator; static std::unique_ptr TM; -// This function is mostly copied from the llvm-isel-fuzzer. -// TODO: Move this into FuzzMutate library and reuse. -static std::unique_ptr parseModule(const uint8_t *Data, size_t Size, - LLVMContext &Context) { - - if (Size <= 1) - // We get bogus data given an empty corpus - just create a new module. - return llvm::make_unique("M", Context); - - auto Buffer = MemoryBuffer::getMemBuffer( - StringRef(reinterpret_cast(Data), Size), "Fuzzer input", - /*RequiresNullTerminator=*/false); - - SMDiagnostic Err; - auto M = parseBitcodeFile(Buffer->getMemBufferRef(), Context); - if (Error E = M.takeError()) { - errs() << toString(std::move(E)) << "\n"; - return nullptr; - } - return std::move(M.get()); -} - -// This function is copied from the llvm-isel-fuzzer. -// TODO: Move this into FuzzMutate library and reuse. -static size_t writeModule(const Module &M, uint8_t *Dest, size_t MaxSize) { - std::string Buf; - { - raw_string_ostream OS(Buf); - WriteBitcodeToFile(&M, OS); - } - if (Buf.size() > MaxSize) - return 0; - memcpy(Dest, Buf.data(), Buf.size()); - return Buf.size(); -} - std::unique_ptr createOptMutator() { std::vector Types{ Type::getInt1Ty, Type::getInt8Ty, Type::getInt16Ty, Type::getInt32Ty,