[llvm] r271630 - [pdb] Print out file names instead of file offsets.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 2 22:52:57 PDT 2016


Author: zturner
Date: Fri Jun  3 00:52:57 2016
New Revision: 271630

URL: http://llvm.org/viewvc/llvm-project?rev=271630&view=rev
Log:
[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.

Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawError.h
    llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/RawError.cpp
    llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h?rev=271630&r1=271629&r2=271630&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h Fri Jun  3 00:52:57 2016
@@ -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.
 };
 

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h?rev=271630&r1=271629&r2=271630&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h Fri Jun  3 00:52:57 2016
@@ -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

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h?rev=271630&r1=271629&r2=271630&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h Fri Jun  3 00:52:57 2016
@@ -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> {

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h?rev=271630&r1=271629&r2=271630&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h Fri Jun  3 00:52:57 2016
@@ -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;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h?rev=271630&r1=271629&r2=271630&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h Fri Jun  3 00:52:57 2016
@@ -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;
 };
 }
 }

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawError.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawError.h?rev=271630&r1=271629&r2=271630&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawError.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawError.h Fri Jun  3 00:52:57 2016
@@ -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

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp?rev=271630&r1=271629&r2=271630&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp Fri Jun  3 00:52:57 2016
@@ -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;
+}

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp?rev=271630&r1=271629&r2=271630&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp Fri Jun  3 00:52:57 2016
@@ -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::getPDB
   }
   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;
+}

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/RawError.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/RawError.cpp?rev=271630&r1=271629&r2=271630&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/RawError.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/RawError.cpp Fri Jun  3 00:52:57 2016
@@ -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");
   }

Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test?rev=271630&r1=271629&r2=271630&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test Fri Jun  3 00:52:57 2016
@@ -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  |....>...)...&...|

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=271630&r1=271629&r2=271630&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Fri Jun  3 00:52:57 2016
@@ -522,11 +522,19 @@ static Error dumpDbiStream(ScopedPrinter
           // 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
               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
                              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
             }
 
           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;




More information about the llvm-commits mailing list