summaryrefslogtreecommitdiff
path: root/lib/DebugInfo/PDB
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-06-26 20:32:52 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-06-26 20:32:52 +0000
commit08bbd35a80bf7765fe0d3043f9eb5a2f2786b649 (patch)
tree80108f0f128657f8623f8f66ad9735b4d88e7b47 /lib/DebugInfo/PDB
parent7c7aba6e5fef47a01a136be655b0a92cfd7090f6 (diff)
Notes
Diffstat (limited to 'lib/DebugInfo/PDB')
-rw-r--r--lib/DebugInfo/PDB/DIA/DIASession.cpp2
-rw-r--r--lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp8
-rw-r--r--lib/DebugInfo/PDB/Native/DbiStream.cpp52
-rw-r--r--lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp9
-rw-r--r--lib/DebugInfo/PDB/Native/InfoStream.cpp8
-rw-r--r--lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp36
-rw-r--r--lib/DebugInfo/PDB/Native/NamedStreamMap.cpp24
-rw-r--r--lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp9
-rw-r--r--lib/DebugInfo/PDB/Native/NativeEnumModules.cpp2
-rw-r--r--lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp9
-rw-r--r--lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp8
-rw-r--r--lib/DebugInfo/PDB/Native/NativeSession.cpp7
-rw-r--r--lib/DebugInfo/PDB/Native/PDBFile.cpp8
-rw-r--r--lib/DebugInfo/PDB/Native/TpiStream.cpp12
14 files changed, 147 insertions, 47 deletions
diff --git a/lib/DebugInfo/PDB/DIA/DIASession.cpp b/lib/DebugInfo/PDB/DIA/DIASession.cpp
index ef47b92b4f2f3..ef9390cda3127 100644
--- a/lib/DebugInfo/PDB/DIA/DIASession.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIASession.cpp
@@ -151,7 +151,7 @@ void DIASession::setLoadAddress(uint64_t Address) {
Session->put_loadAddress(Address);
}
-std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() const {
+std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() {
CComPtr<IDiaSymbol> GlobalScope;
if (S_OK != Session->get_globalScope(&GlobalScope))
return nullptr;
diff --git a/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
index 81a9d3eeec619..745dd742aadc3 100644
--- a/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
@@ -51,6 +51,7 @@ DbiModuleDescriptorBuilder::DbiModuleDescriptorBuilder(StringRef ModuleName,
uint32_t ModIndex,
msf::MSFBuilder &Msf)
: MSF(Msf), ModuleName(ModuleName) {
+ ::memset(&Layout, 0, sizeof(Layout));
Layout.Mod = ModIndex;
}
@@ -102,6 +103,7 @@ template <typename T> struct Foo {
template <typename T> Foo<T> makeFoo(T &&t) { return Foo<T>(std::move(t)); }
void DbiModuleDescriptorBuilder::finalize() {
+ Layout.SC.ModuleIndex = Layout.Mod;
Layout.FileNameOffs = 0; // TODO: Fix this
Layout.Flags = 0; // TODO: Fix this
Layout.C11Bytes = 0;
@@ -182,3 +184,9 @@ void DbiModuleDescriptorBuilder::addDebugSubsection(
C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
std::move(Subsection), CodeViewContainer::Pdb));
}
+
+void DbiModuleDescriptorBuilder::addDebugSubsection(
+ const DebugSubsectionRecord &SubsectionContents) {
+ C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
+ SubsectionContents, CodeViewContainer::Pdb));
+}
diff --git a/lib/DebugInfo/PDB/Native/DbiStream.cpp b/lib/DebugInfo/PDB/Native/DbiStream.cpp
index 24322d942facc..a1f0671dec3e6 100644
--- a/lib/DebugInfo/PDB/Native/DbiStream.cpp
+++ b/lib/DebugInfo/PDB/Native/DbiStream.cpp
@@ -99,29 +99,27 @@ Error DbiStream::reload() {
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI type server substream not aligned.");
- BinaryStreamRef ModInfoSubstream;
- BinaryStreamRef FileInfoSubstream;
- if (auto EC =
- Reader.readStreamRef(ModInfoSubstream, Header->ModiSubstreamSize))
+ if (auto EC = Reader.readSubstream(ModiSubstream, Header->ModiSubstreamSize))
return EC;
- if (auto EC = Reader.readStreamRef(SecContrSubstream,
+ if (auto EC = Reader.readSubstream(SecContrSubstream,
Header->SecContrSubstreamSize))
return EC;
- if (auto EC = Reader.readStreamRef(SecMapSubstream, Header->SectionMapSize))
+ if (auto EC = Reader.readSubstream(SecMapSubstream, Header->SectionMapSize))
return EC;
- if (auto EC = Reader.readStreamRef(FileInfoSubstream, Header->FileInfoSize))
+ if (auto EC = Reader.readSubstream(FileInfoSubstream, Header->FileInfoSize))
return EC;
if (auto EC =
- Reader.readStreamRef(TypeServerMapSubstream, Header->TypeServerSize))
+ Reader.readSubstream(TypeServerMapSubstream, Header->TypeServerSize))
return EC;
- if (auto EC = Reader.readStreamRef(ECSubstream, Header->ECSubstreamSize))
+ if (auto EC = Reader.readSubstream(ECSubstream, Header->ECSubstreamSize))
return EC;
if (auto EC = Reader.readArray(
DbgStreams, Header->OptionalDbgHdrSize / sizeof(ulittle16_t)))
return EC;
- if (auto EC = Modules.initialize(ModInfoSubstream, FileInfoSubstream))
+ if (auto EC = Modules.initialize(ModiSubstream.StreamData,
+ FileInfoSubstream.StreamData))
return EC;
if (auto EC = initializeSectionContributionData())
@@ -137,8 +135,8 @@ Error DbiStream::reload() {
return make_error<RawError>(raw_error_code::corrupt_file,
"Found unexpected bytes in DBI Stream.");
- if (ECSubstream.getLength() > 0) {
- BinaryStreamReader ECReader(ECSubstream);
+ if (!ECSubstream.empty()) {
+ BinaryStreamReader ECReader(ECSubstream.StreamData);
if (auto EC = ECNames.reload(ECReader))
return EC;
}
@@ -228,10 +226,10 @@ void DbiStream::visitSectionContributions(
}
Error DbiStream::initializeSectionContributionData() {
- if (SecContrSubstream.getLength() == 0)
+ if (SecContrSubstream.empty())
return Error::success();
- BinaryStreamReader SCReader(SecContrSubstream);
+ BinaryStreamReader SCReader(SecContrSubstream.StreamData);
if (auto EC = SCReader.readEnum(SectionContribVersion))
return EC;
@@ -302,11 +300,33 @@ Error DbiStream::initializeFpoRecords() {
return Error::success();
}
+BinarySubstreamRef DbiStream::getSectionContributionData() const {
+ return SecContrSubstream;
+}
+
+BinarySubstreamRef DbiStream::getSecMapSubstreamData() const {
+ return SecMapSubstream;
+}
+
+BinarySubstreamRef DbiStream::getModiSubstreamData() const {
+ return ModiSubstream;
+}
+
+BinarySubstreamRef DbiStream::getFileInfoSubstreamData() const {
+ return FileInfoSubstream;
+}
+
+BinarySubstreamRef DbiStream::getTypeServerMapSubstreamData() const {
+ return TypeServerMapSubstream;
+}
+
+BinarySubstreamRef DbiStream::getECSubstreamData() const { return ECSubstream; }
+
Error DbiStream::initializeSectionMapData() {
- if (SecMapSubstream.getLength() == 0)
+ if (SecMapSubstream.empty())
return Error::success();
- BinaryStreamReader SMReader(SecMapSubstream);
+ BinaryStreamReader SMReader(SecMapSubstream.StreamData);
const SecMapHeader *Header;
if (auto EC = SMReader.readObject(Header))
return EC;
diff --git a/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
index e7304b444f23f..aad247ea185f2 100644
--- a/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
@@ -90,10 +90,14 @@ Error DbiStreamBuilder::addModuleSourceFile(StringRef Module, StringRef File) {
if (ModIter == ModiMap.end())
return make_error<RawError>(raw_error_code::no_entry,
"The specified module was not found");
+ return addModuleSourceFile(*ModIter->second, File);
+}
+
+Error DbiStreamBuilder::addModuleSourceFile(DbiModuleDescriptorBuilder &Module,
+ StringRef File) {
uint32_t Index = SourceFileNames.size();
SourceFileNames.insert(std::make_pair(File, Index));
- auto &ModEntry = *ModIter;
- ModEntry.second->addSourceFile(File);
+ Module.addSourceFile(File);
return Error::success();
}
@@ -233,6 +237,7 @@ Error DbiStreamBuilder::finalize() {
return EC;
DbiStreamHeader *H = Allocator.Allocate<DbiStreamHeader>();
+ ::memset(H, 0, sizeof(DbiStreamHeader));
H->VersionHeader = *VerHeader;
H->VersionSignature = -1;
H->Age = Age;
diff --git a/lib/DebugInfo/PDB/Native/InfoStream.cpp b/lib/DebugInfo/PDB/Native/InfoStream.cpp
index a3979d480bf45..21b66b3e7bcff 100644
--- a/lib/DebugInfo/PDB/Native/InfoStream.cpp
+++ b/lib/DebugInfo/PDB/Native/InfoStream.cpp
@@ -57,6 +57,10 @@ Error InfoStream::reload() {
uint32_t NewOffset = Reader.getOffset();
NamedStreamMapByteSize = NewOffset - Offset;
+ Reader.setOffset(Offset);
+ if (auto EC = Reader.readSubstream(SubNamedStreams, NamedStreamMapByteSize))
+ return EC;
+
bool Stop = false;
while (!Stop && !Reader.empty()) {
PdbRaw_FeatureSig Sig;
@@ -129,3 +133,7 @@ ArrayRef<PdbRaw_FeatureSig> InfoStream::getFeatureSignatures() const {
const NamedStreamMap &InfoStream::getNamedStreams() const {
return NamedStreams;
}
+
+BinarySubstreamRef InfoStream::getNamedStreamsBuffer() const {
+ return SubNamedStreams;
+}
diff --git a/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp b/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
index 4186f2eb6ba01..83c56574a16e5 100644
--- a/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
+++ b/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
@@ -47,15 +47,19 @@ Error ModuleDebugStreamRef::reload() {
if (auto EC = Reader.readInteger(Signature))
return EC;
- if (auto EC = Reader.readArray(SymbolsSubstream, SymbolSize - 4))
+ if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize - 4))
return EC;
-
- if (auto EC = Reader.readStreamRef(C11LinesSubstream, C11Size))
+ if (auto EC = Reader.readSubstream(C11LinesSubstream, C11Size))
+ return EC;
+ if (auto EC = Reader.readSubstream(C13LinesSubstream, C13Size))
return EC;
- if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size))
+
+ BinaryStreamReader SymbolReader(SymbolsSubstream.StreamData);
+ if (auto EC =
+ SymbolReader.readArray(SymbolArray, SymbolReader.bytesRemaining()))
return EC;
- BinaryStreamReader SubsectionsReader(C13LinesSubstream);
+ BinaryStreamReader SubsectionsReader(C13LinesSubstream.StreamData);
if (auto EC = SubsectionsReader.readArray(Subsections,
SubsectionsReader.bytesRemaining()))
return EC;
@@ -63,7 +67,7 @@ Error ModuleDebugStreamRef::reload() {
uint32_t GlobalRefsSize;
if (auto EC = Reader.readInteger(GlobalRefsSize))
return EC;
- if (auto EC = Reader.readStreamRef(GlobalRefsSubstream, GlobalRefsSize))
+ if (auto EC = Reader.readSubstream(GlobalRefsSubstream, GlobalRefsSize))
return EC;
if (Reader.bytesRemaining() > 0)
return make_error<RawError>(raw_error_code::corrupt_file,
@@ -72,9 +76,25 @@ Error ModuleDebugStreamRef::reload() {
return Error::success();
}
+BinarySubstreamRef ModuleDebugStreamRef::getSymbolsSubstream() const {
+ return SymbolsSubstream;
+}
+
+BinarySubstreamRef ModuleDebugStreamRef::getC11LinesSubstream() const {
+ return C11LinesSubstream;
+}
+
+BinarySubstreamRef ModuleDebugStreamRef::getC13LinesSubstream() const {
+ return C13LinesSubstream;
+}
+
+BinarySubstreamRef ModuleDebugStreamRef::getGlobalRefsSubstream() const {
+ return GlobalRefsSubstream;
+}
+
iterator_range<codeview::CVSymbolArray::Iterator>
ModuleDebugStreamRef::symbols(bool *HadError) const {
- return make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end());
+ return make_range(SymbolArray.begin(HadError), SymbolArray.end());
}
llvm::iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator>
@@ -83,7 +103,7 @@ ModuleDebugStreamRef::subsections() const {
}
bool ModuleDebugStreamRef::hasDebugSubsections() const {
- return C13LinesSubstream.getLength() > 0;
+ return !C13LinesSubstream.empty();
}
Error ModuleDebugStreamRef::commit() { return Error::success(); }
diff --git a/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp b/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
index c7ba32b82bc6b..4f90cd9cd8ac0 100644
--- a/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
+++ b/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
@@ -23,6 +23,14 @@
using namespace llvm;
using namespace llvm::pdb;
+// FIXME: This shouldn't be necessary, but if we insert the strings in any
+// other order, cvdump cannot read the generated name map. This suggests that
+// we may be using the wrong hash function. A closer inspection of the cvdump
+// source code may reveal something, but for now this at least makes us work,
+// even if only by accident.
+static constexpr const char *OrderedStreamNames[] = {"/LinkInfo", "/names",
+ "/src/headerblock"};
+
NamedStreamMap::NamedStreamMap() = default;
Error NamedStreamMap::load(BinaryStreamReader &Stream) {
@@ -73,9 +81,10 @@ Error NamedStreamMap::commit(BinaryStreamWriter &Writer) const {
if (auto EC = Writer.writeInteger(FinalizedInfo->StringDataBytes))
return EC;
- // Now all of the string data itself.
- for (const auto &Item : Mapping) {
- if (auto EC = Writer.writeCString(Item.getKey()))
+ for (const auto &Name : OrderedStreamNames) {
+ auto Item = Mapping.find(Name);
+ assert(Item != Mapping.end());
+ if (auto EC = Writer.writeCString(Item->getKey()))
return EC;
}
@@ -93,9 +102,12 @@ uint32_t NamedStreamMap::finalize() {
// Build the finalized hash table.
FinalizedHashTable.clear();
FinalizedInfo.emplace();
- for (const auto &Item : Mapping) {
- FinalizedHashTable.set(FinalizedInfo->StringDataBytes, Item.getValue());
- FinalizedInfo->StringDataBytes += Item.getKeyLength() + 1;
+
+ for (const auto &Name : OrderedStreamNames) {
+ auto Item = Mapping.find(Name);
+ assert(Item != Mapping.end());
+ FinalizedHashTable.set(FinalizedInfo->StringDataBytes, Item->getValue());
+ FinalizedInfo->StringDataBytes += Item->getKeyLength() + 1;
}
// Number of bytes of string data.
diff --git a/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
index 77f832582f824..180c169ec209c 100644
--- a/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
@@ -9,17 +9,24 @@
#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+#include "llvm/ADT/STLExtras.h"
+
namespace llvm {
namespace pdb {
NativeCompilandSymbol::NativeCompilandSymbol(NativeSession &Session,
+ uint32_t SymbolId,
DbiModuleDescriptor MI)
- : NativeRawSymbol(Session), Module(MI) {}
+ : NativeRawSymbol(Session, SymbolId), Module(MI) {}
PDB_SymType NativeCompilandSymbol::getSymTag() const {
return PDB_SymType::Compiland;
}
+std::unique_ptr<NativeRawSymbol> NativeCompilandSymbol::clone() const {
+ return llvm::make_unique<NativeCompilandSymbol>(Session, SymbolId, Module);
+}
+
bool NativeCompilandSymbol::isEditAndContinueEnabled() const {
return Module.hasECInfo();
}
diff --git a/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp b/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
index 97319fd77d117..c23120041164a 100644
--- a/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
@@ -34,7 +34,7 @@ NativeEnumModules::getChildAtIndex(uint32_t Index) const {
return nullptr;
return std::unique_ptr<PDBSymbol>(new PDBSymbolCompiland(
Session, std::unique_ptr<IPDBRawSymbol>(new NativeCompilandSymbol(
- Session, Modules.getModuleDescriptor(Index)))));
+ Session, 0, Modules.getModuleDescriptor(Index)))));
}
std::unique_ptr<PDBSymbol> NativeEnumModules::getNext() {
diff --git a/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
index bb52560be167a..6206155b9fb64 100644
--- a/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
@@ -9,6 +9,7 @@
#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h"
@@ -17,8 +18,12 @@
namespace llvm {
namespace pdb {
-NativeExeSymbol::NativeExeSymbol(NativeSession &Session)
- : NativeRawSymbol(Session), File(Session.getPDBFile()) {}
+NativeExeSymbol::NativeExeSymbol(NativeSession &Session, uint32_t SymbolId)
+ : NativeRawSymbol(Session, SymbolId), File(Session.getPDBFile()) {}
+
+std::unique_ptr<NativeRawSymbol> NativeExeSymbol::clone() const {
+ return llvm::make_unique<NativeExeSymbol>(Session, SymbolId);
+}
std::unique_ptr<IPDBEnumSymbols>
NativeExeSymbol::findChildren(PDB_SymType Type) const {
diff --git a/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
index 70968d4330b07..ed6db63edbabf 100644
--- a/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
@@ -22,8 +22,8 @@
using namespace llvm;
using namespace llvm::pdb;
-NativeRawSymbol::NativeRawSymbol(NativeSession &PDBSession)
- : Session(PDBSession) {}
+NativeRawSymbol::NativeRawSymbol(NativeSession &PDBSession, uint32_t SymbolId)
+ : Session(PDBSession), SymbolId(SymbolId) {}
void NativeRawSymbol::dump(raw_ostream &OS, int Indent) const {}
@@ -253,9 +253,7 @@ uint32_t NativeRawSymbol::getSubTypeId() const {
std::string NativeRawSymbol::getSymbolsFileName() const { return ""; }
-uint32_t NativeRawSymbol::getSymIndexId() const {
- return 0;
-}
+uint32_t NativeRawSymbol::getSymIndexId() const { return SymbolId; }
uint32_t NativeRawSymbol::getTargetOffset() const {
return 0;
diff --git a/lib/DebugInfo/PDB/Native/NativeSession.cpp b/lib/DebugInfo/PDB/Native/NativeSession.cpp
index 7e6843bceb7db..3ab381e76e628 100644
--- a/lib/DebugInfo/PDB/Native/NativeSession.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeSession.cpp
@@ -70,12 +70,11 @@ uint64_t NativeSession::getLoadAddress() const { return 0; }
void NativeSession::setLoadAddress(uint64_t Address) {}
-std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() const {
- auto RawSymbol =
- llvm::make_unique<NativeExeSymbol>(const_cast<NativeSession &>(*this));
+std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
+ auto RawSymbol = llvm::make_unique<NativeExeSymbol>(*this, 0);
auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
std::unique_ptr<PDBSymbolExe> ExeSymbol(
- static_cast<PDBSymbolExe *>(PdbSymbol.release()));
+ static_cast<PDBSymbolExe *>(PdbSymbol.release()));
return ExeSymbol;
}
diff --git a/lib/DebugInfo/PDB/Native/PDBFile.cpp b/lib/DebugInfo/PDB/Native/PDBFile.cpp
index a9597cdf4c4d3..4f6ebb0cb3428 100644
--- a/lib/DebugInfo/PDB/Native/PDBFile.cpp
+++ b/lib/DebugInfo/PDB/Native/PDBFile.cpp
@@ -230,6 +230,14 @@ ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {
return ContainerLayout.DirectoryBlocks;
}
+MSFStreamLayout PDBFile::getStreamLayout(uint32_t StreamIdx) const {
+ MSFStreamLayout Result;
+ auto Blocks = getStreamBlockList(StreamIdx);
+ Result.Blocks.assign(Blocks.begin(), Blocks.end());
+ Result.Length = getStreamByteSize(StreamIdx);
+ return Result;
+}
+
Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() {
if (!Globals) {
auto DbiS = getPDBDbiStream();
diff --git a/lib/DebugInfo/PDB/Native/TpiStream.cpp b/lib/DebugInfo/PDB/Native/TpiStream.cpp
index 67c803d3124ec..f917ef91f6396 100644
--- a/lib/DebugInfo/PDB/Native/TpiStream.cpp
+++ b/lib/DebugInfo/PDB/Native/TpiStream.cpp
@@ -66,7 +66,13 @@ Error TpiStream::reload() {
"TPI Stream Invalid number of hash buckets.");
// The actual type records themselves come from this stream
- if (auto EC = Reader.readArray(TypeRecords, Header->TypeRecordBytes))
+ if (auto EC =
+ Reader.readSubstream(TypeRecordsSubstream, Header->TypeRecordBytes))
+ return EC;
+
+ BinaryStreamReader RecordReader(TypeRecordsSubstream.StreamData);
+ if (auto EC =
+ RecordReader.readArray(TypeRecords, TypeRecordsSubstream.size()))
return EC;
// Hash indices, hash values, etc come from the hash stream.
@@ -135,6 +141,10 @@ uint16_t TpiStream::getTypeHashStreamAuxIndex() const {
uint32_t TpiStream::getNumHashBuckets() const { return Header->NumHashBuckets; }
uint32_t TpiStream::getHashKeySize() const { return Header->HashKeySize; }
+BinarySubstreamRef TpiStream::getTypeRecordsSubstream() const {
+ return TypeRecordsSubstream;
+}
+
FixedStreamArray<support::ulittle32_t> TpiStream::getHashValues() const {
return HashValues;
}