diff options
author | Amir Ayupov <aaupov@fb.com> | 2022-02-20 17:23:40 -0800 |
---|---|---|
committer | Amir Ayupov <aaupov@fb.com> | 2022-02-20 17:24:16 -0800 |
commit | d44f99c748e0f35e9a322c9c9bea18d03168fae5 (patch) | |
tree | 977dd7d38b239e33e024abe328759d4699414a30 /bolt/tools | |
parent | 36ada32727d8c9f075ea8943212d489fdbcf637e (diff) | |
download | llvm-d44f99c748e0f35e9a322c9c9bea18d03168fae5.tar.gz |
[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/tools')
-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 |
3 files changed, 78 insertions, 0 deletions
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; +} |