llvm/tools/llvm-pdbdump/fuzzer/llvm-pdbdump-fuzzer.cpp
Zachary Turner 2219387eaf [PDB] Partial resubmit of r296215, which improved PDB Stream Library.
This was reverted because it was breaking some builds, and
because of incorrect error code usage.  Since the CL was
large and contained many different things, I'm resubmitting
it in pieces.

This portion is NFC, and consists of:

1) Renaming classes to follow a consistent naming convention.
2) Fixing the const-ness of the interface methods.
3) Adding detailed doxygen comments.
4) Fixing a few instances of passing `const BinaryStream& X`.  These
   are now passed as `BinaryStreamRef X`.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296394 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-27 22:11:43 +00:00

106 lines
3.4 KiB
C++

//===-- llvm-pdbdump-fuzzer.cpp - Fuzz the llvm-pdbdump tool --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements a function that runs llvm-pdbdump
/// on a single input. This function is then linked into the Fuzzer library.
///
//===----------------------------------------------------------------------===//
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/CodeView/BinaryByteStream.h"
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
#include "llvm/DebugInfo/CodeView/TypeDumper.h"
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Raw/ModStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawSession.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ScopedPrinter.h"
using namespace llvm;
namespace {
// We need a class which behaves like an immutable BinaryByteStream, but whose
// data
// is backed by an llvm::MemoryBuffer. It also needs to own the underlying
// MemoryBuffer, so this simple adapter is a good way to achieve that.
class InputByteStream : public codeview::BinaryByteStream<false> {
public:
explicit InputByteStream(std::unique_ptr<MemoryBuffer> Buffer)
: BinaryByteStream(ArrayRef<uint8_t>(Buffer->getBuffer().bytes_begin(),
Buffer->getBuffer().bytes_end())),
MemBuffer(std::move(Buffer)) {}
std::unique_ptr<MemoryBuffer> MemBuffer;
};
}
extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
std::unique_ptr<MemoryBuffer> Buff = MemoryBuffer::getMemBuffer(
StringRef((const char *)data, size), "", false);
ScopedPrinter P(nulls());
codeview::CVTypeDumper TD(&P, false);
auto InputStream = llvm::make_unique<InputByteStream>(std::move(Buff));
std::unique_ptr<pdb::PDBFile> File(new pdb::PDBFile(std::move(InputStream)));
if (auto E = File->parseFileHeaders()) {
consumeError(std::move(E));
return 0;
}
if (auto E = File->parseStreamData()) {
consumeError(std::move(E));
return 0;
}
auto DbiS = File->getPDBDbiStream();
if (auto E = DbiS.takeError()) {
consumeError(std::move(E));
return 0;
}
auto TpiS = File->getPDBTpiStream();
if (auto E = TpiS.takeError()) {
consumeError(std::move(E));
return 0;
}
auto IpiS = File->getPDBIpiStream();
if (auto E = IpiS.takeError()) {
consumeError(std::move(E));
return 0;
}
auto InfoS = File->getPDBInfoStream();
if (auto E = InfoS.takeError()) {
consumeError(std::move(E));
return 0;
}
pdb::DbiStream &DS = DbiS.get();
for (auto &Modi : DS.modules()) {
auto ModStreamData = pdb::MappedBlockStream::createIndexedStream(
Modi.Info.getModuleStreamIndex(), *File);
if (!ModStreamData) {
consumeError(ModStreamData.takeError());
return 0;
}
pdb::ModStream ModS(Modi.Info, std::move(*ModStreamData));
if (auto E = ModS.reload()) {
consumeError(std::move(E));
return 0;
}
codeview::CVSymbolDumper SD(P, TD, nullptr, false);
bool HadError = false;
for (auto &S : ModS.symbols(&HadError)) {
SD.dump(S);
}
}
return 0;
}