r310408 - Integrate Kostya's clang-proto-fuzzer with LLVM.

Nico Weber via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 10 10:56:05 PDT 2017


I really believe this has way too many deps to live in the clang repro, as
said on the review already. Maybe this could live in clang-extra instead?

On Aug 8, 2017 4:15 PM, "Matt Morehouse via cfe-commits" <
cfe-commits at lists.llvm.org> wrote:

> Author: morehouse
> Date: Tue Aug  8 13:15:04 2017
> New Revision: 310408
>
> URL: http://llvm.org/viewvc/llvm-project?rev=310408&view=rev
> Log:
> Integrate Kostya's clang-proto-fuzzer with LLVM.
>
> Summary:
> The clang-proto-fuzzer models a subset of C++ as a protobuf and
> uses libprotobuf-mutator to generate interesting mutations of C++
> programs.  Clang-proto-fuzzer has already found several bugs in
> Clang (e.g., https://bugs.llvm.org/show_bug.cgi?id=33747,
> https://bugs.llvm.org/show_bug.cgi?id=33749).
>
> As with clang-fuzzer, clang-proto-fuzzer requires the following
> cmake flags:
> - CMAKE_C_COMPILER=clang
> - CMAKE_CXX_COMPILER=clang++
> - LLVM_USE_SANITIZE_COVERAGE=YES  // needed for libFuzzer
> - LLVM_USE_SANITIZER=Address  // needed for libFuzzer
>
> In addition, clang-proto-fuzzer requires:
> - CLANG_ENABLE_PROTO_FUZZER=ON
>
> clang-proto-fuzzer also requires the following dependencies:
> - binutils  // needed for libprotobuf-mutator
> - liblzma-dev  // needed for libprotobuf-mutator
> - libz-dev  // needed for libprotobuf-mutator
> - docbook2x  // needed for libprotobuf-mutator
> - Recent version of protobuf [3.3.0 is known to work]
>
> A working version of libprotobuf-mutator will automatically be
> downloaded and built as an external project.
>
> Implementation of clang-proto-fuzzer provided by Kostya
> Serebryany.
>
> https://bugs.llvm.org/show_bug.cgi?id=33829
>
> Reviewers: kcc, vitalybuka, bogner
>
> Reviewed By: kcc, vitalybuka
>
> Subscribers: thakis, mgorny, cfe-commits
>
> Differential Revision: https://reviews.llvm.org/D36324
>
> Added:
>     cfe/trunk/cmake/modules/ProtobufMutator.cmake
>     cfe/trunk/tools/clang-fuzzer/ExampleClangProtoFuzzer.cpp
>     cfe/trunk/tools/clang-fuzzer/README.txt
>     cfe/trunk/tools/clang-fuzzer/cxx_proto.proto
>     cfe/trunk/tools/clang-fuzzer/handle-cxx/
>     cfe/trunk/tools/clang-fuzzer/handle-cxx/CMakeLists.txt
>     cfe/trunk/tools/clang-fuzzer/handle-cxx/handle_cxx.cpp
>     cfe/trunk/tools/clang-fuzzer/handle-cxx/handle_cxx.h
>     cfe/trunk/tools/clang-fuzzer/proto-to-cxx/
>     cfe/trunk/tools/clang-fuzzer/proto-to-cxx/CMakeLists.txt
>     cfe/trunk/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.cpp
>     cfe/trunk/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.h
>     cfe/trunk/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx_main.cpp
> Modified:
>     cfe/trunk/CMakeLists.txt
>     cfe/trunk/tools/clang-fuzzer/CMakeLists.txt
>     cfe/trunk/tools/clang-fuzzer/ClangFuzzer.cpp
>
> Modified: cfe/trunk/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CMakeLists.
> txt?rev=310408&r1=310407&r2=310408&view=diff
> ============================================================
> ==================
> --- cfe/trunk/CMakeLists.txt (original)
> +++ cfe/trunk/CMakeLists.txt Tue Aug  8 13:15:04 2017
> @@ -377,6 +377,8 @@ option(CLANG_ENABLE_STATIC_ANALYZER "Bui
>  option(CLANG_ANALYZER_BUILD_Z3
>    "Build the static analyzer with the Z3 constraint manager." OFF)
>
> +option(CLANG_ENABLE_PROTO_FUZZER "Build Clang protobuf fuzzer." OFF)
> +
>  if(NOT CLANG_ENABLE_STATIC_ANALYZER AND (CLANG_ENABLE_ARCMT OR
> CLANG_ANALYZER_BUILD_Z3))
>    message(FATAL_ERROR "Cannot disable static analyzer while enabling
> ARCMT or Z3")
>  endif()
>
> Added: cfe/trunk/cmake/modules/ProtobufMutator.cmake
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/cmake/
> modules/ProtobufMutator.cmake?rev=310408&view=auto
> ============================================================
> ==================
> --- cfe/trunk/cmake/modules/ProtobufMutator.cmake (added)
> +++ cfe/trunk/cmake/modules/ProtobufMutator.cmake Tue Aug  8 13:15:04 2017
> @@ -0,0 +1,24 @@
> +set(PBM_PREFIX protobuf_mutator)
> +set(PBM_PATH ${CMAKE_CURRENT_BINARY_DIR}/${PBM_PREFIX}/src/${PBM_PREFIX})
> +set(PBM_LIB_PATH ${PBM_PATH}/src/libprotobuf-mutator.a)
> +set(PBM_FUZZ_LIB_PATH ${PBM_PATH}/src/libfuzzer/
> libprotobuf-mutator-libfuzzer.a)
> +
> +ExternalProject_Add(${PBM_PREFIX}
> +  PREFIX ${PBM_PREFIX}
> +  GIT_REPOSITORY https://github.com/google/libprotobuf-mutator.git
> +  GIT_TAG 34287f8
> +  CONFIGURE_COMMAND ${CMAKE_COMMAND} -G${CMAKE_GENERATOR}
> +    -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
> +    -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
> +    -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
> +  BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
> +  BUILD_BYPRODUCTS ${PBM_LIB_PATH} ${PBM_FUZZ_LIB_PATH}
> +  BUILD_IN_SOURCE 1
> +  INSTALL_COMMAND ""
> +  LOG_DOWNLOAD 1
> +  LOG_CONFIGURE 1
> +  LOG_BUILD 1
> +  )
> +
> +set(ProtobufMutator_INCLUDE_DIRS ${PBM_PATH})
> +set(ProtobufMutator_LIBRARIES ${PBM_FUZZ_LIB_PATH} ${PBM_LIB_PATH})
>
> Modified: cfe/trunk/tools/clang-fuzzer/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-
> fuzzer/CMakeLists.txt?rev=310408&r1=310407&r2=310408&view=diff
> ============================================================
> ==================
> --- cfe/trunk/tools/clang-fuzzer/CMakeLists.txt (original)
> +++ cfe/trunk/tools/clang-fuzzer/CMakeLists.txt Tue Aug  8 13:15:04 2017
> @@ -1,21 +1,60 @@
>  if( LLVM_USE_SANITIZE_COVERAGE )
>    set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD})
>
> +  if(CLANG_ENABLE_PROTO_FUZZER)
> +    # Create protobuf .h and .cc files, and put them in a library for use
> by
> +    # clang-proto-fuzzer components.
> +    find_package(Protobuf REQUIRED)
> +    add_definitions(-DGOOGLE_PROTOBUF_NO_RTTI)
> +    include_directories(${PROTOBUF_INCLUDE_DIRS})
> +    include_directories(${CMAKE_CURRENT_BINARY_DIR})
> +    protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS cxx_proto.proto)
> +    # Hack to bypass LLVM's cmake sources check and allow multiple
> libraries and
> +    # executables from this directory.
> +    set(LLVM_OPTIONAL_SOURCES
> +      ClangFuzzer.cpp
> +      ExampleClangProtoFuzzer.cpp
> +      ${PROTO_SRCS}
> +      )
> +    add_clang_library(clangCXXProto
> +      ${PROTO_SRCS}
> +      ${PROTO_HDRS}
> +
> +      LINK_LIBS
> +      ${PROTOBUF_LIBRARIES}
> +      )
> +
> +    # Build and include libprotobuf-mutator
> +    include(ProtobufMutator)
> +    include_directories(${ProtobufMutator_INCLUDE_DIRS})
> +
> +    # Build the protobuf->C++ translation library and driver.
> +    add_clang_subdirectory(proto-to-cxx)
> +
> +    # Build the protobuf fuzzer
> +    add_clang_executable(clang-proto-fuzzer ExampleClangProtoFuzzer.cpp)
> +    target_link_libraries(clang-proto-fuzzer
> +      ${ProtobufMutator_LIBRARIES}
> +      clangCXXProto
> +      clangHandleCXX
> +      clangProtoToCXX
> +      LLVMFuzzer
> +      )
> +  else()
> +    # Hack to bypass LLVM's cmake sources check and allow multiple
> libraries and
> +    # executables from this directory.
> +    set(LLVM_OPTIONAL_SOURCES ClangFuzzer.cpp ExampleClangProtoFuzzer.cpp)
> +  endif()
> +
> +  add_clang_subdirectory(handle-cxx)
> +
>    add_clang_executable(clang-fuzzer
>      EXCLUDE_FROM_ALL
>      ClangFuzzer.cpp
>      )
>
>    target_link_libraries(clang-fuzzer
> -    ${CLANG_FORMAT_LIB_DEPS}
> -    clangAST
> -    clangBasic
> -    clangCodeGen
> -    clangDriver
> -    clangFrontend
> -    clangRewriteFrontend
> -    clangStaticAnalyzerFrontend
> -    clangTooling
> +    clangHandleCXX
>      LLVMFuzzer
>      )
>  endif()
>
> Modified: cfe/trunk/tools/clang-fuzzer/ClangFuzzer.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-
> fuzzer/ClangFuzzer.cpp?rev=310408&r1=310407&r2=310408&view=diff
> ============================================================
> ==================
> --- cfe/trunk/tools/clang-fuzzer/ClangFuzzer.cpp (original)
> +++ cfe/trunk/tools/clang-fuzzer/ClangFuzzer.cpp Tue Aug  8 13:15:04 2017
> @@ -13,43 +13,12 @@
>  ///
>  //===-------------------------------------------------------
> ---------------===//
>
> -#include "clang/Tooling/Tooling.h"
> -#include "clang/CodeGen/CodeGenAction.h"
> -#include "clang/Frontend/CompilerInstance.h"
> -#include "clang/Lex/PreprocessorOptions.h"
> -#include "llvm/Option/Option.h"
> -#include "llvm/Support/TargetSelect.h"
> +#include "handle-cxx/handle_cxx.h"
>
> -using namespace clang;
> +using namespace clang_fuzzer;
>
>  extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
>    std::string s((const char *)data, size);
> -  llvm::InitializeAllTargets();
> -  llvm::InitializeAllTargetMCs();
> -  llvm::InitializeAllAsmPrinters();
> -  llvm::InitializeAllAsmParsers();
> -
> -  llvm::opt::ArgStringList CC1Args;
> -  CC1Args.push_back("-cc1");
> -  CC1Args.push_back("./test.cc");
> -  CC1Args.push_back("-O2");
> -  llvm::IntrusiveRefCntPtr<FileManager> Files(
> -      new FileManager(FileSystemOptions()));
> -  IgnoringDiagConsumer Diags;
> -  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new
> DiagnosticOptions();
> -  DiagnosticsEngine Diagnostics(
> -      IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()),
> &*DiagOpts,
> -      &Diags, false);
> -  std::unique_ptr<clang::CompilerInvocation> Invocation(
> -      tooling::newInvocation(&Diagnostics, CC1Args));
> -  std::unique_ptr<llvm::MemoryBuffer> Input =
> -      llvm::MemoryBuffer::getMemBuffer(s);
> -  Invocation->getPreprocessorOpts().addRemappedFile("./test.cc",
> Input.release());
> -  std::unique_ptr<tooling::ToolAction> action(
> -      tooling::newFrontendActionFactory<clang::EmitObjAction>());
> -  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
> -      std::make_shared<PCHContainerOperations>();
> -  action->runInvocation(std::move(Invocation), Files.get(),
> PCHContainerOps,
> -                        &Diags);
> +  HandleCXX(s, {"-O2"});
>    return 0;
>  }
>
> Added: cfe/trunk/tools/clang-fuzzer/ExampleClangProtoFuzzer.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-fuzzer/
> ExampleClangProtoFuzzer.cpp?rev=310408&view=auto
> ============================================================
> ==================
> --- cfe/trunk/tools/clang-fuzzer/ExampleClangProtoFuzzer.cpp (added)
> +++ cfe/trunk/tools/clang-fuzzer/ExampleClangProtoFuzzer.cpp Tue Aug  8
> 13:15:04 2017
> @@ -0,0 +1,28 @@
> +//===-- ExampleClangProtoFuzzer.cpp - Fuzz Clang
> --------------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +///
> +/// \file
> +/// \brief This file implements a function that runs Clang on a single
> +///  input and uses libprotobuf-mutator to find new inputs. This function
> is
> +///  then linked into the Fuzzer library.
> +///
> +//===------------------------------------------------------
> ----------------===//
> +
> +#include "cxx_proto.pb.h"
> +#include "handle-cxx/handle_cxx.h"
> +#include "proto-to-cxx/proto_to_cxx.h"
> +
> +#include "src/libfuzzer/libfuzzer_macro.h"
> +
> +using namespace clang_fuzzer;
> +
> +DEFINE_BINARY_PROTO_FUZZER(const Function& input) {
> +  auto S = FunctionToString(input);
> +  HandleCXX(S, {"-O2"});
> +}
>
> Added: cfe/trunk/tools/clang-fuzzer/README.txt
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-
> fuzzer/README.txt?rev=310408&view=auto
> ============================================================
> ==================
> --- cfe/trunk/tools/clang-fuzzer/README.txt (added)
> +++ cfe/trunk/tools/clang-fuzzer/README.txt Tue Aug  8 13:15:04 2017
> @@ -0,0 +1,73 @@
> +This directory contains two utilities for fuzzing Clang: clang-fuzzer and
> +clang-proto-fuzzer.  Both use libFuzzer to generate inputs to clang via
> +coverage-guided mutation.
> +
> +The two utilities differ, however, in how they structure inputs to Clang.
> +clang-fuzzer makes no attempt to generate valid C++ programs and is
> therefore
> +primarily useful for stressing the surface layers of Clang (i.e. lexer,
> parser).
> +clang-proto-fuzzer uses a protobuf class to describe a subset of the C++
> +language and then uses libprotobuf-mutator to mutate instantiations of
> that
> +class, producing valid C++ programs in the process.  As a result,
> +clang-proto-fuzzer is better at stressing deeper layers of Clang and LLVM.
> +
> +===================================
> + Building clang-fuzzer
> +===================================
> +Within your LLVM build directory, run CMake with the following variable
> +definitions:
> +- CMAKE_C_COMPILER=clang
> +- CMAKE_CXX_COMPILER=clang++
> +- LLVM_USE_SANITIZE_COVERAGE=YES
> +- LLVM_USE_SANITIZER=Address
> +
> +Then build the clang-fuzzer target.
> +
> +Example:
> +  cd $LLVM_SOURCE_DIR
> +  mkdir build && cd build
> +  cmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
> +    -DLLVM_USE_SANITIZE_COVERAGE=YES -DLLVM_USE_SANITIZER=Address
> +  ninja clang-fuzzer
> +
> +
> +=======================================================
> + Building clang-proto-fuzzer (Linux-only instructions)
> +=======================================================
> +Install the necessary dependencies:
> +- binutils  // needed for libprotobuf-mutator
> +- liblzma-dev  // needed for libprotobuf-mutator
> +- libz-dev  // needed for libprotobuf-mutator
> +- docbook2x  // needed for libprotobuf-mutator
> +- Recent version of protobuf [3.3.0 is known to work]
> +
> +Within your LLVM build directory, run CMake with the following variable
> +definitions:
> +- CMAKE_C_COMPILER=clang
> +- CMAKE_CXX_COMPILER=clang++
> +- LLVM_USE_SANITIZE_COVERAGE=YES
> +- LLVM_USE_SANITIZER=Address
> +- CLANG_ENABLE_PROTO_FUZZER=ON
> +
> +Then build the clang-proto-fuzzer and clang-proto-to-cxx targets.
> Optionally,
> +you may also build clang-fuzzer with this setup.
> +
> +Example:
> +  cd $LLVM_SOURCE_DIR
> +  mkdir build && cd build
> +  cmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
> +    -DLLVM_USE_SANITIZE_COVERAGE=YES -DLLVM_USE_SANITIZER=Address \
> +    -DCLANG_ENABLE_PROTO_FUZZER=ON
> +  ninja clang-proto-fuzzer clang-proto-to-cxx
> +
> +
> +=====================
> + Running the fuzzers
> +=====================
> +clang-fuzzer:
> +  bin/clang-fuzzer CORPUS_DIR
> +
> +clang-proto-fuzzer:
> +  bin/clang-proto-fuzzer CORPUS_DIR
> +
> +Translating a clang-proto-fuzzer corpus output to C++:
> +  bin/clang-proto-to-cxx CORPUS_OUTPUT_FILE
>
> Added: cfe/trunk/tools/clang-fuzzer/cxx_proto.proto
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-
> fuzzer/cxx_proto.proto?rev=310408&view=auto
> ============================================================
> ==================
> --- cfe/trunk/tools/clang-fuzzer/cxx_proto.proto (added)
> +++ cfe/trunk/tools/clang-fuzzer/cxx_proto.proto Tue Aug  8 13:15:04 2017
> @@ -0,0 +1,93 @@
> +//===-- cxx_proto.proto - Protobuf description of C++
> ---------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +///
> +/// \file
> +/// \brief This file describes a subset of C++ as a protobuf.  It is used
> to
> +///  more easily find interesting inputs for fuzzing Clang.
> +///
> +//===------------------------------------------------------
> ----------------===//
> +
> +syntax = "proto2";
> +
> +message VarRef {
> +  required int32 varnum = 1;
> +}
> +
> +message Lvalue {
> +  required VarRef varref = 1;
> +}
> +
> +message Const {
> +  required int32 val = 1;
> +}
> +
> +message BinaryOp {
> +  enum Op {
> +    PLUS = 0;
> +    MINUS = 1;
> +    MUL = 2;
> +    DIV = 3;
> +    MOD = 4;
> +    XOR = 5;
> +    AND = 6;
> +    OR = 7;
> +    EQ = 8;
> +    NE = 9;
> +    LE = 10;
> +    GE = 11;
> +    LT = 12;
> +    GT = 13;
> +  };
> +  required Op op = 1;
> +  required Rvalue left = 2;
> +  required Rvalue right = 3;
> +}
> +
> +message Rvalue {
> +  oneof rvalue_oneof {
> +    VarRef varref = 1;
> +    Const cons = 2;
> +    BinaryOp binop = 3;
> +  }
> +}
> +
> +message AssignmentStatement {
> +  required Lvalue lvalue = 1;
> +  required Rvalue rvalue = 2;
> +}
> +
> +
> +message IfElse {
> +  required Rvalue cond = 1;
> +  required StatementSeq if_body = 2;
> +  required StatementSeq else_body = 3;
> +}
> +
> +message While {
> +  required Rvalue cond = 1;
> +  required StatementSeq body = 2;
> +}
> +
> +message Statement {
> +  oneof stmt_oneof {
> +    AssignmentStatement assignment = 1;
> +    IfElse              ifelse     = 2;
> +    While               while_loop = 3;
> +  }
> +}
> +
> +message StatementSeq {
> +  repeated Statement statements = 1;
> +}
> +
> +message Function {
> +  required StatementSeq statements = 1;
> +}
> +
> +package clang_fuzzer;
>
> Added: cfe/trunk/tools/clang-fuzzer/handle-cxx/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-
> fuzzer/handle-cxx/CMakeLists.txt?rev=310408&view=auto
> ============================================================
> ==================
> --- cfe/trunk/tools/clang-fuzzer/handle-cxx/CMakeLists.txt (added)
> +++ cfe/trunk/tools/clang-fuzzer/handle-cxx/CMakeLists.txt Tue Aug  8
> 13:15:04 2017
> @@ -0,0 +1,11 @@
> +set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD})
> +
> +add_clang_library(clangHandleCXX
> +  handle_cxx.cpp
> +
> +  LINK_LIBS
> +  clangCodeGen
> +  clangFrontend
> +  clangLex
> +  clangTooling
> +  )
>
> Added: cfe/trunk/tools/clang-fuzzer/handle-cxx/handle_cxx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-
> fuzzer/handle-cxx/handle_cxx.cpp?rev=310408&view=auto
> ============================================================
> ==================
> --- cfe/trunk/tools/clang-fuzzer/handle-cxx/handle_cxx.cpp (added)
> +++ cfe/trunk/tools/clang-fuzzer/handle-cxx/handle_cxx.cpp Tue Aug  8
> 13:15:04 2017
> @@ -0,0 +1,58 @@
> +//==-- handle_cxx.cpp - Helper function for Clang fuzzers
> ------------------==//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +//
> +// Implements HandleCXX for use by the Clang fuzzers.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +#include "handle_cxx.h"
> +
> +#include "clang/CodeGen/CodeGenAction.h"
> +#include "clang/Frontend/CompilerInstance.h"
> +#include "clang/Lex/PreprocessorOptions.h"
> +#include "clang/Tooling/Tooling.h"
> +#include "llvm/Option/Option.h"
> +#include "llvm/Support/TargetSelect.h"
> +
> +using namespace clang;
> +
> +void clang_fuzzer::HandleCXX(const std::string &S,
> +                             const std::vector<const char *> &ExtraArgs) {
> +  llvm::InitializeAllTargets();
> +  llvm::InitializeAllTargetMCs();
> +  llvm::InitializeAllAsmPrinters();
> +  llvm::InitializeAllAsmParsers();
> +
> +  llvm::opt::ArgStringList CC1Args;
> +  CC1Args.push_back("-cc1");
> +  for (auto &A : ExtraArgs)
> +    CC1Args.push_back(A);
> +  CC1Args.push_back("./test.cc");
> +
> +  llvm::IntrusiveRefCntPtr<FileManager> Files(
> +      new FileManager(FileSystemOptions()));
> +  IgnoringDiagConsumer Diags;
> +  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new
> DiagnosticOptions();
> +  DiagnosticsEngine Diagnostics(
> +      IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()),
> &*DiagOpts,
> +      &Diags, false);
> +  std::unique_ptr<clang::CompilerInvocation> Invocation(
> +      tooling::newInvocation(&Diagnostics, CC1Args));
> +  std::unique_ptr<llvm::MemoryBuffer> Input =
> +      llvm::MemoryBuffer::getMemBuffer(S);
> +  Invocation->getPreprocessorOpts().addRemappedFile("./test.cc",
> +                                                    Input.release());
> +  std::unique_ptr<tooling::ToolAction> action(
> +      tooling::newFrontendActionFactory<clang::EmitObjAction>());
> +  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
> +      std::make_shared<PCHContainerOperations>();
> +  action->runInvocation(std::move(Invocation), Files.get(),
> PCHContainerOps,
> +                        &Diags);
> +}
> +
>
> Added: cfe/trunk/tools/clang-fuzzer/handle-cxx/handle_cxx.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-
> fuzzer/handle-cxx/handle_cxx.h?rev=310408&view=auto
> ============================================================
> ==================
> --- cfe/trunk/tools/clang-fuzzer/handle-cxx/handle_cxx.h (added)
> +++ cfe/trunk/tools/clang-fuzzer/handle-cxx/handle_cxx.h Tue Aug  8
> 13:15:04 2017
> @@ -0,0 +1,25 @@
> +//==-- handle_cxx.h - Helper function for Clang fuzzers
> --------------------==//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +//
> +// Defines HandleCXX for use by the Clang fuzzers.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +#ifndef LLVM_CLANG_TOOLS_CLANG_FUZZER_HANDLE_CXX_HANDLECXX_H
> +#define LLVM_CLANG_TOOLS_CLANG_FUZZER_HANDLE_CXX_HANDLECXX_H
> +
> +#include <string>
> +#include <vector>
> +
> +namespace clang_fuzzer {
> +void HandleCXX(const std::string &S,
> +               const std::vector<const char *> &ExtraArgs);
> +} // namespace clang_fuzzer
> +
> +#endif
>
> Added: cfe/trunk/tools/clang-fuzzer/proto-to-cxx/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-
> fuzzer/proto-to-cxx/CMakeLists.txt?rev=310408&view=auto
> ============================================================
> ==================
> --- cfe/trunk/tools/clang-fuzzer/proto-to-cxx/CMakeLists.txt (added)
> +++ cfe/trunk/tools/clang-fuzzer/proto-to-cxx/CMakeLists.txt Tue Aug  8
> 13:15:04 2017
> @@ -0,0 +1,10 @@
> +set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD})
> +
> +# Hack to bypass LLVM's CMake source checks so we can have both a library
> and
> +# an executable built from this directory.
> +set(LLVM_OPTIONAL_SOURCES proto_to_cxx.cpp proto_to_cxx_main.cpp)
> +
> +add_clang_library(clangProtoToCXX proto_to_cxx.cpp LINK_LIBS
> clangCXXProto)
> +
> +add_clang_executable(clang-proto-to-cxx proto_to_cxx_main.cpp)
> +target_link_libraries(clang-proto-to-cxx clangProtoToCXX)
>
> Added: cfe/trunk/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-
> fuzzer/proto-to-cxx/proto_to_cxx.cpp?rev=310408&view=auto
> ============================================================
> ==================
> --- cfe/trunk/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.cpp (added)
> +++ cfe/trunk/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.cpp Tue Aug  8
> 13:15:04 2017
> @@ -0,0 +1,102 @@
> +//==-- proto_to_cxx.cpp - Protobuf-C++ conversion
> --------------------------==//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +//
> +// Implements functions for converting between protobufs and C++.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +#include "proto_to_cxx.h"
> +#include "cxx_proto.pb.h"
> +
> +#include <ostream>
> +#include <sstream>
> +
> +namespace clang_fuzzer {
> +
> +// Forward decls.
> +std::ostream &operator<<(std::ostream &os, const BinaryOp &x);
> +std::ostream &operator<<(std::ostream &os, const StatementSeq &x);
> +
> +// Proto to C++.
> +std::ostream &operator<<(std::ostream &os, const Const &x) {
> +  return os << "(" << x.val() << ")";
> +}
> +std::ostream &operator<<(std::ostream &os, const VarRef &x) {
> +  return os << "a[" << (static_cast<uint32_t>(x.varnum()) % 100) << "]";
> +}
> +std::ostream &operator<<(std::ostream &os, const Lvalue &x) {
> +  return os << x.varref();
> +}
> +std::ostream &operator<<(std::ostream &os, const Rvalue &x) {
> +    if (x.has_varref()) return os << x.varref();
> +    if (x.has_cons())   return os << x.cons();
> +    if (x.has_binop())  return os << x.binop();
> +    return os << "1";
> +}
> +std::ostream &operator<<(std::ostream &os, const BinaryOp &x) {
> +  os << "(" << x.left();
> +  switch (x.op()) {
> +    case BinaryOp::PLUS: os << "+"; break;
> +    case BinaryOp::MINUS: os << "-"; break;
> +    case BinaryOp::MUL: os << "*"; break;
> +    case BinaryOp::DIV: os << "/"; break;
> +    case BinaryOp::MOD: os << "%"; break;
> +    case BinaryOp::XOR: os << "^"; break;
> +    case BinaryOp::AND: os << "&"; break;
> +    case BinaryOp::OR: os << "|"; break;
> +    case BinaryOp::EQ: os << "=="; break;
> +    case BinaryOp::NE: os << "!="; break;
> +    case BinaryOp::LE: os << "<="; break;
> +    case BinaryOp::GE: os << ">="; break;
> +    case BinaryOp::LT: os << "<"; break;
> +    case BinaryOp::GT: os << ">"; break;
> +  }
> +  return os << x.right() << ")";
> +}
> +std::ostream &operator<<(std::ostream &os, const AssignmentStatement &x) {
> +  return os << x.lvalue() << "=" << x.rvalue() << ";\n";
> +}
> +std::ostream &operator<<(std::ostream &os, const IfElse &x) {
> +  return os << "if (" << x.cond() << "){\n"
> +            << x.if_body() << "} else { \n"
> +            << x.else_body() << "}\n";
> +}
> +std::ostream &operator<<(std::ostream &os, const While &x) {
> +  return os << "while (" << x.cond() << "){\n" << x.body() << "}\n";
> +}
> +std::ostream &operator<<(std::ostream &os, const Statement &x) {
> +  if (x.has_assignment()) return os << x.assignment();
> +  if (x.has_ifelse())     return os << x.ifelse();
> +  if (x.has_while_loop()) return os << x.while_loop();
> +  return os << "(void)0;\n";
> +}
> +std::ostream &operator<<(std::ostream &os, const StatementSeq &x) {
> +  for (auto &st : x.statements()) os << st;
> +  return os;
> +}
> +std::ostream &operator<<(std::ostream &os, const Function &x) {
> +  return os << "void foo(int *a) {\n" << x.statements() << "}\n";
> +}
> +
> +// ---------------------------------
> +
> +std::string FunctionToString(const Function &input) {
> +  std::ostringstream os;
> +  os << input;
> +  return os.str();
> +
> +}
> +std::string ProtoToCxx(const uint8_t *data, size_t size) {
> +  Function message;
> +  if (!message.ParseFromArray(data, size))
> +    return "#error invalid proto\n";
> +  return FunctionToString(message);
> +}
> +
> +} // namespace clang_fuzzer
>
> Added: cfe/trunk/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-
> fuzzer/proto-to-cxx/proto_to_cxx.h?rev=310408&view=auto
> ============================================================
> ==================
> --- cfe/trunk/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.h (added)
> +++ cfe/trunk/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.h Tue Aug  8
> 13:15:04 2017
> @@ -0,0 +1,22 @@
> +//==-- proto_to_cxx.h - Protobuf-C++ conversion
> ----------------------------==//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +//
> +// Defines functions for converting between protobufs and C++.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +#include <cstdint>
> +#include <cstddef>
> +#include <string>
> +
> +namespace clang_fuzzer {
> +class Function;
> +std::string FunctionToString(const Function &input);
> +std::string ProtoToCxx(const uint8_t *data, size_t size);
> +}
>
> Added: cfe/trunk/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx_main.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-
> fuzzer/proto-to-cxx/proto_to_cxx_main.cpp?rev=310408&view=auto
> ============================================================
> ==================
> --- cfe/trunk/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx_main.cpp
> (added)
> +++ cfe/trunk/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx_main.cpp Tue
> Aug  8 13:15:04 2017
> @@ -0,0 +1,30 @@
> +//==-- proto_to_cxx_main.cpp - Driver for protobuf-C++ conversion
> ----------==//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +//
> +// Implements a simple driver to print a C++ program from a protobuf.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +#include <fstream>
> +#include <iostream>
> +#include <streambuf>
> +#include <string>
> +
> +#include "proto_to_cxx.h"
> +
> +int main(int argc, char **argv) {
> +  for (int i = 1; i < argc; i++) {
> +    std::fstream in(argv[i]);
> +    std::string str((std::istreambuf_iterator<char>(in)),
> +                    std::istreambuf_iterator<char>());
> +    std::cout << "// " << argv[i] << std::endl;
> +    std::cout << clang_fuzzer::ProtoToCxx(
> +        reinterpret_cast<const uint8_t *>(str.data()), str.size());
> +  }
> +}
> +
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170810/520db43b/attachment-0001.html>


More information about the cfe-commits mailing list