[llvm] 0a83ff8 - [FuzzMutate] Move LLVM module (de)serialization from FuzzerCLI -> IRMutator. NFC

Sam McCall via llvm-commits llvm-commits at lists.llvm.org
Sat May 7 03:11:43 PDT 2022


Author: Sam McCall
Date: 2022-05-07T12:09:49+02:00
New Revision: 0a83ff83af3d8db5512d61e043c246d854502e9e

URL: https://github.com/llvm/llvm-project/commit/0a83ff83af3d8db5512d61e043c246d854502e9e
DIFF: https://github.com/llvm/llvm-project/commit/0a83ff83af3d8db5512d61e043c246d854502e9e.diff

LOG: [FuzzMutate] Move LLVM module (de)serialization from FuzzerCLI -> IRMutator. NFC

These are not directly related to the CLI, and are mostly (always?) used when
mutating the modules as part of fuzzing.

Motivation: split FuzzerCLI into its own library that does not depend on IR.
Subprojects that don't use IR should be be fuzzed without the dependency.

Differential Revision: https://reviews.llvm.org/D125080

Added: 
    

Modified: 
    llvm/include/llvm/FuzzMutate/FuzzerCLI.h
    llvm/include/llvm/FuzzMutate/IRMutator.h
    llvm/lib/FuzzMutate/FuzzerCLI.cpp
    llvm/lib/FuzzMutate/IRMutator.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/FuzzMutate/FuzzerCLI.h b/llvm/include/llvm/FuzzMutate/FuzzerCLI.h
index 8ae767bb3aa2e..7a4b1008efbe7 100644
--- a/llvm/include/llvm/FuzzMutate/FuzzerCLI.h
+++ b/llvm/include/llvm/FuzzMutate/FuzzerCLI.h
@@ -20,8 +20,6 @@
 
 namespace llvm {
 
-class LLVMContext;
-class Module;
 class StringRef;
 
 /// Parse cl::opts from a fuzz target commandline.
@@ -54,29 +52,6 @@ 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);
-
-/// Try to parse module and verify it. May output verification errors to the
-/// errs().
-/// \return New module or nullptr in case of error.
-std::unique_ptr<Module> parseAndVerify(const uint8_t *Data, size_t Size,
-                                       LLVMContext &Context);
-
-} // end llvm namespace
+} // namespace llvm
 
 #endif // LLVM_FUZZMUTATE_FUZZERCLI_H

diff  --git a/llvm/include/llvm/FuzzMutate/IRMutator.h b/llvm/include/llvm/FuzzMutate/IRMutator.h
index 423582eace9b2..ade76f1b5845d 100644
--- a/llvm/include/llvm/FuzzMutate/IRMutator.h
+++ b/llvm/include/llvm/FuzzMutate/IRMutator.h
@@ -10,6 +10,9 @@
 // configurable set of strategies. Some common strategies are also included
 // here.
 //
+// Fuzzer-friendly (de)serialization functions are also provided, as these
+// are usually needed when mutating IR.
+//
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_FUZZMUTATE_IRMUTATOR_H
@@ -113,6 +116,29 @@ class InstModificationIRStrategy : public IRMutationStrategy {
   void mutate(Instruction &Inst, RandomIRBuilder &IB) override;
 };
 
+/// 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);
+
+/// Try to parse module and verify it. May output verification errors to the
+/// errs().
+/// \return New module or nullptr in case of error.
+std::unique_ptr<Module> parseAndVerify(const uint8_t *Data, size_t Size,
+                                       LLVMContext &Context);
+
 } // end llvm namespace
 
 #endif // LLVM_FUZZMUTATE_IRMUTATOR_H

diff  --git a/llvm/lib/FuzzMutate/FuzzerCLI.cpp b/llvm/lib/FuzzMutate/FuzzerCLI.cpp
index 5473c84b2c378..90a1a35e2e3e1 100644
--- a/llvm/lib/FuzzMutate/FuzzerCLI.cpp
+++ b/llvm/lib/FuzzMutate/FuzzerCLI.cpp
@@ -9,14 +9,8 @@
 #include "llvm/FuzzMutate/FuzzerCLI.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Triple.h"
-#include "llvm/Bitcode/BitcodeReader.h"
-#include "llvm/Bitcode/BitcodeWriter.h"
-#include "llvm/IR/Verifier.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;
@@ -165,44 +159,3 @@ 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 std::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();
-}
-
-std::unique_ptr<Module> llvm::parseAndVerify(const uint8_t *Data, size_t Size,
-                                             LLVMContext &Context) {
-  auto M = parseModule(Data, Size, Context);
-  if (!M || verifyModule(*M, &errs()))
-    return nullptr;
-
-  return M;
-}

diff  --git a/llvm/lib/FuzzMutate/IRMutator.cpp b/llvm/lib/FuzzMutate/IRMutator.cpp
index 105f8bc6c5227..b62a326a40cca 100644
--- a/llvm/lib/FuzzMutate/IRMutator.cpp
+++ b/llvm/lib/FuzzMutate/IRMutator.cpp
@@ -9,6 +9,8 @@
 #include "llvm/FuzzMutate/IRMutator.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Bitcode/BitcodeReader.h"
+#include "llvm/Bitcode/BitcodeWriter.h"
 #include "llvm/FuzzMutate/Operations.h"
 #include "llvm/FuzzMutate/Random.h"
 #include "llvm/FuzzMutate/RandomIRBuilder.h"
@@ -17,6 +19,9 @@
 #include "llvm/IR/InstIterator.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
 #include "llvm/Transforms/Scalar/DCE.h"
 
 using namespace llvm;
@@ -243,3 +248,44 @@ void InstModificationIRStrategy::mutate(Instruction &Inst,
   if (RS)
     RS.getSelection()();
 }
+
+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 std::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();
+}
+
+std::unique_ptr<Module> llvm::parseAndVerify(const uint8_t *Data, size_t Size,
+                                             LLVMContext &Context) {
+  auto M = parseModule(Data, Size, Context);
+  if (!M || verifyModule(*M, &errs()))
+    return nullptr;
+
+  return M;
+}


        


More information about the llvm-commits mailing list