From: Justin Bogner Date: Fri, 1 Sep 2017 17:02:22 +0000 (+0000) Subject: llvm-isel-fuzzer: Make buildable and testable without libFuzzer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8cb6b3ebf8480fe273085b39396b852fa9302041;p=llvm llvm-isel-fuzzer: Make buildable and testable without libFuzzer This adds a dummy main so we can build and run the llvm-isel-fuzzer functionality when we aren't building LLVM with coverage. The approach here should serve as a template to stop in-tree fuzzers from bitrotting (See llvm.org/pr34314). Note that I'll probably move most of the logic in DummyISelFuzzer's `main` to a library so it's easy to reuse it in other fuzz targets, but I'm planning on doing that in a follow up that also consolidates argument handling in our LLVMFuzzerInitialize implementations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312338 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake index 8c884db4706..61417865c77 100644 --- a/cmake/modules/AddLLVM.cmake +++ b/cmake/modules/AddLLVM.cmake @@ -893,11 +893,15 @@ macro(add_llvm_utility name) endmacro(add_llvm_utility name) macro(add_llvm_fuzzer name) + cmake_parse_arguments(ARG "" "DUMMY_MAIN" "" ${ARGN}) if( LLVM_USE_SANITIZE_COVERAGE ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer") - add_llvm_executable(${name} ${ARGN}) + add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS}) set_target_properties(${name} PROPERTIES FOLDER "Fuzzers") - endif() + elseif( ARG_DUMMY_MAIN ) + add_llvm_executable(${name} ${ARG_DUMMY_MAIN} ${ARG_UNPARSED_ARGUMENTS}) + set_target_properties(${name} PROPERTIES FOLDER "Fuzzers") +endif() endmacro() macro(add_llvm_target target_name) diff --git a/tools/llvm-isel-fuzzer/CMakeLists.txt b/tools/llvm-isel-fuzzer/CMakeLists.txt index 474bcf928eb..4bd4420bade 100644 --- a/tools/llvm-isel-fuzzer/CMakeLists.txt +++ b/tools/llvm-isel-fuzzer/CMakeLists.txt @@ -12,4 +12,5 @@ set(LLVM_LINK_COMPONENTS Support Target ) -add_llvm_fuzzer(llvm-isel-fuzzer llvm-isel-fuzzer.cpp) +add_llvm_fuzzer(llvm-isel-fuzzer llvm-isel-fuzzer.cpp + DUMMY_MAIN DummyISelFuzzer.cpp) diff --git a/tools/llvm-isel-fuzzer/DummyISelFuzzer.cpp b/tools/llvm-isel-fuzzer/DummyISelFuzzer.cpp new file mode 100644 index 00000000000..929a63a541d --- /dev/null +++ b/tools/llvm-isel-fuzzer/DummyISelFuzzer.cpp @@ -0,0 +1,56 @@ +//===--- DummyFuzzerMain.cpp - Entry point to sanity check the fuzzer -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implementation of main so we can build and test without linking libFuzzer. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); +extern "C" LLVM_ATTRIBUTE_WEAK int LLVMFuzzerInitialize(int *argc, + char ***argv) { + return 0; +} + +int main(int argc, char *argv[]) { + errs() << "*** This tool was not linked to libFuzzer.\n" + << "*** No fuzzing will be performed.\n"; + if (int RC = LLVMFuzzerInitialize(&argc, &argv)) { + errs() << "Initialization failed\n"; + return RC; + } + + for (int I = 1; I < argc; ++I) { + StringRef Arg(argv[I]); + if (Arg.startswith("-")) { + if (Arg.equals("-ignore_remaining_args=1")) + break; + continue; + } + + auto BufOrErr = MemoryBuffer::getFile(Arg, /*FileSize-*/ -1, + /*RequiresNullTerminator=*/false); + if (std::error_code EC = BufOrErr.getError()) { + errs() << "Error reading file: " << Arg << ": " << EC.message() << "\n"; + return 1; + } + std::unique_ptr Buf = std::move(BufOrErr.get()); + errs() << "Running: " << Arg << " (" << Buf->getBufferSize() << " bytes)\n"; + LLVMFuzzerTestOneInput( + reinterpret_cast(Buf->getBufferStart()), + Buf->getBufferSize()); + } +}