summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/PDB/Raw
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-05-27 01:54:44 +0000
committerZachary Turner <zturner@google.com>2016-05-27 01:54:44 +0000
commit8dbe3629a09a754464f1420ce3059676c986090a (patch)
treea332a7c4b100869604af7066e58aa664ac623289 /llvm/lib/DebugInfo/PDB/Raw
parentbd8e9542163f4218b6ad52df8c143c06263ff4a2 (diff)
downloadbcm5719-llvm-8dbe3629a09a754464f1420ce3059676c986090a.tar.gz
bcm5719-llvm-8dbe3629a09a754464f1420ce3059676c986090a.zip
[codeview,pdb] Try really hard to conserve memory when reading.
PDBs can be extremely large. We're already mapping the entire PDB into the process's address space, but to make matters worse the blocks of the PDB are not arranged contiguously. So, when we have something like an array or a string embedded into the stream, we have to make a copy. Since it's convenient to use traditional data structures to iterate and manipulate these records, we need the memory to be contiguous. As a result of this, we were using roughly twice as much memory as the file size of the PDB, because every stream was copied out and re-stitched together contiguously. This patch addresses this by improving the MappedBlockStream to allocate from a BumpPtrAllocator only when a read requires a discontiguous read. Furthermore, it introduces some data structures backed by a stream which can iterate over both fixed and variable length records of a PDB. Since everything is backed by a stream and not a buffer, we can read almost everything from the PDB with zero copies. Differential Revision: http://reviews.llvm.org/D20654 Reviewed By: ruiu llvm-svn: 270951
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Raw')
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp85
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp14
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp85
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp77
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp8
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp30
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp7
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp13
10 files changed, 179 insertions, 146 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
index 078384ebae3..35937574645 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
@@ -6,9 +6,9 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
@@ -73,7 +73,8 @@ struct DbiStream::HeaderInfo {
ulittle32_t Reserved; // Pad to 64 bytes
};
-DbiStream::DbiStream(PDBFile &File) : Pdb(File), Stream(StreamDBI, File) {
+DbiStream::DbiStream(PDBFile &File)
+ : Pdb(File), Stream(StreamDBI, File), Header(nullptr) {
static_assert(sizeof(HeaderInfo) == 64, "Invalid HeaderInfo size!");
}
@@ -82,12 +83,10 @@ DbiStream::~DbiStream() {}
Error DbiStream::reload() {
codeview::StreamReader Reader(Stream);
- Header.reset(new HeaderInfo());
-
if (Stream.getLength() < sizeof(HeaderInfo))
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI Stream does not contain a header.");
- if (auto EC = Reader.readObject(Header.get()))
+ if (auto EC = Reader.readObject(Header))
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI Stream does not contain a header.");
@@ -137,30 +136,31 @@ Error DbiStream::reload() {
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI type server substream not aligned.");
- if (auto EC = ModInfoSubstream.initialize(Reader, Header->ModiSubstreamSize))
+ if (auto EC =
+ Reader.readStreamRef(ModInfoSubstream, Header->ModiSubstreamSize))
return EC;
// Since each ModInfo in the stream is a variable length, we have to iterate
// them to know how many there actually are.
- auto Range =
- llvm::make_range(ModInfoIterator(&ModInfoSubstream.data().front()),
- ModInfoIterator(&ModInfoSubstream.data().back() + 1));
- for (auto Info : Range)
- ModuleInfos.push_back(ModuleInfoEx(Info));
+ codeview::VarStreamArray ModInfoArray(ModInfoSubstream, ModInfoRecordLength);
+ for (auto Info : ModInfoArray) {
+ ModuleInfos.emplace_back(Info);
+ }
- if (auto EC =
- SecContrSubstream.initialize(Reader, Header->SecContrSubstreamSize))
+ if (auto EC = Reader.readStreamRef(SecContrSubstream,
+ Header->SecContrSubstreamSize))
return EC;
- if (auto EC = SecMapSubstream.initialize(Reader, Header->SectionMapSize))
+ if (auto EC = Reader.readStreamRef(SecMapSubstream, Header->SectionMapSize))
return EC;
- if (auto EC = FileInfoSubstream.initialize(Reader, Header->FileInfoSize))
+ if (auto EC = Reader.readStreamRef(FileInfoSubstream, Header->FileInfoSize))
return EC;
if (auto EC =
- TypeServerMapSubstream.initialize(Reader, Header->TypeServerSize))
+ Reader.readStreamRef(TypeServerMapSubstream, Header->TypeServerSize))
return EC;
- if (auto EC = ECSubstream.initialize(Reader, Header->ECSubstreamSize))
+ if (auto EC = Reader.readStreamRef(ECSubstream, Header->ECSubstreamSize))
return EC;
- if (auto EC = DbgHeader.initialize(Reader, Header->OptionalDbgHdrSize))
+ if (auto EC = Reader.readArray(DbgStreams, Header->OptionalDbgHdrSize /
+ sizeof(ulittle16_t)))
return EC;
if (auto EC = initializeFileInfo())
@@ -247,25 +247,30 @@ Error DbiStream::initializeFileInfo() {
// with the caveat that `NumSourceFiles` cannot be trusted, so
// it is computed by summing `ModFileCounts`.
//
- const uint8_t *Buf = &FileInfoSubstream.data().front();
- auto FI = reinterpret_cast<const FileInfoSubstreamHeader *>(Buf);
- Buf += sizeof(FileInfoSubstreamHeader);
+ const FileInfoSubstreamHeader *FH;
+ codeview::StreamReader FISR(FileInfoSubstream);
+ if (auto EC = FISR.readObject(FH))
+ return EC;
+
// The number of modules in the stream should be the same as reported by
// the FileInfoSubstreamHeader.
- if (FI->NumModules != ModuleInfos.size())
+ if (FH->NumModules != ModuleInfos.size())
return make_error<RawError>(raw_error_code::corrupt_file,
"FileInfo substream count doesn't match DBI.");
+ codeview::FixedStreamArray<ulittle16_t> ModIndexArray;
+ codeview::FixedStreamArray<ulittle16_t> ModFileCountArray;
+ codeview::FixedStreamArray<little32_t> FileNameOffsets;
+
// First is an array of `NumModules` module indices. This is not used for the
// same reason that `NumSourceFiles` is not used. It's an array of uint16's,
// but it's possible there are more than 64k source files, which would imply
// more than 64k modules (e.g. object files) as well. So we ignore this
// field.
- llvm::ArrayRef<ulittle16_t> ModIndexArray(
- reinterpret_cast<const ulittle16_t *>(Buf), ModuleInfos.size());
-
- llvm::ArrayRef<ulittle16_t> ModFileCountArray(ModIndexArray.end(),
- ModuleInfos.size());
+ if (auto EC = FISR.readArray(ModIndexArray, ModuleInfos.size()))
+ return EC;
+ if (auto EC = FISR.readArray(ModFileCountArray, ModuleInfos.size()))
+ return EC;
// Compute the real number of source files.
uint32_t NumSourceFiles = 0;
@@ -280,11 +285,13 @@ Error DbiStream::initializeFileInfo() {
// them in `ModuleInfoEx`. The value written to and read from the file is
// not used anyway, it is only there as a way to store the offsets for the
// purposes of later accessing the names at runtime.
- llvm::ArrayRef<little32_t> FileNameOffsets(
- reinterpret_cast<const little32_t *>(ModFileCountArray.end()),
- NumSourceFiles);
+ if (auto EC = FISR.readArray(FileNameOffsets, NumSourceFiles))
+ return EC;
- const char *Names = reinterpret_cast<const char *>(FileNameOffsets.end());
+ codeview::StreamRef NamesBufferRef;
+ if (auto EC = FISR.readStreamRef(NamesBufferRef))
+ return EC;
+ codeview::StreamReader Names(NamesBufferRef);
// We go through each ModuleInfo, determine the number N of source files for
// that module, and then get the next N offsets from the Offsets array, using
@@ -295,8 +302,10 @@ Error DbiStream::initializeFileInfo() {
uint32_t NumFiles = ModFileCountArray[I];
ModuleInfos[I].SourceFiles.resize(NumFiles);
for (size_t J = 0; J < NumFiles; ++J, ++NextFileIndex) {
- uint32_t FileIndex = FileNameOffsets[NextFileIndex];
- ModuleInfos[I].SourceFiles[J] = StringRef(Names + FileIndex);
+ uint32_t FileOffset = FileNameOffsets[NextFileIndex];
+ Names.setOffset(FileOffset);
+ if (auto EC = Names.readZeroString(ModuleInfos[I].SourceFiles[J]))
+ return EC;
}
}
@@ -304,13 +313,5 @@ Error DbiStream::initializeFileInfo() {
}
uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const {
- ArrayRef<uint8_t> DbgData;
- if (auto EC = DbgHeader.getArrayRef(0, DbgData, DbgHeader.getLength())) {
- consumeError(std::move(EC));
- return uint32_t(-1);
- }
- ArrayRef<ulittle16_t> DebugStreams(
- reinterpret_cast<const ulittle16_t *>(DbgData.data()),
- DbgData.size() / sizeof(ulittle16_t));
- return DebugStreams[static_cast<uint16_t>(Type)];
+ return DbgStreams[static_cast<uint16_t>(Type)];
}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
index e7c8a831c73..64d8319efe1 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
@@ -29,19 +29,19 @@ Error InfoStream::reload() {
PDB_UniqueId Guid;
};
- Header H;
- if (auto EC = Reader.readObject(&H))
+ const Header *H;
+ if (auto EC = Reader.readObject(H))
return make_error<RawError>(raw_error_code::corrupt_file,
"PDB Stream does not contain a header.");
- if (H.Version < PdbRaw_ImplVer::PdbImplVC70)
+ if (H->Version < PdbRaw_ImplVer::PdbImplVC70)
return make_error<RawError>(raw_error_code::corrupt_file,
"Unsupported PDB stream version.");
- Version = H.Version;
- Signature = H.Signature;
- Age = H.Age;
- Guid = H.Guid;
+ Version = H->Version;
+ Signature = H->Signature;
+ Age = H->Age;
+ Guid = H->Guid;
return NamedStreams.load(Reader);
}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp
index 09d71985031..a3db147f57e 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp
@@ -23,6 +23,69 @@ MappedBlockStream::MappedBlockStream(uint32_t StreamIdx, const PDBFile &File) :
}
}
+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 (Buffer.size() > StreamLength)
+ return make_error<RawError>(raw_error_code::insufficient_buffer);
+ if (Offset > StreamLength - Buffer.size())
+ return make_error<RawError>(raw_error_code::insufficient_buffer);
+
+ if (tryReadContiguously(Offset, Size, Buffer))
+ return Error::success();
+
+ auto CacheIter = CacheMap.find(Offset);
+ if (CacheIter != CacheMap.end()) {
+ // In a more general solution, we would need to guarantee that the
+ // cached allocation is at least the requested size. In practice, since
+ // these are CodeView / PDB records, we know they are always formatted
+ // the same way and never change, so we should never be requesting two
+ // allocations from the same address with different sizes.
+ Buffer = ArrayRef<uint8_t>(CacheIter->second, Size);
+ return Error::success();
+ }
+
+ // Otherwise allocate a large enough buffer in the pool, memcpy the data
+ // into it, and return an ArrayRef to that.
+ uint8_t *WriteBuffer = Pool.Allocate<uint8_t>(Size);
+
+ if (auto EC = readBytes(Offset, MutableArrayRef<uint8_t>(WriteBuffer, Size)))
+ return EC;
+ CacheMap.insert(std::make_pair(Offset, WriteBuffer));
+ Buffer = ArrayRef<uint8_t>(WriteBuffer, Size);
+ return Error::success();
+}
+
+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.
+ // This can work even if the request crosses a block boundary, provided that
+ // all subsequent blocks are contiguous. For example, a 10k read with a 4k
+ // block size can be filled with a reference if, from the starting offset,
+ // 3 blocks in a row are contiguous.
+ uint32_t BlockNum = Offset / Pdb.getBlockSize();
+ uint32_t OffsetInBlock = Offset % Pdb.getBlockSize();
+ uint32_t BytesFromFirstBlock =
+ std::min(Size, Pdb.getBlockSize() - OffsetInBlock);
+ uint32_t NumAdditionalBlocks =
+ llvm::alignTo(Size - BytesFromFirstBlock, Pdb.getBlockSize()) /
+ Pdb.getBlockSize();
+
+ uint32_t RequiredContiguousBlocks = NumAdditionalBlocks + 1;
+ uint32_t E = BlockList[BlockNum];
+ for (uint32_t I = 0; I < RequiredContiguousBlocks; ++I, ++E) {
+ if (BlockList[I + BlockNum] != E)
+ return false;
+ }
+
+ uint32_t FirstBlockAddr = BlockList[BlockNum];
+ StringRef Str = Pdb.getBlockData(FirstBlockAddr, Pdb.getBlockSize());
+ Str = Str.drop_front(OffsetInBlock);
+ Buffer =
+ ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Str.data()), Size);
+ return true;
+}
+
Error MappedBlockStream::readBytes(uint32_t Offset,
MutableArrayRef<uint8_t> Buffer) const {
uint32_t BlockNum = Offset / Pdb.getBlockSize();
@@ -54,27 +117,5 @@ Error MappedBlockStream::readBytes(uint32_t Offset,
}
return Error::success();
-}
-Error MappedBlockStream::getArrayRef(uint32_t Offset, ArrayRef<uint8_t> &Buffer,
- uint32_t Length) const {
- uint32_t BlockNum = Offset / Pdb.getBlockSize();
- uint32_t OffsetInBlock = Offset % Pdb.getBlockSize();
- uint32_t BytesAvailableInBlock = Pdb.getBlockSize() - OffsetInBlock;
-
- // If this is the last block in the stream, not all of the data is valid.
- if (BlockNum == BlockList.size() - 1) {
- uint32_t AllocatedBytesInBlock = StreamLength % Pdb.getBlockSize();
- if (AllocatedBytesInBlock < BytesAvailableInBlock)
- BytesAvailableInBlock = AllocatedBytesInBlock;
- }
- if (BytesAvailableInBlock < Length)
- return make_error<RawError>(raw_error_code::feature_unsupported);
-
- uint32_t StreamBlockAddr = BlockList[BlockNum];
- StringRef Data = Pdb.getBlockData(StreamBlockAddr, Pdb.getBlockSize());
- Data = Data.substr(OffsetInBlock, Length);
-
- Buffer = ArrayRef<uint8_t>(Data.bytes_begin(), Data.bytes_end());
- return Error::success();
}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp
index 362c402c09b..9ccb7edd696 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
+
+#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/Support/Endian.h"
@@ -16,6 +18,7 @@ using namespace llvm::pdb;
using namespace llvm::support;
namespace {
+
struct SCBytes {
ulittle16_t Section;
char Padding1[2];
@@ -60,17 +63,29 @@ struct ModInfo::FileLayout {
// for now since it is unused.
ulittle32_t SrcFileNameNI; // Name Index for src file name
ulittle32_t PdbFilePathNI; // Name Index for path to compiler PDB
- char VarInfo[1]; // Module name followed by Obj File Name
-
- StringRef getModuleName() const { return StringRef(VarInfo); }
+ // Null terminated Module name
+ // Null terminated Obj File Name
+};
- StringRef getObjectFileName() const {
- return StringRef(getModuleName().end() + 1);
+ModInfo::ModInfo(codeview::StreamRef Stream) : Layout(nullptr) {
+ codeview::StreamReader Reader(Stream);
+ if (auto EC = Reader.readObject(Layout)) {
+ consumeError(std::move(EC));
+ return;
}
-};
+ if (auto EC = Reader.readZeroString(ModuleName)) {
+ consumeError(std::move(EC));
+ return;
+ }
+ if (auto EC = Reader.readZeroString(ObjFileName)) {
+ consumeError(std::move(EC));
+ return;
+ }
+}
-ModInfo::ModInfo(const uint8_t *Bytes)
- : Layout(reinterpret_cast<const FileLayout *>(Bytes)) {}
+ModInfo::ModInfo(const ModInfo &Info)
+ : ModuleName(Info.ModuleName), ObjFileName(Info.ObjFileName),
+ Layout(Info.Layout) {}
ModInfo::~ModInfo() {}
@@ -100,44 +115,14 @@ uint32_t ModInfo::getPdbFilePathNameIndex() const {
return Layout->PdbFilePathNI;
}
-llvm::StringRef ModInfo::getModuleName() const {
- return Layout->getModuleName();
-}
-
-llvm::StringRef ModInfo::getObjFileName() const {
- return Layout->getObjectFileName();
-}
-
-ModInfoIterator::ModInfoIterator(const uint8_t *Stream) : Bytes(Stream) {}
-
-ModInfoIterator::ModInfoIterator(const ModInfoIterator &Other)
- : Bytes(Other.Bytes) {}
-
-ModInfo ModInfoIterator::operator*() { return ModInfo(Bytes); }
-
-ModInfoIterator &ModInfoIterator::operator++() {
- StringRef Obj = ModInfo(Bytes).getObjFileName();
- Bytes = Obj.bytes_end() + 1;
- Bytes = reinterpret_cast<const uint8_t *>(llvm::alignAddr(Bytes, 4));
-
- return *this;
-}
+StringRef ModInfo::getModuleName() const { return ModuleName; }
-ModInfoIterator ModInfoIterator::operator++(int) {
- ModInfoIterator Copy(*this);
- ++(*this);
- return Copy;
-}
-
-bool ModInfoIterator::operator==(const ModInfoIterator &Other) {
- return Bytes == Other.Bytes;
-}
-
-bool ModInfoIterator::operator!=(const ModInfoIterator &Other) {
- return !(*this == Other);
-}
+StringRef ModInfo::getObjFileName() const { return ObjFileName; }
-ModInfoIterator &ModInfoIterator::operator=(const ModInfoIterator &Other) {
- Bytes = Other.Bytes;
- return *this;
+uint32_t ModInfo::getRecordLength() const {
+ uint32_t M = ModuleName.str().size() + 1;
+ uint32_t O = ObjFileName.str().size() + 1;
+ uint32_t Size = sizeof(FileLayout) + M + O;
+ Size = llvm::alignTo(Size, 4);
+ return Size;
}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
index c359e7757d0..38d3f2f23e3 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
@@ -32,17 +32,17 @@ Error ModStream::reload() {
return llvm::make_error<RawError>(raw_error_code::corrupt_file,
"Module has both C11 and C13 line info");
- if (auto EC = SymbolsSubstream.initialize(Reader, SymbolSize))
+ if (auto EC = SymbolsSubstream.load(Reader, SymbolSize))
return EC;
- if (auto EC = LinesSubstream.initialize(Reader, C11Size))
+ if (auto EC = Reader.readStreamRef(LinesSubstream, C11Size))
return EC;
- if (auto EC = C13LinesSubstream.initialize(Reader, C13Size))
+ if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size))
return EC;
uint32_t GlobalRefsSize;
if (auto EC = Reader.readInteger(GlobalRefsSize))
return EC;
- if (auto EC = GlobalRefsSubstream.initialize(Reader, GlobalRefsSize))
+ if (auto EC = Reader.readStreamRef(GlobalRefsSubstream, GlobalRefsSize))
return EC;
if (Reader.bytesRemaining() > 0)
return llvm::make_error<RawError>(raw_error_code::corrupt_file,
diff --git a/llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp b/llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp
index a542a51b188..7eae7489a0e 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp
@@ -84,28 +84,28 @@ Error NameHashTable::load(codeview::StreamReader &Stream) {
support::ulittle32_t ByteSize;
};
- Header H;
- if (auto EC = Stream.readObject(&H))
+ const Header *H;
+ if (auto EC = Stream.readObject(H))
return EC;
- if (H.Signature != 0xEFFEEFFE)
+ if (H->Signature != 0xEFFEEFFE)
return make_error<RawError>(raw_error_code::corrupt_file,
"Invalid hash table signature");
- if (H.HashVersion != 1 && H.HashVersion != 2)
+ if (H->HashVersion != 1 && H->HashVersion != 2)
return make_error<RawError>(raw_error_code::corrupt_file,
"Unsupported hash version");
- Signature = H.Signature;
- HashVersion = H.HashVersion;
- if (auto EC = NamesBuffer.initialize(Stream, H.ByteSize))
+ Signature = H->Signature;
+ HashVersion = H->HashVersion;
+ if (auto EC = Stream.readStreamRef(NamesBuffer, H->ByteSize))
return make_error<RawError>(raw_error_code::corrupt_file,
"Invalid hash table byte length");
- support::ulittle32_t HashCount;
- if (auto EC = Stream.readObject(&HashCount))
+ const support::ulittle32_t *HashCount;
+ if (auto EC = Stream.readObject(HashCount))
return EC;
- std::vector<support::ulittle32_t> BucketArray(HashCount);
+ std::vector<support::ulittle32_t> BucketArray(*HashCount);
if (auto EC = Stream.readArray<support::ulittle32_t>(BucketArray))
return make_error<RawError>(raw_error_code::corrupt_file,
"Could not read bucket array");
@@ -124,7 +124,15 @@ StringRef NameHashTable::getStringForID(uint32_t ID) const {
if (ID == IDs[0])
return StringRef();
- return StringRef(NamesBuffer.str().begin() + ID);
+ // NamesBuffer is a buffer of null terminated strings back to back. ID is
+ // the starting offset of the string we're looking for. So just seek into
+ // the desired offset and a read a null terminated stream from that offset.
+ StringRef Result;
+ codeview::StreamReader NameReader(NamesBuffer);
+ NameReader.setOffset(ID);
+ if (auto EC = NameReader.readZeroString(Result))
+ consumeError(std::move(EC));
+ return Result;
}
uint32_t NameHashTable::getIDForString(StringRef Str) const {
diff --git a/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp b/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp
index 777d93279c1..be4ce56ab15 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp
@@ -113,7 +113,7 @@ Error NameMap::load(codeview::StreamReader &Stream) {
uint32_t StringOffset = StringsOffset + NameOffset;
uint32_t OldOffset = Stream.getOffset();
// Pump out our c-string from the stream.
- std::string Str;
+ StringRef Str;
Stream.setOffset(StringOffset);
if (Stream.readZeroString(Str))
return make_error<RawError>(raw_error_code::corrupt_file,
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
index db66f536e5a..aba6a147afc 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
@@ -107,12 +107,11 @@ Error PublicsStream::reload() {
"Publics Stream does not contain a header.");
// Read PSGSIHDR and GSIHashHdr structs.
- Header.reset(new HeaderInfo());
- if (Reader.readObject(Header.get()))
+ if (Reader.readObject(Header))
return make_error<RawError>(raw_error_code::corrupt_file,
"Publics Stream does not contain a header.");
- HashHdr.reset(new GSIHashHeader());
- if (Reader.readObject(HashHdr.get()))
+
+ if (Reader.readObject(HashHdr))
return make_error<RawError>(raw_error_code::corrupt_file,
"Publics Stream does not contain a header.");
diff --git a/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp
index 2037a646de7..ba4ea577d81 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp
@@ -30,7 +30,7 @@ SymbolStream::~SymbolStream() {}
Error SymbolStream::reload() {
codeview::StreamReader Reader(MappedStream);
- if (Stream.initialize(Reader, MappedStream.getLength()))
+ if (Stream.load(Reader, MappedStream.getLength()))
return make_error<RawError>(raw_error_code::corrupt_file,
"Could not load symbol stream.");
@@ -40,7 +40,7 @@ Error SymbolStream::reload() {
iterator_range<codeview::SymbolIterator> SymbolStream::getSymbols() const {
using codeview::SymbolIterator;
ArrayRef<uint8_t> Data;
- if (auto Error = Stream.getArrayRef(0, Data, Stream.getLength())) {
+ if (auto Error = Stream.readBytes(0, Stream.getLength(), Data)) {
consumeError(std::move(Error));
return iterator_range<SymbolIterator>(SymbolIterator(), SymbolIterator());
}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
index 99daf6e29fd..3345ab27571 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
@@ -68,8 +68,7 @@ Error TpiStream::reload() {
return make_error<RawError>(raw_error_code::corrupt_file,
"TPI Stream does not contain a header.");
- Header.reset(new HeaderInfo());
- if (Reader.readObject(Header.get()))
+ if (Reader.readObject(Header))
return make_error<RawError>(raw_error_code::corrupt_file,
"TPI Stream does not contain a header.");
@@ -93,7 +92,7 @@ Error TpiStream::reload() {
HashFunction = HashBufferV8;
// The actual type records themselves come from this stream
- if (auto EC = RecordsBuffer.initialize(Reader, Header->TypeRecordBytes))
+ if (auto EC = RecordsBuffer.load(Reader, Header->TypeRecordBytes))
return EC;
// Hash indices, hash values, etc come from the hash stream.
@@ -101,16 +100,16 @@ Error TpiStream::reload() {
codeview::StreamReader HSR(HS);
HSR.setOffset(Header->HashValueBuffer.Off);
if (auto EC =
- HashValuesBuffer.initialize(HSR, Header->HashValueBuffer.Length))
+ HSR.readStreamRef(HashValuesBuffer, Header->HashValueBuffer.Length))
return EC;
HSR.setOffset(Header->HashAdjBuffer.Off);
- if (auto EC = HashAdjBuffer.initialize(HSR, Header->HashAdjBuffer.Length))
+ if (auto EC = HSR.readStreamRef(HashAdjBuffer, Header->HashAdjBuffer.Length))
return EC;
HSR.setOffset(Header->IndexOffsetBuffer.Off);
- if (auto EC = TypeIndexOffsetBuffer.initialize(
- HSR, Header->IndexOffsetBuffer.Length))
+ if (auto EC = HSR.readStreamRef(TypeIndexOffsetBuffer,
+ Header->IndexOffsetBuffer.Length))
return EC;
return Error::success();
OpenPOWER on IntegriCloud