1 | //===- llvm-bolt-fuzzer.cpp - Fuzzing target for llvm-bolt ----------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "bolt/Rewrite/RewriteInstance.h" |
10 | #include "llvm/Support/CommandLine.h" |
11 | #include "llvm/Support/TargetSelect.h" |
12 | |
13 | using namespace llvm; |
14 | using namespace object; |
15 | using namespace bolt; |
16 | |
17 | namespace opts { |
18 | extern cl::opt<std::string> OutputFilename; |
19 | extern cl::opt<bool> Lite; |
20 | } // namespace opts |
21 | |
22 | extern "C" int LLVMFuzzerTestOneInput(const char *Data, size_t Size) { |
23 | const char *argv[] = {"llvm-bolt" , nullptr}; |
24 | const char argc = 1; |
25 | opts::OutputFilename = "/dev/null" ; |
26 | opts::Lite = false; |
27 | |
28 | // Input has to be an ELF - we don't want to fuzz createBinary interface. |
29 | if (Size < 4 || strncmp(s1: "\177ELF" , s2: Data, n: 4) != 0) |
30 | return 0; |
31 | // Construct an ELF binary from fuzzer input. |
32 | std::unique_ptr<MemoryBuffer> Buffer = |
33 | MemoryBuffer::getMemBuffer(InputData: StringRef(Data, Size), BufferName: "" , RequiresNullTerminator: false); |
34 | Expected<std::unique_ptr<Binary>> BinaryOrErr = |
35 | createBinary(Source: Buffer->getMemBufferRef()); |
36 | // Check that the input is a valid binary. |
37 | if (Error E = BinaryOrErr.takeError()) { |
38 | consumeError(Err: std::move(E)); |
39 | return 0; |
40 | } |
41 | Binary &Binary = *BinaryOrErr.get(); |
42 | // Check that the binary is an ELF64LE object file. |
43 | auto *E = dyn_cast<ELF64LEObjectFile>(Val: &Binary); |
44 | if (!E) |
45 | return 0; |
46 | |
47 | // Fuzz RewriteInstance. |
48 | auto RIOrErr = RewriteInstance::create(File: E, Argc: argc, Argv: argv, ToolPath: "llvm-bolt" ); |
49 | if (Error E = RIOrErr.takeError()) { |
50 | consumeError(Err: std::move(E)); |
51 | return 0; |
52 | } |
53 | RewriteInstance &RI = *RIOrErr.get(); |
54 | if (Error E = RI.run()) |
55 | consumeError(Err: std::move(E)); |
56 | return 0; |
57 | } |
58 | |
59 | extern "C" LLVM_ATTRIBUTE_USED int LLVMFuzzerInitialize(int *argc, |
60 | char ***argv) { |
61 | llvm::InitializeAllTargetInfos(); |
62 | llvm::InitializeAllTargetMCs(); |
63 | llvm::InitializeAllAsmParsers(); |
64 | llvm::InitializeAllDisassemblers(); |
65 | |
66 | llvm::InitializeAllTargets(); |
67 | llvm::InitializeAllAsmPrinters(); |
68 | |
69 | return 0; |
70 | } |
71 | |