llvm.org GIT mirror llvm / f7d0c1f
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271630 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 4 years ago
11 changed file(s) with 105 addition(s) and 37 deletion(s). Raw diff Collapse all Expand all
141141 };
142142
143143 struct FileChecksum {
144 ulittle32_t FileNameOffset; // Offset of filename in string table substream.
145 uint8_t ChecksumSize;
146 uint8_t ChecksumKind; // FileChecksumKind
144 ulittle32_t FileNameOffset; // Byte offset of filename in global string table.
145 uint8_t ChecksumSize; // Number of bytes of checksum.
146 uint8_t ChecksumKind; // FileChecksumKind
147147 // Checksum bytes follow.
148148 };
149149
3434
3535 // Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
3636 struct LineFileBlockHeader {
37 support::ulittle32_t FileOffset;
37 support::ulittle32_t NameIndex; // Index in DBI name buffer of filename.
3838 support::ulittle32_t NumLines; // Number of lines
3939 support::ulittle32_t BlockSize; // Code size of block, in bytes.
4040 // The following two variable length arrays appear immediately after the
2020 namespace codeview {
2121
2222 struct LineColumnEntry {
23 support::ulittle32_t Offset;
23 support::ulittle32_t NameIndex;
2424 FixedStreamArray LineNumbers;
2525 FixedStreamArray Columns;
2626 };
4949 // The value recorded in BlockHeader->BlockSize includes the size of
5050 // LineFileBlockHeader.
5151 Len = BlockHeader->BlockSize;
52 Item.Offset = BlockHeader->FileOffset;
52 Item.NameIndex = BlockHeader->NameIndex;
5353 if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines))
5454 return EC;
5555 if (HasColumn) {
6464 };
6565
6666 struct FileChecksumEntry {
67 uint32_t FileNameOffset;
68 FileChecksumKind Kind;
69 ArrayRef Checksum;
67 uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
68 FileChecksumKind Kind; // The type of checksum.
69 ArrayRef Checksum; // The bytes of the checksum.
7070 };
7171
7272 template <> class VarStreamArrayExtractor {
6060
6161 ArrayRef modules() const;
6262
63 Expected getFileNameForIndex(uint32_t Index) const;
64
6365 codeview::FixedStreamArray getSectionHeaders();
6466
6567 codeview::FixedStreamArray getSectionMap() const;
8486 codeview::StreamRef TypeServerMapSubstream;
8587 codeview::StreamRef ECSubstream;
8688
89 codeview::StreamRef NamesBuffer;
90
8791 codeview::FixedStreamArray DbgStreams;
8892
8993 PdbRaw_DbiSecContribVer SectionContribVersion;
9094 codeview::FixedStreamArray SectionContribs;
9195 codeview::FixedStreamArray SectionContribs2;
9296 codeview::FixedStreamArray SectionMap;
97 codeview::FixedStreamArray FileNameOffsets;
9398
9499 std::unique_ptr SectionHeaderStream;
95100 codeview::FixedStreamArray SectionHeaders;
2424 struct PDBFileContext;
2525 class DbiStream;
2626 class InfoStream;
27 class MappedBlockStream;
28 class NameHashTable;
2729 class PublicsStream;
2830 class SymbolStream;
2931 class TpiStream;
6870 Expected getPDBIpiStream();
6971 Expected getPDBPublicsStream();
7072 Expected getPDBSymbolStream();
73 Expected getStringTable();
7174
7275 private:
7376 std::unique_ptr Context;
7780 std::unique_ptr Ipi;
7881 std::unique_ptr Publics;
7982 std::unique_ptr Symbols;
83 std::unique_ptr StringTableStream;
84 std::unique_ptr StringTable;
8085 };
8186 }
8287 }
2020 feature_unsupported,
2121 corrupt_file,
2222 insufficient_buffer,
23 no_stream,
24 index_out_of_bounds
2325 };
2426
2527 /// Base class for errors originating when parsing raw PDB files
344344
345345 FixedStreamArray ModIndexArray;
346346 FixedStreamArray ModFileCountArray;
347 FixedStreamArray FileNameOffsets;
348347
349348 // First is an array of `NumModules` module indices. This is not used for the
350349 // same reason that `NumSourceFiles` is not used. It's an array of uint16's,
372371 if (auto EC = FISR.readArray(FileNameOffsets, NumSourceFiles))
373372 return EC;
374373
375 StreamRef NamesBufferRef;
376 if (auto EC = FISR.readStreamRef(NamesBufferRef))
377 return EC;
378 StreamReader Names(NamesBufferRef);
374 if (auto EC = FISR.readStreamRef(NamesBuffer))
375 return EC;
379376
380377 // We go through each ModuleInfo, determine the number N of source files for
381378 // that module, and then get the next N offsets from the Offsets array, using
386383 uint32_t NumFiles = ModFileCountArray[I];
387384 ModuleInfos[I].SourceFiles.resize(NumFiles);
388385 for (size_t J = 0; J < NumFiles; ++J, ++NextFileIndex) {
389 uint32_t FileOffset = FileNameOffsets[NextFileIndex];
390 Names.setOffset(FileOffset);
391 if (auto EC = Names.readZeroString(ModuleInfos[I].SourceFiles[J]))
392 return EC;
386 if (auto Name = getFileNameForIndex(NextFileIndex))
387 ModuleInfos[I].SourceFiles[J] = Name.get();
388 else
389 return Name.takeError();
393390 }
394391 }
395392
399396 uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const {
400397 return DbgStreams[static_cast(Type)];
401398 }
399
400 Expected DbiStream::getFileNameForIndex(uint32_t Index) const {
401 StreamReader Names(NamesBuffer);
402 if (Index >= FileNameOffsets.size())
403 return make_error(raw_error_code::index_out_of_bounds);
404
405 uint32_t FileOffset = FileNameOffsets[Index];
406 Names.setOffset(FileOffset);
407 StringRef Name;
408 if (auto EC = Names.readZeroString(Name))
409 return std::move(EC);
410 return Name;
411 }
1010 #include "llvm/ADT/ArrayRef.h"
1111 #include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
1212 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
13 #include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
1314 #include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
1415 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
1516 #include "llvm/DebugInfo/PDB/Raw/SymbolStream.h"
358359 }
359360 return *Symbols;
360361 }
362
363 Expected PDBFile::getStringTable() {
364 if (!StringTable || !StringTableStream) {
365 auto InfoS = getPDBInfoStream();
366 if (auto EC = InfoS.takeError())
367 return std::move(EC);
368 auto &IS = InfoS.get();
369 uint32_t NameStreamIndex = IS.getNamedStreamIndex("/names");
370
371 if (NameStreamIndex == 0)
372 return make_error(raw_error_code::no_stream);
373 auto S = llvm::make_unique(NameStreamIndex, *this);
374 codeview::StreamReader Reader(*S);
375 auto N = llvm::make_unique();
376 if (auto EC = N->load(Reader))
377 return std::move(EC);
378 StringTable = std::move(N);
379 StringTableStream = std::move(S);
380 }
381 return *StringTable;
382 }
2323 case raw_error_code::insufficient_buffer:
2424 return "The buffer is not large enough to read the requested number of "
2525 "bytes.";
26 case raw_error_code::no_stream:
27 return "The specified stream could not be loaded.";
28 case raw_error_code::index_out_of_bounds:
29 return "The specified item does not exist in the array.";
2630 }
2731 llvm_unreachable("Unrecognized raw_error_code");
2832 }
331331 ; EMPTY-NEXT: ]
332332 ; EMPTY-NEXT: LineInfo [
333333 ; EMPTY-NEXT: Lines {
334 ; EMPTY-NEXT: FileOffset: 0
334 ; EMPTY-NEXT: FileName: d:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp
335335 ; EMPTY-NEXT: Line {
336336 ; EMPTY-NEXT: Offset: 0
337337 ; EMPTY-NEXT: LineNumberStart: 5
353353 ; EMPTY-NEXT: }
354354 ; EMPTY-NEXT: FileChecksums {
355355 ; EMPTY-NEXT: Checksum {
356 ; EMPTY-NEXT: FileNameOffset: 86
356 ; EMPTY-NEXT: FileName: d:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp
357357 ; EMPTY-NEXT: Kind: MD5 (0x1)
358358 ; EMPTY-NEXT: Checksum (
359359 ; EMPTY-NEXT: 0000: A0A5BD0D 3ECD93FC 29D19DE8 26FBF4BC |....>...)...&...|
521521 // substream types types.
522522 class RecordVisitor : public codeview::IModuleSubstreamVisitor {
523523 public:
524 RecordVisitor(ScopedPrinter &P) : P(P) {}
524 RecordVisitor(ScopedPrinter &P, PDBFile &F) : P(P), F(F) {}
525525 Error visitUnknown(ModuleSubstreamKind Kind,
526 StreamRef Data) override {
526 StreamRef Stream) override {
527527 DictScope DD(P, "Unknown");
528 return printBinaryData(Data);
528 ArrayRef Data;
529 StreamReader R(Stream);
530 if (auto EC = R.readBytes(Data, R.bytesRemaining())) {
531 return make_error(
532 raw_error_code::corrupt_file,
533 "DBI stream contained corrupt line info record");
534 }
535 P.printBinaryBlock("Data", Data);
536 return Error::success();
529537 }
530538 Error
531539 visitFileChecksums(StreamRef Data,
533541 DictScope DD(P, "FileChecksums");
534542 for (const auto &C : Checksums) {
535543 DictScope DDD(P, "Checksum");
536 P.printNumber("FileNameOffset", C.FileNameOffset);
544 if (auto Result = getFileNameForOffset(C.FileNameOffset))
545 P.printString("FileName", Result.get());
546 else
547 return Result.takeError();
548 P.flush();
537549 P.printEnum("Kind", uint8_t(C.Kind), getFileChecksumNames());
538550 P.printBinaryBlock("Checksum", C.Checksum);
539551 }
544556 const LineInfoArray &Lines) override {
545557 DictScope DD(P, "Lines");
546558 for (const auto &L : Lines) {
547 P.printNumber("FileOffset", L.Offset);
559 if (auto Result = getFileNameForOffset2(L.NameIndex))
560 P.printString("FileName", Result.get());
561 else
562 return Result.takeError();
563 P.flush();
548564 for (const auto &N : L.LineNumbers) {
549565 DictScope DDD(P, "Line");
550566 LineInfo LI(N.Flags);
568584 }
569585
570586 private:
571 Error printBinaryData(StreamRef Stream) {
572 ArrayRef Data;
573 StreamReader R(Stream);
574 if (auto EC = R.readBytes(Data, R.bytesRemaining())) {
575 return make_error(
576 raw_error_code::corrupt_file,
577 "DBI stream contained corrupt line info record");
578 }
579 P.printBinaryBlock("Data", Data);
580 P.flush();
581 return Error::success();
587 Expected getFileNameForOffset(uint32_t Offset) {
588 auto StringT = F.getStringTable();
589 if (auto EC = StringT.takeError())
590 return std::move(EC);
591 NameHashTable &ST = StringT.get();
592 return ST.getStringForID(Offset);
593 }
594 Expected getFileNameForOffset2(uint32_t Offset) {
595 auto DbiS = F.getPDBDbiStream();
596 if (auto EC = DbiS.takeError())
597 return std::move(EC);
598 auto &DS = DbiS.get();
599 return DS.getFileNameForIndex(Offset);
582600 }
583601 ScopedPrinter &P;
602 PDBFile &F;
584603 };
585 RecordVisitor V(P);
604
605 RecordVisitor V(P, File);
586606 for (const auto &L : ModS.lines(&HadError)) {
587607 if (auto EC = codeview::visitModuleSubstream(L, V))
588608 return EC;