OSDN Git Service

Allow pnacl-sz to be compiled to textual bitcode records.
authorKarl Schimpf <kschimpf@google.com>
Mon, 22 Jun 2015 20:20:23 +0000 (13:20 -0700)
committerKarl Schimpf <kschimpf@google.com>
Mon, 22 Jun 2015 20:20:23 +0000 (13:20 -0700)
This has been added to allow fuzzing to be applied to textual bitcode
records. When built with make option TEXTUAL_BITCODE=1, the
corresponding generated pnacl-sz will preprocess the input file
(containing the textual form of bitcode records) and generate
a corresponding data stream with the binary form.

Note that the texual form of bitcode records is not LLVM assembly
(i.e. .ll files). Rather, it is sequences of texual integers
corresponding to bitcode records.

Dependent on: https://codereview.chromium.org/1191393004

BUG= https://code.google.com/p/nativeclient/issues/detail?id=4169
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/1190413004

Makefile.standalone
src/IceCompileServer.cpp

index 5f2686b..76b1d14 100644 (file)
@@ -86,6 +86,15 @@ else
     -DALLOW_MINIMAL_BUILD=0
 endif
 
+ifdef TEXTUAL_BITCODE
+  BASE_CXX_DEFINES += -DINPUT_IS_TEXTUAL_BITCODE=1
+  OBJDIR := $(OBJDIR)+Tbc
+  TEXTBC_LIBS = -LLVMNaClBitTestUtils
+else
+  BASE_CXX_DEFINES += -DINPUT_IS_TEXTUAL_BITCODE=0
+  TEXTBC_LIBS =
+endif
+
 SB_CXX_DEFINES := $(BASE_CXX_DEFINES) -DPNACL_BROWSER_TRANSLATOR=1
 CXX_DEFINES := $(BASE_CXX_DEFINES) -DPNACL_BROWSER_TRANSLATOR=0
 
@@ -130,7 +139,7 @@ LLVM_LIBS_LIST := -lLLVMIRReader -lLLVMBitReader -lLLVMNaClBitTestUtils \
 
 ifeq ($(AUTOCONF), 0)
   # LLVM cmake build
-  LLVM_LIBS := $(LLVM_LIBS_LIST)
+  LLVM_LIBS := $(LLVM_LIBS_LIST) $(TEXTBC_LIBS)
   # For the cmake build, the gtest libs end up in the same place as the LLVM
   # libs, so no "-L..." arg is needed.
   GTEST_LIB_PATH ?=
@@ -225,6 +234,14 @@ else
 sb: $(SB_OBJDIR)/pnacl-sz.x86-32.nexe
 endif
 
+# SHOW_BUILD_ATTS is an executable that is run to show what build
+# attributes were used to build pnacl-sz.
+ifdef TEXTUAL_BITCODE
+  SHOW_BUILD_ATTS = echo "Can't show build attributes when TEXTUAL_BITCODE=1"
+else
+  SHOW_BUILD_ATTS = $(OBJDIR)/pnacl-sz --build-atts
+endif
+
 # Creates symbolic link so that testing is easier. Also runs
 # pnacl-sz to verify that the defines flags have valid values,
 # as well as describe the corresponding build attributes.
@@ -232,7 +249,7 @@ make_symlink: $(OBJDIR)/pnacl-sz
        rm -rf pnacl-sz
        ln -s $(OBJDIR)/pnacl-sz
        @echo "Build Attributes:"
-       @$(OBJDIR)/pnacl-sz --build-atts
+       @$(SHOW_BUILD_ATTS)
 
 .PHONY: all make_symlink runtime bloat sb
 
index d4048e9..cda32da 100644 (file)
 #include <iostream>
 #include <thread>
 
+// Include code to handle converting textual bitcode records to binary (for
+// INPUT_IS_TEXTUAL_BITCODE).
+#include "llvm/Bitcode/NaCl/NaClBitcodeMungeUtils.h"
+
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/raw_os_ostream.h"
 #include "llvm/Support/Signals.h"
@@ -31,6 +35,50 @@ namespace Ice {
 
 namespace {
 
+static_assert(
+!(INPUT_IS_TEXTUAL_BITCODE && PNACL_BROWSER_TRANSLATOR),
+  "Can not define INPUT_IS_TEXTUAL_BITCODE when building browswer translator");
+
+// Define a SmallVector backed buffer as a data stream, so that it
+// can hold the generated binary version of the textual bitcode in the
+// input file.
+class TextDataStreamer : public llvm::DataStreamer {
+public:
+  TextDataStreamer() = default;
+  ~TextDataStreamer() final = default;
+  static TextDataStreamer *create(const IceString &Filename, std::string *Err);
+  size_t GetBytes(unsigned char *Buf, size_t Len) final;
+private:
+  llvm::SmallVector<char, 1024> BitcodeBuffer;
+  size_t Cursor = 0;
+};
+
+TextDataStreamer *TextDataStreamer::create(const IceString &Filename,
+                                           std::string *Err) {
+  TextDataStreamer *Streamer = new TextDataStreamer();
+  llvm::raw_string_ostream ErrStrm(*Err);
+  if (std::error_code EC = llvm::readNaClRecordTextAndBuildBitcode(
+          Filename, Streamer->BitcodeBuffer, &ErrStrm)) {
+    ErrStrm << "Error: " << EC.message() << "\n";
+    ErrStrm.flush();
+    delete Streamer;
+    return nullptr;
+  }
+  ErrStrm.flush();
+  return Streamer;
+}
+
+size_t TextDataStreamer::GetBytes(unsigned char *Buf, size_t Len) {
+  if (Cursor >= BitcodeBuffer.size())
+    return 0;
+  size_t Remaining = BitcodeBuffer.size();
+  Len = std::min(Len, Remaining);
+  for (size_t i = 0; i < Len; ++i)
+    Buf[i] = BitcodeBuffer[Cursor + i];
+  Cursor += Len;
+  return Len;
+}
+
 std::unique_ptr<Ostream> makeStream(const IceString &Filename,
                                     std::error_code &EC) {
   if (Filename == "-") {
@@ -100,7 +148,10 @@ void CLCompileServer::run() {
 
   IceString StrError;
   std::unique_ptr<llvm::DataStreamer> InputStream(
-      llvm::getDataFileStreamer(ExtraFlags.getIRFilename(), &StrError));
+      INPUT_IS_TEXTUAL_BITCODE
+      ? TextDataStreamer::create(ExtraFlags.getIRFilename(), &StrError)
+      : llvm::getDataFileStreamer(ExtraFlags.getIRFilename(), &StrError)
+                                                  );
   if (!StrError.empty() || !InputStream) {
     llvm::SMDiagnostic Err(ExtraFlags.getIRFilename(),
                            llvm::SourceMgr::DK_Error, StrError);