summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/StreamArray.h2
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/StreamReader.h14
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h4
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h38
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h34
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h5
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h12
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h2
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h7
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h2
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h4
-rw-r--r--llvm/lib/DebugInfo/PDB/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp11
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/IndexedStreamData.cpp25
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp25
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp7
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp155
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp6
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp10
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp.rej11
-rw-r--r--llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp7
23 files changed, 247 insertions, 143 deletions
diff --git a/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h b/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h
index 7dd731df947..0241bb82be2 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h
@@ -224,6 +224,8 @@ public:
return FixedStreamArrayIterator<T>(*this, size());
}
+ StreamRef getUnderlyingStream() const { return Stream; }
+
private:
StreamRef Stream;
};
diff --git a/llvm/include/llvm/DebugInfo/CodeView/StreamReader.h b/llvm/include/llvm/DebugInfo/CodeView/StreamReader.h
index a0e6a076b09..0cd779419c5 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/StreamReader.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/StreamReader.h
@@ -52,6 +52,20 @@ public:
return Error::success();
}
+ template <typename T>
+ Error readArray(ArrayRef<T> &Array, uint32_t NumElements) {
+ ArrayRef<uint8_t> Bytes;
+ if (NumElements == 0) {
+ Array = ArrayRef<T>();
+ return Error::success();
+ }
+
+ if (auto EC = readBytes(Bytes, NumElements * sizeof(T)))
+ return EC;
+ Array = ArrayRef<T>(reinterpret_cast<const T *>(Bytes.data()), NumElements);
+ return Error::success();
+ }
+
template <typename T, typename U>
Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
StreamRef S;
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h b/llvm/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h
index d76ba9f10ee..a772ef1a7ae 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h
@@ -12,6 +12,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
#include "llvm/Support/Endian.h"
#include <stdint.h>
@@ -28,7 +29,8 @@ public:
virtual uint32_t getNumStreams() const = 0;
virtual uint32_t getStreamByteSize(uint32_t StreamIndex) const = 0;
- virtual ArrayRef<uint32_t> getStreamBlockList(uint32_t StreamIndex) const = 0;
+ virtual ArrayRef<support::ulittle32_t>
+ getStreamBlockList(uint32_t StreamIndex) const = 0;
virtual StringRef getBlockData(uint32_t BlockIndex,
uint32_t NumBytes) const = 0;
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h b/llvm/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h
new file mode 100644
index 00000000000..ab3c9f77075
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h
@@ -0,0 +1,38 @@
+//===- IPDBStreamData.h - Base interface for PDB Stream Data ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_IPDBSTREAMDATA_H
+#define LLVM_DEBUGINFO_PDB_RAW_IPDBSTREAMDATA_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace pdb {
+/// IPDBStream abstracts the notion of PDB stream data. Although we already
+/// have another stream abstraction (namely in the form of StreamInterface
+/// and MappedBlockStream), they assume that the stream data is referenced
+/// the same way. Namely, by looking in the directory to get the list of
+/// stream blocks, and by looking in the array of stream lengths to get the
+/// length. This breaks down for the directory itself, however, since its
+/// length and list of blocks are stored elsewhere. By abstracting the
+/// notion of stream data further, we can use a MappedBlockStream to read
+/// from the directory itself, or from an indexed stream which references
+/// the directory.
+class IPDBStreamData {
+public:
+ virtual ~IPDBStreamData() {}
+
+ virtual uint32_t getLength() = 0;
+ virtual ArrayRef<support::ulittle32_t> getStreamBlocks() = 0;
+};
+}
+}
+
+#endif
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h b/llvm/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h
new file mode 100644
index 00000000000..30563bc5b89
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h
@@ -0,0 +1,34 @@
+//===- IndexedStreamData.h - Standard PDB Stream Data -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_INDEXEDSTREAMDATA_H
+#define LLVM_DEBUGINFO_PDB_RAW_INDEXEDSTREAMDATA_H
+
+#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"
+
+namespace llvm {
+namespace pdb {
+class IPDBFile;
+
+class IndexedStreamData : public IPDBStreamData {
+public:
+ IndexedStreamData(uint32_t StreamIdx, const IPDBFile &File);
+ virtual ~IndexedStreamData() {}
+
+ uint32_t getLength() override;
+ ArrayRef<support::ulittle32_t> getStreamBlocks() override;
+
+private:
+ uint32_t StreamIdx;
+ const IPDBFile &File;
+};
+}
+}
+
+#endif
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h
index 39ac2796595..01b0b16e7f8 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h
@@ -24,7 +24,7 @@ namespace pdb {
class PDBFile;
class InfoStream {
public:
- InfoStream(PDBFile &File);
+ InfoStream(const PDBFile &File);
Error reload();
@@ -36,10 +36,7 @@ public:
uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
iterator_range<StringMapConstIterator<uint32_t>> named_streams() const;
- PDBFile &getFile() { return Pdb; }
-
private:
- PDBFile &Pdb;
MappedBlockStream Stream;
// PDB file format version. We only support VC70. See the enumeration
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h
index e8eb7cf7e27..ea5d0a147ad 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h
@@ -14,6 +14,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/DebugInfo/CodeView/StreamInterface.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cstdint>
#include <vector>
@@ -22,15 +23,16 @@ namespace llvm {
namespace pdb {
class IPDBFile;
+class IPDBStreamData;
class MappedBlockStream : public codeview::StreamInterface {
public:
- MappedBlockStream(uint32_t StreamIdx, const IPDBFile &File);
+ MappedBlockStream(std::unique_ptr<IPDBStreamData> Data, const IPDBFile &File);
Error readBytes(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const override;
- uint32_t getLength() const override { return StreamLength; }
+ uint32_t getLength() const override;
uint32_t getNumBytesCopied() const;
@@ -39,11 +41,11 @@ private:
bool tryReadContiguously(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const;
- uint32_t StreamLength;
- std::vector<uint32_t> BlockList;
+ const IPDBFile &Pdb;
+ std::unique_ptr<IPDBStreamData> Data;
+
mutable llvm::BumpPtrAllocator Pool;
mutable DenseMap<uint32_t, uint8_t *> CacheMap;
- const IPDBFile &Pdb;
};
} // end namespace pdb
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h
index b76537f025f..570e513e371 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h
@@ -26,7 +26,7 @@ class ModInfo;
class ModStream {
public:
- ModStream(PDBFile &File, const ModInfo &Module);
+ ModStream(const PDBFile &File, const ModInfo &Module);
~ModStream();
Error reload();
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
index 1b8dbb898be..d3f269430a7 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
@@ -11,6 +11,7 @@
#define LLVM_DEBUGINFO_PDB_RAW_PDBFILE_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
#include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
@@ -48,11 +49,12 @@ public:
uint32_t getNumStreams() const override;
uint32_t getStreamByteSize(uint32_t StreamIndex) const override;
- ArrayRef<uint32_t> getStreamBlockList(uint32_t StreamIndex) const override;
+ ArrayRef<support::ulittle32_t>
+ getStreamBlockList(uint32_t StreamIndex) const override;
StringRef getBlockData(uint32_t BlockIndex, uint32_t NumBytes) const override;
- ArrayRef<support::ulittle32_t> getDirectoryBlockArray();
+ ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;
Error parseFileHeaders();
Error parseStreamData();
@@ -81,6 +83,7 @@ private:
std::unique_ptr<TpiStream> Ipi;
std::unique_ptr<PublicsStream> Publics;
std::unique_ptr<SymbolStream> Symbols;
+ std::unique_ptr<MappedBlockStream> DirectoryStream;
std::unique_ptr<MappedBlockStream> StringTableStream;
std::unique_ptr<NameHashTable> StringTable;
};
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h
index 1f8598d4410..dc43e221786 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h
@@ -22,7 +22,7 @@ class PDBFile;
class SymbolStream {
public:
- SymbolStream(PDBFile &File, uint32_t StreamNum);
+ SymbolStream(const PDBFile &File, uint32_t StreamNum);
~SymbolStream();
Error reload();
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h
index 52fd31a90b0..a3eb8e6af55 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h
@@ -31,7 +31,7 @@ class TpiStream {
struct HeaderInfo;
public:
- TpiStream(PDBFile &File, uint32_t StreamIdx);
+ TpiStream(const PDBFile &File, uint32_t StreamIdx);
~TpiStream();
Error reload();
@@ -50,7 +50,7 @@ public:
iterator_range<codeview::CVTypeArray::Iterator> types(bool *HadError) const;
private:
- PDBFile &Pdb;
+ const PDBFile &Pdb;
MappedBlockStream Stream;
HashFunctionType HashFunction;
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
index 46074f769cd..336729d3543 100644
--- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
@@ -30,6 +30,7 @@ endif()
add_pdb_impl_folder(Raw
Raw/DbiStream.cpp
Raw/EnumTables.cpp
+ Raw/IndexedStreamData.cpp
Raw/InfoStream.cpp
Raw/MappedBlockStream.cpp
Raw/ModInfo.cpp
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
index b1c571bf78c..80441ccd825 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
@@ -12,6 +12,7 @@
#include "llvm/DebugInfo/CodeView/StreamArray.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h"
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
@@ -93,7 +94,9 @@ Error loadSectionContribs(FixedStreamArray<ContribType> &Output,
}
DbiStream::DbiStream(PDBFile &File)
- : Pdb(File), Stream(StreamDBI, File), Header(nullptr) {
+ : Pdb(File),
+ Stream(llvm::make_unique<IndexedStreamData>(StreamDBI, File), File),
+ Header(nullptr) {
static_assert(sizeof(HeaderInfo) == 64, "Invalid HeaderInfo size!");
}
@@ -290,7 +293,8 @@ Error DbiStream::initializeSectionContributionData() {
// Initializes this->SectionHeaders.
Error DbiStream::initializeSectionHeadersData() {
uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr);
- SectionHeaderStream.reset(new MappedBlockStream(StreamNum, Pdb));
+ SectionHeaderStream.reset(new MappedBlockStream(
+ llvm::make_unique<IndexedStreamData>(StreamNum, Pdb), Pdb));
size_t StreamLen = SectionHeaderStream->getLength();
if (StreamLen % sizeof(object::coff_section))
@@ -308,7 +312,8 @@ Error DbiStream::initializeSectionHeadersData() {
// Initializes this->Fpos.
Error DbiStream::initializeFpoRecords() {
uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::NewFPO);
- FpoStream.reset(new MappedBlockStream(StreamNum, Pdb));
+ FpoStream.reset(new MappedBlockStream(
+ llvm::make_unique<IndexedStreamData>(StreamNum, Pdb), Pdb));
size_t StreamLen = FpoStream->getLength();
if (StreamLen % sizeof(object::FpoData))
diff --git a/llvm/lib/DebugInfo/PDB/Raw/IndexedStreamData.cpp b/llvm/lib/DebugInfo/PDB/Raw/IndexedStreamData.cpp
new file mode 100644
index 00000000000..9bd16ea76ef
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Raw/IndexedStreamData.cpp
@@ -0,0 +1,25 @@
+//===- IndexedStreamData.cpp - Standard PDB Stream Data ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
+#include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+IndexedStreamData::IndexedStreamData(uint32_t StreamIdx, const IPDBFile &File)
+ : StreamIdx(StreamIdx), File(File) {}
+
+uint32_t IndexedStreamData::getLength() {
+ return File.getStreamByteSize(StreamIdx);
+}
+
+ArrayRef<support::ulittle32_t> IndexedStreamData::getStreamBlocks() {
+ return File.getStreamBlockList(StreamIdx);
+}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
index 4388ed41664..0f2fd24395c 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
@@ -11,6 +11,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
@@ -18,7 +19,8 @@
using namespace llvm;
using namespace llvm::pdb;
-InfoStream::InfoStream(PDBFile &File) : Pdb(File), Stream(StreamPDB, File) {}
+InfoStream::InfoStream(const PDBFile &File)
+ : Stream(llvm::make_unique<IndexedStreamData>(StreamPDB, File), File) {}
Error InfoStream::reload() {
codeview::StreamReader Reader(Stream);
diff --git a/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp
index 34d16712271..03462b38863 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp
@@ -8,28 +8,23 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
using namespace llvm;
using namespace llvm::pdb;
-MappedBlockStream::MappedBlockStream(uint32_t StreamIdx, const IPDBFile &File)
- : Pdb(File) {
- if (StreamIdx >= Pdb.getNumStreams()) {
- StreamLength = 0;
- } else {
- StreamLength = Pdb.getStreamByteSize(StreamIdx);
- BlockList = Pdb.getStreamBlockList(StreamIdx);
- }
-}
+MappedBlockStream::MappedBlockStream(std::unique_ptr<IPDBStreamData> Data,
+ const IPDBFile &Pdb)
+ : Pdb(Pdb), Data(std::move(Data)) {}
Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const {
// Make sure we aren't trying to read beyond the end of the stream.
- if (Size > StreamLength)
+ if (Size > Data->getLength())
return make_error<RawError>(raw_error_code::insufficient_buffer);
- if (Offset > StreamLength - Size)
+ if (Offset > Data->getLength() - Size)
return make_error<RawError>(raw_error_code::insufficient_buffer);
if (tryReadContiguously(Offset, Size, Buffer))
@@ -57,6 +52,8 @@ Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
return Error::success();
}
+uint32_t MappedBlockStream::getLength() const { return Data->getLength(); }
+
bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const {
// Attempt to fulfill the request with a reference directly into the stream.
@@ -72,6 +69,7 @@ bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
llvm::alignTo(Size - BytesFromFirstBlock, Pdb.getBlockSize()) /
Pdb.getBlockSize();
+ auto BlockList = Data->getStreamBlocks();
uint32_t RequiredContiguousBlocks = NumAdditionalBlocks + 1;
uint32_t E = BlockList[BlockNum];
for (uint32_t I = 0; I < RequiredContiguousBlocks; ++I, ++E) {
@@ -93,14 +91,15 @@ Error MappedBlockStream::readBytes(uint32_t Offset,
uint32_t OffsetInBlock = Offset % Pdb.getBlockSize();
// Make sure we aren't trying to read beyond the end of the stream.
- if (Buffer.size() > StreamLength)
+ if (Buffer.size() > Data->getLength())
return make_error<RawError>(raw_error_code::insufficient_buffer);
- if (Offset > StreamLength - Buffer.size())
+ if (Offset > Data->getLength() - Buffer.size())
return make_error<RawError>(raw_error_code::insufficient_buffer);
uint32_t BytesLeft = Buffer.size();
uint32_t BytesWritten = 0;
uint8_t *WriteBuffer = Buffer.data();
+ auto BlockList = Data->getStreamBlocks();
while (BytesLeft > 0) {
uint32_t StreamBlockAddr = BlockList[BlockNum];
diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
index 14c55906e06..57c455e0a00 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
@@ -10,6 +10,7 @@
#include "llvm/DebugInfo/PDB/Raw/ModStream.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
@@ -18,8 +19,10 @@
using namespace llvm;
using namespace llvm::pdb;
-ModStream::ModStream(PDBFile &File, const ModInfo &Module)
- : Mod(Module), Stream(Module.getModuleStreamIndex(), File) {}
+ModStream::ModStream(const PDBFile &File, const ModInfo &Module)
+ : Mod(Module), Stream(llvm::make_unique<IndexedStreamData>(
+ Module.getModuleStreamIndex(), File),
+ File) {}
ModStream::~ModStream() {}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
index 73d8eef570f..81762e7f879 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
@@ -8,8 +8,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
#include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
@@ -49,13 +53,28 @@ struct SuperBlock {
// This contains the block # of the block map.
support::ulittle32_t BlockMapAddr;
};
+
+class DirectoryStreamData : public IPDBStreamData {
+public:
+ DirectoryStreamData(const PDBFile &File) : File(File) {}
+
+ virtual uint32_t getLength() { return File.getNumDirectoryBytes(); }
+ virtual llvm::ArrayRef<llvm::support::ulittle32_t> getStreamBlocks() {
+ return File.getDirectoryBlockArray();
+ }
+
+private:
+ const PDBFile &File;
+};
+
+typedef codeview::FixedStreamArray<support::ulittle32_t> ulittle_array;
}
struct llvm::pdb::PDBFileContext {
std::unique_ptr<MemoryBuffer> Buffer;
const SuperBlock *SB;
- std::vector<uint32_t> StreamSizes;
- DenseMap<uint32_t, std::vector<uint32_t>> StreamMap;
+ ArrayRef<support::ulittle32_t> StreamSizes;
+ std::vector<ulittle_array> StreamMap;
};
static Error checkOffset(MemoryBufferRef M, uintptr_t Addr,
@@ -109,10 +128,14 @@ uint32_t PDBFile::getStreamByteSize(uint32_t StreamIndex) const {
return Context->StreamSizes[StreamIndex];
}
-llvm::ArrayRef<uint32_t>
+ArrayRef<support::ulittle32_t>
PDBFile::getStreamBlockList(uint32_t StreamIndex) const {
- auto &Data = Context->StreamMap[StreamIndex];
- return llvm::ArrayRef<uint32_t>(Data);
+ auto Result = Context->StreamMap[StreamIndex];
+ codeview::StreamReader Reader(Result.getUnderlyingStream());
+ ArrayRef<support::ulittle32_t> Array;
+ if (auto EC = Reader.readArray(Array, Result.size()))
+ return ArrayRef<support::ulittle32_t>();
+ return Array;
}
StringRef PDBFile::getBlockData(uint32_t BlockIndex, uint32_t NumBytes) const {
@@ -184,113 +207,44 @@ Error PDBFile::parseFileHeaders() {
Error PDBFile::parseStreamData() {
assert(Context && Context->SB);
+ if (DirectoryStream)
+ return Error::success();
- bool SeenNumStreams = false;
+ // bool SeenNumStreams = false;
uint32_t NumStreams = 0;
- uint32_t StreamIdx = 0;
- uint64_t DirectoryBytesRead = 0;
+ // uint32_t StreamIdx = 0;
+ // uint64_t DirectoryBytesRead = 0;
- MemoryBufferRef M = *Context->Buffer;
const SuperBlock *SB = Context->SB;
- auto DirectoryBlocks = getDirectoryBlockArray();
-
- // The structure of the directory is as follows:
- // struct PDBDirectory {
- // uint32_t NumStreams;
- // uint32_t StreamSizes[NumStreams];
- // uint32_t StreamMap[NumStreams][];
- // };
- //
- // Empty streams don't consume entries in the StreamMap.
- for (uint32_t DirectoryBlockAddr : DirectoryBlocks) {
- uint64_t DirectoryBlockOffset =
- blockToOffset(DirectoryBlockAddr, SB->BlockSize);
- auto DirectoryBlock =
- makeArrayRef(reinterpret_cast<const support::ulittle32_t *>(
- M.getBufferStart() + DirectoryBlockOffset),
- SB->BlockSize / sizeof(support::ulittle32_t));
- if (auto EC = checkOffset(M, DirectoryBlock))
- return EC;
-
- // We read data out of the directory four bytes at a time. Depending on
- // where we are in the directory, the contents may be: the number of streams
- // in the directory, a stream's size, or a block in the stream map.
- for (uint32_t Data : DirectoryBlock) {
- // Don't read beyond the end of the directory.
- if (DirectoryBytesRead == SB->NumDirectoryBytes)
- break;
-
- DirectoryBytesRead += sizeof(Data);
-
- // This data must be the number of streams if we haven't seen it yet.
- if (!SeenNumStreams) {
- NumStreams = Data;
- SeenNumStreams = true;
- continue;
- }
- // This data must be a stream size if we have not seen them all yet.
- if (Context->StreamSizes.size() < NumStreams) {
- // It seems like some streams have their set to -1 when their contents
- // are not present. Treat them like empty streams for now.
- if (Data == UINT32_MAX)
- Context->StreamSizes.push_back(0);
- else
- Context->StreamSizes.push_back(Data);
- continue;
- }
-
- // This data must be a stream block number if we have seen all of the
- // stream sizes.
- std::vector<uint32_t> *StreamBlocks = nullptr;
- // Figure out which stream this block number belongs to.
- while (StreamIdx < NumStreams) {
- uint64_t NumExpectedStreamBlocks =
- bytesToBlocks(Context->StreamSizes[StreamIdx], SB->BlockSize);
- StreamBlocks = &Context->StreamMap[StreamIdx];
- if (NumExpectedStreamBlocks > StreamBlocks->size())
- break;
- ++StreamIdx;
- }
- // It seems this block doesn't belong to any stream? The stream is either
- // corrupt or something more mysterious is going on.
- if (StreamIdx == NumStreams)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Orphaned block found?");
-
- uint64_t BlockOffset = blockToOffset(Data, getBlockSize());
- if (BlockOffset + getBlockSize() < BlockOffset)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Bogus stream block number");
- if (BlockOffset + getBlockSize() > M.getBufferSize())
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Stream block number is out of bounds");
-
- StreamBlocks->push_back(Data);
- }
- }
-
- if (Context->StreamSizes.size() != NumStreams)
- return make_error<RawError>(
- raw_error_code::corrupt_file,
- "The directory has fewer streams then expected");
+ // Normally you can't use a MappedBlockStream without having fully parsed the
+ // PDB file, because it accesses the directory and various other things, which
+ // is exactly what we are attempting to parse. By specifying a custom
+ // subclass of IPDBStreamData which only accesses the fields that have already
+ // been parsed, we can avoid this and reuse MappedBlockStream.
+ auto SD = llvm::make_unique<DirectoryStreamData>(*this);
+ DirectoryStream = llvm::make_unique<MappedBlockStream>(std::move(SD), *this);
+ codeview::StreamReader Reader(*DirectoryStream);
+ if (auto EC = Reader.readInteger(NumStreams))
+ return EC;
- for (uint32_t I = 0; I != NumStreams; ++I) {
+ if (auto EC = Reader.readArray(Context->StreamSizes, NumStreams))
+ return EC;
+ for (uint32_t I = 0; I < NumStreams; ++I) {
uint64_t NumExpectedStreamBlocks =
- bytesToBlocks(getStreamByteSize(I), getBlockSize());
- size_t NumStreamBlocks = getStreamBlockList(I).size();
- if (NumExpectedStreamBlocks != NumStreamBlocks)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "The number of stream blocks is not "
- "sufficient for the size of this stream");
+ bytesToBlocks(getStreamByteSize(I), SB->BlockSize);
+ ulittle_array Blocks;
+ if (auto EC = Reader.readArray(Blocks, NumExpectedStreamBlocks))
+ return EC;
+ Context->StreamMap.push_back(Blocks);
}
// We should have read exactly SB->NumDirectoryBytes bytes.
- assert(DirectoryBytesRead == SB->NumDirectoryBytes);
+ assert(Reader.bytesRemaining() == 0);
return Error::success();
}
-llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() {
+llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {
return makeArrayRef(
reinterpret_cast<const support::ulittle32_t *>(
Context->Buffer->getBufferStart() + getBlockMapOffset()),
@@ -371,7 +325,8 @@ Expected<NameHashTable &> PDBFile::getStringTable() {
if (NameStreamIndex == 0)
return make_error<RawError>(raw_error_code::no_stream);
- auto S = llvm::make_unique<MappedBlockStream>(NameStreamIndex, *this);
+ auto SD = llvm::make_unique<IndexedStreamData>(NameStreamIndex, *this);
+ auto S = llvm::make_unique<MappedBlockStream>(std::move(SD), *this);
codeview::StreamReader Reader(*S);
auto N = llvm::make_unique<NameHashTable>();
if (auto EC = N->load(Reader))
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
index d3a7ffd7f93..e3e100806ee 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
@@ -27,6 +27,7 @@
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
@@ -71,7 +72,8 @@ struct PublicsStream::GSIHashHeader {
};
PublicsStream::PublicsStream(PDBFile &File, uint32_t StreamNum)
- : Pdb(File), StreamNum(StreamNum), Stream(StreamNum, File) {}
+ : Pdb(File), StreamNum(StreamNum),
+ Stream(llvm::make_unique<IndexedStreamData>(StreamNum, File), File) {}
PublicsStream::~PublicsStream() {}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp
index 8b358b04f68..b6267a7f3f4 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp
@@ -12,6 +12,7 @@
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
@@ -23,8 +24,9 @@ using namespace llvm;
using namespace llvm::support;
using namespace llvm::pdb;
-SymbolStream::SymbolStream(PDBFile &File, uint32_t StreamNum)
- : MappedStream(StreamNum, File) {}
+SymbolStream::SymbolStream(const PDBFile &File, uint32_t StreamNum)
+ : MappedStream(llvm::make_unique<IndexedStreamData>(StreamNum, File),
+ File) {}
SymbolStream::~SymbolStream() {}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
index 11e10a58e5d..9d8a45ebc88 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
@@ -13,6 +13,7 @@
#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
@@ -61,8 +62,10 @@ struct TpiStream::HeaderInfo {
EmbeddedBuf HashAdjBuffer;
};
-TpiStream::TpiStream(PDBFile &File, uint32_t StreamIdx)
- : Pdb(File), Stream(StreamIdx, File), HashFunction(nullptr) {}
+TpiStream::TpiStream(const PDBFile &File, uint32_t StreamIdx)
+ : Pdb(File),
+ Stream(llvm::make_unique<IndexedStreamData>(StreamIdx, File), File),
+ HashFunction(nullptr) {}
TpiStream::~TpiStream() {}
@@ -101,7 +104,8 @@ Error TpiStream::reload() {
return EC;
// Hash indices, hash values, etc come from the hash stream.
- HashStream.reset(new MappedBlockStream(Header->HashStreamIndex, Pdb));
+ HashStream.reset(new MappedBlockStream(
+ llvm::make_unique<IndexedStreamData>(Header->HashStreamIndex, Pdb), Pdb));
codeview::StreamReader HSR(*HashStream);
uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);
diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp.rej b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp.rej
new file mode 100644
index 00000000000..3547269eff4
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp.rej
@@ -0,0 +1,11 @@
+diff a/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/lib/DebugInfo/PDB/Raw/TpiStream.cpp (rejected hunks)
+@@ -101,7 +104,8 @@
+ return EC;
+
+ // Hash indices, hash values, etc come from the hash stream.
+- HashStream.reset(new MappedBlockStream(Header->HashStreamIndex, Pdb));
++ HashStream.reset(new MappedBlockStream(
++ llvm::make_unique<IndexedStreamData>(Header->HashStreamIndex, Pdb), Pdb));
+ codeview::StreamReader HSR(*HashStream);
+ uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);
+ HSR.setOffset(Header->HashValueBuffer.Off);
diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
index 034879bf0f4..f819a2cfc92 100644
--- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
@@ -17,6 +17,7 @@
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
#include "llvm/DebugInfo/PDB/Raw/EnumTables.h"
#include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h"
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
#include "llvm/DebugInfo/PDB/Raw/ModStream.h"
@@ -194,7 +195,8 @@ Error LLVMOutputStyle::dumpStreamData() {
DumpStreamNum >= StreamCount)
return Error::success();
- MappedBlockStream S(DumpStreamNum, File);
+ MappedBlockStream S(llvm::make_unique<IndexedStreamData>(DumpStreamNum, File),
+ File);
codeview::StreamReader R(S);
while (R.bytesRemaining() > 0) {
ArrayRef<uint8_t> Data;
@@ -244,7 +246,8 @@ Error LLVMOutputStyle::dumpNamedStream() {
DictScope D(P, Name);
P.printNumber("Index", NameStreamIndex);
- MappedBlockStream NameStream(NameStreamIndex, File);
+ MappedBlockStream NameStream(
+ llvm::make_unique<IndexedStreamData>(NameStreamIndex, File), File);
codeview::StreamReader Reader(NameStream);
NameHashTable NameTable;
OpenPOWER on IntegriCloud