blob: 38eaf16c65b05dae4ccbca9f3fe76f40e0ee65e9 [file] [log] [blame]
David Majnemer8df24c32016-05-31 01:24:40 +00001//===-- llvm-pdbdump-fuzzer.cpp - Fuzz the llvm-pdbdump tool --------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief This file implements a function that runs llvm-pdbdump
12/// on a single input. This function is then linked into the Fuzzer library.
13///
14//===----------------------------------------------------------------------===//
Zachary Turnerb84faa82016-06-10 05:10:19 +000015#include "llvm/ADT/STLExtras.h"
Zachary Turner120faca2017-02-27 22:11:43 +000016#include "llvm/DebugInfo/CodeView/BinaryByteStream.h"
David Majnemer8df24c32016-05-31 01:24:40 +000017#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
18#include "llvm/DebugInfo/CodeView/TypeDumper.h"
19#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
Zachary Turner36eb0472016-06-09 00:21:37 +000020#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"
21#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
David Majnemer8df24c32016-05-31 01:24:40 +000022#include "llvm/DebugInfo/PDB/Raw/ModStream.h"
23#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
24#include "llvm/DebugInfo/PDB/Raw/RawSession.h"
25#include "llvm/Support/MemoryBuffer.h"
26#include "llvm/Support/ScopedPrinter.h"
27
28using namespace llvm;
29
Zachary Turnerb84faa82016-06-10 05:10:19 +000030namespace {
Zachary Turner120faca2017-02-27 22:11:43 +000031// We need a class which behaves like an immutable BinaryByteStream, but whose
32// data
Zachary Turnerb84faa82016-06-10 05:10:19 +000033// is backed by an llvm::MemoryBuffer. It also needs to own the underlying
34// MemoryBuffer, so this simple adapter is a good way to achieve that.
Zachary Turner120faca2017-02-27 22:11:43 +000035class InputByteStream : public codeview::BinaryByteStream<false> {
Zachary Turnerb84faa82016-06-10 05:10:19 +000036public:
37 explicit InputByteStream(std::unique_ptr<MemoryBuffer> Buffer)
Zachary Turner120faca2017-02-27 22:11:43 +000038 : BinaryByteStream(ArrayRef<uint8_t>(Buffer->getBuffer().bytes_begin(),
39 Buffer->getBuffer().bytes_end())),
Zachary Turnerb84faa82016-06-10 05:10:19 +000040 MemBuffer(std::move(Buffer)) {}
41
42 std::unique_ptr<MemoryBuffer> MemBuffer;
43};
44}
45
Kostya Serebryanyf7a8ef52016-05-31 23:39:31 +000046extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
David Majnemer8df24c32016-05-31 01:24:40 +000047 std::unique_ptr<MemoryBuffer> Buff = MemoryBuffer::getMemBuffer(
48 StringRef((const char *)data, size), "", false);
49
50 ScopedPrinter P(nulls());
Reid Klecknercbb1d062016-05-31 22:32:54 +000051 codeview::CVTypeDumper TD(&P, false);
David Majnemer8df24c32016-05-31 01:24:40 +000052
Zachary Turnerb84faa82016-06-10 05:10:19 +000053 auto InputStream = llvm::make_unique<InputByteStream>(std::move(Buff));
54 std::unique_ptr<pdb::PDBFile> File(new pdb::PDBFile(std::move(InputStream)));
David Majnemer8df24c32016-05-31 01:24:40 +000055 if (auto E = File->parseFileHeaders()) {
56 consumeError(std::move(E));
Kostya Serebryanyf7a8ef52016-05-31 23:39:31 +000057 return 0;
David Majnemer8df24c32016-05-31 01:24:40 +000058 }
59 if (auto E = File->parseStreamData()) {
60 consumeError(std::move(E));
Kostya Serebryanyf7a8ef52016-05-31 23:39:31 +000061 return 0;
David Majnemer8df24c32016-05-31 01:24:40 +000062 }
63
64 auto DbiS = File->getPDBDbiStream();
65 if (auto E = DbiS.takeError()) {
66 consumeError(std::move(E));
Kostya Serebryanyf7a8ef52016-05-31 23:39:31 +000067 return 0;
David Majnemer8df24c32016-05-31 01:24:40 +000068 }
69 auto TpiS = File->getPDBTpiStream();
70 if (auto E = TpiS.takeError()) {
71 consumeError(std::move(E));
Kostya Serebryanyf7a8ef52016-05-31 23:39:31 +000072 return 0;
David Majnemer8df24c32016-05-31 01:24:40 +000073 }
74 auto IpiS = File->getPDBIpiStream();
75 if (auto E = IpiS.takeError()) {
76 consumeError(std::move(E));
Kostya Serebryanyf7a8ef52016-05-31 23:39:31 +000077 return 0;
David Majnemer8df24c32016-05-31 01:24:40 +000078 }
79 auto InfoS = File->getPDBInfoStream();
80 if (auto E = InfoS.takeError()) {
81 consumeError(std::move(E));
Kostya Serebryanyf7a8ef52016-05-31 23:39:31 +000082 return 0;
David Majnemer8df24c32016-05-31 01:24:40 +000083 }
84 pdb::DbiStream &DS = DbiS.get();
85
86 for (auto &Modi : DS.modules()) {
Zachary Turner36eb0472016-06-09 00:21:37 +000087 auto ModStreamData = pdb::MappedBlockStream::createIndexedStream(
88 Modi.Info.getModuleStreamIndex(), *File);
89 if (!ModStreamData) {
90 consumeError(ModStreamData.takeError());
91 return 0;
92 }
93 pdb::ModStream ModS(Modi.Info, std::move(*ModStreamData));
David Majnemer8df24c32016-05-31 01:24:40 +000094 if (auto E = ModS.reload()) {
95 consumeError(std::move(E));
Kostya Serebryanyf7a8ef52016-05-31 23:39:31 +000096 return 0;
David Majnemer8df24c32016-05-31 01:24:40 +000097 }
98 codeview::CVSymbolDumper SD(P, TD, nullptr, false);
99 bool HadError = false;
100 for (auto &S : ModS.symbols(&HadError)) {
101 SD.dump(S);
102 }
103 }
Kostya Serebryanyf7a8ef52016-05-31 23:39:31 +0000104 return 0;
David Majnemer8df24c32016-05-31 01:24:40 +0000105}