diff options
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Raw')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp | 26 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/RawError.cpp | 4 |
3 files changed, 44 insertions, 8 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp index 8c46957706e..e79d6572be1 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp @@ -345,7 +345,6 @@ Error DbiStream::initializeFileInfo() { FixedStreamArray<ulittle16_t> ModIndexArray; FixedStreamArray<ulittle16_t> ModFileCountArray; - 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, @@ -373,10 +372,8 @@ Error DbiStream::initializeFileInfo() { if (auto EC = FISR.readArray(FileNameOffsets, NumSourceFiles)) return EC; - StreamRef NamesBufferRef; - if (auto EC = FISR.readStreamRef(NamesBufferRef)) + if (auto EC = FISR.readStreamRef(NamesBuffer)) return EC; - 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 @@ -387,10 +384,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 FileOffset = FileNameOffsets[NextFileIndex]; - Names.setOffset(FileOffset); - if (auto EC = Names.readZeroString(ModuleInfos[I].SourceFiles[J])) - return EC; + if (auto Name = getFileNameForIndex(NextFileIndex)) + ModuleInfos[I].SourceFiles[J] = Name.get(); + else + return Name.takeError(); } } @@ -400,3 +397,16 @@ Error DbiStream::initializeFileInfo() { uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const { return DbgStreams[static_cast<uint16_t>(Type)]; } + +Expected<StringRef> DbiStream::getFileNameForIndex(uint32_t Index) const { + StreamReader Names(NamesBuffer); + if (Index >= FileNameOffsets.size()) + return make_error<RawError>(raw_error_code::index_out_of_bounds); + + uint32_t FileOffset = FileNameOffsets[Index]; + Names.setOffset(FileOffset); + StringRef Name; + if (auto EC = Names.readZeroString(Name)) + return std::move(EC); + return Name; +} diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp index d0fbb142ec3..73d8eef570f 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp @@ -11,6 +11,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/DebugInfo/PDB/Raw/DbiStream.h" #include "llvm/DebugInfo/PDB/Raw/InfoStream.h" +#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h" #include "llvm/DebugInfo/PDB/Raw/PublicsStream.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" #include "llvm/DebugInfo/PDB/Raw/SymbolStream.h" @@ -359,3 +360,24 @@ Expected<SymbolStream &> PDBFile::getPDBSymbolStream() { } return *Symbols; } + +Expected<NameHashTable &> PDBFile::getStringTable() { + if (!StringTable || !StringTableStream) { + auto InfoS = getPDBInfoStream(); + if (auto EC = InfoS.takeError()) + return std::move(EC); + auto &IS = InfoS.get(); + uint32_t NameStreamIndex = IS.getNamedStreamIndex("/names"); + + if (NameStreamIndex == 0) + return make_error<RawError>(raw_error_code::no_stream); + auto S = llvm::make_unique<MappedBlockStream>(NameStreamIndex, *this); + codeview::StreamReader Reader(*S); + auto N = llvm::make_unique<NameHashTable>(); + if (auto EC = N->load(Reader)) + return std::move(EC); + StringTable = std::move(N); + StringTableStream = std::move(S); + } + return *StringTable; +} diff --git a/llvm/lib/DebugInfo/PDB/Raw/RawError.cpp b/llvm/lib/DebugInfo/PDB/Raw/RawError.cpp index 037a1aab4b1..bcfa55a8b01 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/RawError.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/RawError.cpp @@ -24,6 +24,10 @@ public: case raw_error_code::insufficient_buffer: return "The buffer is not large enough to read the requested number of " "bytes."; + case raw_error_code::no_stream: + return "The specified stream could not be loaded."; + case raw_error_code::index_out_of_bounds: + return "The specified item does not exist in the array."; } llvm_unreachable("Unrecognized raw_error_code"); } |