| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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); | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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()); | ||
| } | ||
| } | ||
|
|