diff options
author | Amir Ayupov <aaupov@fb.com> | 2022-02-21 04:23:40 +0300 |
---|---|---|
committer | Amir Ayupov <aaupov@fb.com> | 2022-02-21 04:24:16 +0300 |
commit | d44f99c748e0f35e9a322c9c9bea18d03168fae5 (patch) | |
tree | 977dd7d38b239e33e024abe328759d4699414a30 /bolt | |
parent | 36ada32727d8c9f075ea8943212d489fdbcf637e (diff) |
[BOLT] Added fuzzer target (llvm-bolt-fuzzer)
This adds a target that would consume random binary as an
input ELF file.
TBD: add structured input support (ELF).
Build:
```
cmake /path/to/llvm-project/llvm -GNinja \
-DLLVM_TARGETS_TO_BUILD="X86;AArch64" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_ASSERTIONS=1 \
-DCMAKE_C_COMPILER=<sanitizer-capable clang> \
-DCMAKE_CXX_COMPILER=<sanitizer-capable clang++> \
-DLLVM_ENABLE_PROJECTS="bolt" \
-DLLVM_USE_SANITIZER=Address \
-DLLVM_USE_SANITIZE_COVERAGE=On
ninja llvm-bolt-fuzzer
```
Test Plan: ninja llvm-bolt-fuzzer
Reviewed By: maksfb
Differential Revision: https://reviews.llvm.org/D120016
Diffstat (limited to 'bolt')
-rw-r--r-- | bolt/lib/Rewrite/RewriteInstance.cpp | 2 | ||||
-rw-r--r-- | bolt/tools/CMakeLists.txt | 1 | ||||
-rw-r--r-- | bolt/tools/llvm-bolt-fuzzer/CMakeLists.txt | 7 | ||||
-rw-r--r-- | bolt/tools/llvm-bolt-fuzzer/llvm-bolt-fuzzer.cpp | 70 |
4 files changed, 79 insertions, 1 deletions
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 2671df8ebc31..51607eab8c8a 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -138,7 +138,7 @@ KeepTmp("keep-tmp", cl::Hidden, cl::cat(BoltCategory)); -static cl::opt<bool> +cl::opt<bool> Lite("lite", cl::desc("skip processing of cold functions"), cl::init(false), diff --git a/bolt/tools/CMakeLists.txt b/bolt/tools/CMakeLists.txt index bd5a1d17af4c..1fe85145d79a 100644 --- a/bolt/tools/CMakeLists.txt +++ b/bolt/tools/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(driver) +add_subdirectory(llvm-bolt-fuzzer) add_subdirectory(merge-fdata) add_subdirectory(heatmap) diff --git a/bolt/tools/llvm-bolt-fuzzer/CMakeLists.txt b/bolt/tools/llvm-bolt-fuzzer/CMakeLists.txt new file mode 100644 index 000000000000..3c26b78c855c --- /dev/null +++ b/bolt/tools/llvm-bolt-fuzzer/CMakeLists.txt @@ -0,0 +1,7 @@ +set(LLVM_LINK_COMPONENTS + BOLTRewrite + ) + +add_llvm_fuzzer(llvm-bolt-fuzzer + llvm-bolt-fuzzer.cpp + ) diff --git a/bolt/tools/llvm-bolt-fuzzer/llvm-bolt-fuzzer.cpp b/bolt/tools/llvm-bolt-fuzzer/llvm-bolt-fuzzer.cpp new file mode 100644 index 000000000000..ac129a0d9a62 --- /dev/null +++ b/bolt/tools/llvm-bolt-fuzzer/llvm-bolt-fuzzer.cpp @@ -0,0 +1,70 @@ +//===- llvm-bolt-fuzzer.cpp - Fuzzing target for llvm-bolt ----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "bolt/Rewrite/RewriteInstance.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/TargetSelect.h" + +using namespace llvm; +using namespace object; +using namespace bolt; + +namespace opts { +extern cl::opt<std::string> OutputFilename; +extern cl::opt<bool> Lite; +} // namespace opts + +extern "C" int LLVMFuzzerTestOneInput(const char *Data, size_t Size) { + const char *argv[] = {"llvm-bolt", nullptr}; + const char argc = 1; + opts::OutputFilename = "/dev/null"; + opts::Lite = false; + + // Input has to be an ELF - we don't want to fuzz createBinary interface. + if (Size < 4 || strncmp("\177ELF", Data, 4) != 0) + return 0; + // Construct an ELF binary from fuzzer input. + std::unique_ptr<MemoryBuffer> Buffer = + MemoryBuffer::getMemBuffer(StringRef(Data, Size), "", false); + Expected<std::unique_ptr<Binary>> BinaryOrErr = + createBinary(Buffer->getMemBufferRef()); + // Check that the input is a valid binary. + if (Error E = BinaryOrErr.takeError()) { + consumeError(std::move(E)); + return 0; + } + Binary &Binary = *BinaryOrErr.get(); + // Check that the binary is an ELF64LE object file. + auto *E = dyn_cast<ELF64LEObjectFile>(&Binary); + if (!E) + return 0; + + // Fuzz RewriteInstance. + auto RIOrErr = + RewriteInstance::createRewriteInstance(E, argc, argv, "llvm-bolt"); + if (Error E = RIOrErr.takeError()) { + consumeError(std::move(E)); + return 0; + } + RewriteInstance &RI = *RIOrErr.get(); + RI.run(); + return 0; +} + +extern "C" LLVM_ATTRIBUTE_USED int LLVMFuzzerInitialize(int *argc, + char ***argv) { + llvm::InitializeAllTargetInfos(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllAsmParsers(); + llvm::InitializeAllDisassemblers(); + + llvm::InitializeAllTargets(); + llvm::InitializeAllAsmPrinters(); + + return 0; +} |