diff options
author | Zachary Turner <zturner@google.com> | 2016-06-03 05:52:57 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2016-06-03 05:52:57 +0000 |
commit | 3df1bfaaec1c70c6501f01868bcd81764c9582e9 (patch) | |
tree | b1451ece7ed3236beda44a10c3e9f514decd66dd /llvm | |
parent | e7ae106147bfa93390e1b275829c93cc60712aa4 (diff) | |
download | bcm5719-llvm-3df1bfaaec1c70c6501f01868bcd81764c9582e9.tar.gz bcm5719-llvm-3df1bfaaec1c70c6501f01868bcd81764c9582e9.zip |
[pdb] Print out file names instead of file offsets.
When printing line information and file checksums, we were printing
the file offset field from the struct header. This teaches
llvm-pdbdump how to turn those numbers into the filename. In the
case of file checksums, this is done by looking in the global
string table. In the case of line contributions, this is done
by indexing into the file names buffer of the DBI stream. Why
they use a different technique I don't know.
llvm-svn: 271630
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/Line.h | 6 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h | 10 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h | 5 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h | 5 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h | 2 | ||||
-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 | ||||
-rw-r--r-- | llvm/test/DebugInfo/PDB/pdbdump-headers.test | 4 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp | 54 |
11 files changed, 104 insertions, 36 deletions
diff --git a/llvm/include/llvm/DebugInfo/CodeView/Line.h b/llvm/include/llvm/DebugInfo/CodeView/Line.h index 278400742b1..975b503fe30 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/Line.h +++ b/llvm/include/llvm/DebugInfo/CodeView/Line.h @@ -142,9 +142,9 @@ struct InlineeSourceLine { }; struct FileChecksum { - ulittle32_t FileNameOffset; // Offset of filename in string table substream. - uint8_t ChecksumSize; - uint8_t ChecksumKind; // FileChecksumKind + ulittle32_t FileNameOffset; // Byte offset of filename in global string table. + uint8_t ChecksumSize; // Number of bytes of checksum. + uint8_t ChecksumKind; // FileChecksumKind // Checksum bytes follow. }; diff --git a/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h b/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h index 0de564d82b4..6affac801d4 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h +++ b/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h @@ -35,7 +35,7 @@ struct LineSubstreamHeader { // Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure. struct LineFileBlockHeader { - support::ulittle32_t FileOffset; + support::ulittle32_t NameIndex; // Index in DBI name buffer of filename. support::ulittle32_t NumLines; // Number of lines support::ulittle32_t BlockSize; // Code size of block, in bytes. // The following two variable length arrays appear immediately after the diff --git a/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h b/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h index 1c15512e98b..6df23090371 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h +++ b/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h @@ -21,7 +21,7 @@ namespace llvm { namespace codeview { struct LineColumnEntry { - support::ulittle32_t Offset; + support::ulittle32_t NameIndex; FixedStreamArray<LineNumberEntry> LineNumbers; FixedStreamArray<ColumnNumberEntry> Columns; }; @@ -50,7 +50,7 @@ public: // The value recorded in BlockHeader->BlockSize includes the size of // LineFileBlockHeader. Len = BlockHeader->BlockSize; - Item.Offset = BlockHeader->FileOffset; + Item.NameIndex = BlockHeader->NameIndex; if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines)) return EC; if (HasColumn) { @@ -65,9 +65,9 @@ private: }; struct FileChecksumEntry { - uint32_t FileNameOffset; - FileChecksumKind Kind; - ArrayRef<uint8_t> Checksum; + uint32_t FileNameOffset; // Byte offset of filename in global stringtable. + FileChecksumKind Kind; // The type of checksum. + ArrayRef<uint8_t> Checksum; // The bytes of the checksum. }; template <> class VarStreamArrayExtractor<FileChecksumEntry> { diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h index c3b00271628..132dfda5506 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h @@ -61,6 +61,8 @@ public: ArrayRef<ModuleInfoEx> modules() const; + Expected<StringRef> getFileNameForIndex(uint32_t Index) const; + codeview::FixedStreamArray<object::coff_section> getSectionHeaders(); codeview::FixedStreamArray<SecMapEntry> getSectionMap() const; @@ -85,12 +87,15 @@ private: codeview::StreamRef TypeServerMapSubstream; codeview::StreamRef ECSubstream; + codeview::StreamRef NamesBuffer; + codeview::FixedStreamArray<support::ulittle16_t> DbgStreams; PdbRaw_DbiSecContribVer SectionContribVersion; codeview::FixedStreamArray<SectionContrib> SectionContribs; codeview::FixedStreamArray<SectionContrib2> SectionContribs2; codeview::FixedStreamArray<SecMapEntry> SectionMap; + codeview::FixedStreamArray<support::little32_t> FileNameOffsets; std::unique_ptr<MappedBlockStream> SectionHeaderStream; codeview::FixedStreamArray<object::coff_section> SectionHeaders; diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h index e6eada8c09d..1b8dbb898be 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h @@ -25,6 +25,8 @@ namespace pdb { struct PDBFileContext; class DbiStream; class InfoStream; +class MappedBlockStream; +class NameHashTable; class PublicsStream; class SymbolStream; class TpiStream; @@ -69,6 +71,7 @@ public: Expected<TpiStream &> getPDBIpiStream(); Expected<PublicsStream &> getPDBPublicsStream(); Expected<SymbolStream &> getPDBSymbolStream(); + Expected<NameHashTable &> getStringTable(); private: std::unique_ptr<PDBFileContext> Context; @@ -78,6 +81,8 @@ private: std::unique_ptr<TpiStream> Ipi; std::unique_ptr<PublicsStream> Publics; std::unique_ptr<SymbolStream> Symbols; + std::unique_ptr<MappedBlockStream> StringTableStream; + std::unique_ptr<NameHashTable> StringTable; }; } } diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h b/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h index b3c491a8bdc..5a1614fc82e 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h @@ -21,6 +21,8 @@ enum class raw_error_code { feature_unsupported, corrupt_file, insufficient_buffer, + no_stream, + index_out_of_bounds }; /// Base class for errors originating when parsing raw PDB files 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"); } diff --git a/llvm/test/DebugInfo/PDB/pdbdump-headers.test b/llvm/test/DebugInfo/PDB/pdbdump-headers.test index 136e4005ef9..902dae9f941 100644 --- a/llvm/test/DebugInfo/PDB/pdbdump-headers.test +++ b/llvm/test/DebugInfo/PDB/pdbdump-headers.test @@ -332,7 +332,7 @@ ; EMPTY-NEXT: ] ; EMPTY-NEXT: LineInfo [ ; EMPTY-NEXT: Lines { -; EMPTY-NEXT: FileOffset: 0 +; EMPTY-NEXT: FileName: d:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp ; EMPTY-NEXT: Line { ; EMPTY-NEXT: Offset: 0 ; EMPTY-NEXT: LineNumberStart: 5 @@ -354,7 +354,7 @@ ; EMPTY-NEXT: } ; EMPTY-NEXT: FileChecksums { ; EMPTY-NEXT: Checksum { -; EMPTY-NEXT: FileNameOffset: 86 +; EMPTY-NEXT: FileName: d:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp ; EMPTY-NEXT: Kind: MD5 (0x1) ; EMPTY-NEXT: Checksum ( ; EMPTY-NEXT: 0000: A0A5BD0D 3ECD93FC 29D19DE8 26FBF4BC |....>...)...&...| diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp index dcaf494ee5c..1a9d5583486 100644 --- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -522,11 +522,19 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File, // substream types types. class RecordVisitor : public codeview::IModuleSubstreamVisitor { public: - RecordVisitor(ScopedPrinter &P) : P(P) {} + RecordVisitor(ScopedPrinter &P, PDBFile &F) : P(P), F(F) {} Error visitUnknown(ModuleSubstreamKind Kind, - StreamRef Data) override { + StreamRef Stream) override { DictScope DD(P, "Unknown"); - return printBinaryData(Data); + ArrayRef<uint8_t> Data; + StreamReader R(Stream); + if (auto EC = R.readBytes(Data, R.bytesRemaining())) { + return make_error<RawError>( + raw_error_code::corrupt_file, + "DBI stream contained corrupt line info record"); + } + P.printBinaryBlock("Data", Data); + return Error::success(); } Error visitFileChecksums(StreamRef Data, @@ -534,7 +542,11 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File, DictScope DD(P, "FileChecksums"); for (const auto &C : Checksums) { DictScope DDD(P, "Checksum"); - P.printNumber("FileNameOffset", C.FileNameOffset); + if (auto Result = getFileNameForOffset(C.FileNameOffset)) + P.printString("FileName", Result.get()); + else + return Result.takeError(); + P.flush(); P.printEnum("Kind", uint8_t(C.Kind), getFileChecksumNames()); P.printBinaryBlock("Checksum", C.Checksum); } @@ -545,7 +557,11 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File, const LineInfoArray &Lines) override { DictScope DD(P, "Lines"); for (const auto &L : Lines) { - P.printNumber("FileOffset", L.Offset); + if (auto Result = getFileNameForOffset2(L.NameIndex)) + P.printString("FileName", Result.get()); + else + return Result.takeError(); + P.flush(); for (const auto &N : L.LineNumbers) { DictScope DDD(P, "Line"); LineInfo LI(N.Flags); @@ -569,21 +585,25 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File, } private: - Error printBinaryData(StreamRef Stream) { - ArrayRef<uint8_t> Data; - StreamReader R(Stream); - if (auto EC = R.readBytes(Data, R.bytesRemaining())) { - return make_error<RawError>( - raw_error_code::corrupt_file, - "DBI stream contained corrupt line info record"); - } - P.printBinaryBlock("Data", Data); - P.flush(); - return Error::success(); + Expected<StringRef> getFileNameForOffset(uint32_t Offset) { + auto StringT = F.getStringTable(); + if (auto EC = StringT.takeError()) + return std::move(EC); + NameHashTable &ST = StringT.get(); + return ST.getStringForID(Offset); + } + Expected<StringRef> getFileNameForOffset2(uint32_t Offset) { + auto DbiS = F.getPDBDbiStream(); + if (auto EC = DbiS.takeError()) + return std::move(EC); + auto &DS = DbiS.get(); + return DS.getFileNameForIndex(Offset); } ScopedPrinter &P; + PDBFile &F; }; - RecordVisitor V(P); + + RecordVisitor V(P, File); for (const auto &L : ModS.lines(&HadError)) { if (auto EC = codeview::visitModuleSubstream(L, V)) return EC; |