xref: /llvm-project/bolt/tools/llvm-bolt-fuzzer/llvm-bolt-fuzzer.cpp (revision 16492a6143aba599beaac71752f612751ab3af09)
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 
LLVMFuzzerTestOneInput(const char * Data,size_t Size)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("\177ELF", Data, 4) != 0)
30     return 0;
31   // Construct an ELF binary from fuzzer input.
32   std::unique_ptr<MemoryBuffer> Buffer =
33       MemoryBuffer::getMemBuffer(StringRef(Data, Size), "", false);
34   Expected<std::unique_ptr<Binary>> BinaryOrErr =
35       createBinary(Buffer->getMemBufferRef());
36   // Check that the input is a valid binary.
37   if (Error E = BinaryOrErr.takeError()) {
38     consumeError(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>(&Binary);
44   if (!E)
45     return 0;
46 
47   // Fuzz RewriteInstance.
48   auto RIOrErr = RewriteInstance::create(E, argc, argv, "llvm-bolt");
49   if (Error E = RIOrErr.takeError()) {
50     consumeError(std::move(E));
51     return 0;
52   }
53   RewriteInstance &RI = *RIOrErr.get();
54   if (Error E = RI.run())
55     consumeError(std::move(E));
56   return 0;
57 }
58 
LLVMFuzzerInitialize(int * argc,char *** argv)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