[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
This commit is contained in:
Igor Laevsky 2017-11-16 15:23:08 +00:00
parent c3347d4247
commit e714ef49af
4 changed files with 54 additions and 63 deletions

View File

@ -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<Module> 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

View File

@ -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<Module> 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<Module>("M", Context);
auto Buffer = MemoryBuffer::getMemBuffer(
StringRef(reinterpret_cast<const char *>(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();
}

View File

@ -52,33 +52,6 @@ TargetTriple("mtriple", cl::desc("Override target triple for module"));
static std::unique_ptr<TargetMachine> TM;
static std::unique_ptr<IRMutator> Mutator;
static std::unique_ptr<Module> parseModule(const uint8_t *Data, size_t Size,
LLVMContext &Context) {
auto Buffer = MemoryBuffer::getMemBuffer(
StringRef(reinterpret_cast<const char *>(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<IRMutator> createISelMutator() {
std::vector<TypeGetter> Types{
Type::getInt1Ty, Type::getInt8Ty, Type::getInt16Ty, Type::getInt32Ty,

View File

@ -37,42 +37,6 @@ static cl::opt<std::string> PassPipeline(
static std::unique_ptr<IRMutator> Mutator;
static std::unique_ptr<TargetMachine> TM;
// This function is mostly copied from the llvm-isel-fuzzer.
// TODO: Move this into FuzzMutate library and reuse.
static std::unique_ptr<Module> 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<Module>("M", Context);
auto Buffer = MemoryBuffer::getMemBuffer(
StringRef(reinterpret_cast<const char *>(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<IRMutator> createOptMutator() {
std::vector<TypeGetter> Types{
Type::getInt1Ty, Type::getInt8Ty, Type::getInt16Ty, Type::getInt32Ty,