[llvm] r270262 - pdbdump: print out symbol names referred by publics stream.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Fri May 20 12:55:17 PDT 2016


Author: ruiu
Date: Fri May 20 14:55:17 2016
New Revision: 270262

URL: http://llvm.org/viewvc/llvm-project?rev=270262&view=rev
Log:
pdbdump: print out symbol names referred by publics stream.

DBI stream contains a stream number of the symbol record stream.
Symbol record streams is an array of length-type-value members.
Each member represents one symbol.

Publics stream contains offsets to the symbol record stream.
This patch is to print out all symbols that are referenced by
the publics stream.

Note that even with this patch, llvm-pdbdump cannot dump all the
information in a publics stream since it contains more information
than symbol names. I'll improve it in followup patches.

Differential Revision: http://reviews.llvm.org/D20480

Added:
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h
    llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp
Modified:
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h
    llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
    llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
    llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp

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=270262&r1=270261&r2=270262&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h Fri May 20 14:55:17 2016
@@ -25,6 +25,7 @@ struct PDBFileContext;
 class DbiStream;
 class InfoStream;
 class PublicsStream;
+class SymbolStream;
 class TpiStream;
 
 class PDBFile {
@@ -64,6 +65,7 @@ public:
   Expected<DbiStream &> getPDBDbiStream();
   Expected<TpiStream &> getPDBTpiStream();
   Expected<PublicsStream &> getPDBPublicsStream();
+  Expected<SymbolStream &> getPDBSymbolStream();
 
 private:
   std::unique_ptr<PDBFileContext> Context;
@@ -71,6 +73,7 @@ private:
   std::unique_ptr<DbiStream> Dbi;
   std::unique_ptr<TpiStream> Tpi;
   std::unique_ptr<PublicsStream> Publics;
+  std::unique_ptr<SymbolStream> Symbols;
 };
 }
 }

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h?rev=270262&r1=270261&r2=270262&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h Fri May 20 14:55:17 2016
@@ -20,12 +20,13 @@
 
 namespace llvm {
 namespace pdb {
+class DbiStream;
 class PDBFile;
 
 class PublicsStream {
-  struct HeaderInfo;
   struct GSIHashHeader;
-  struct HRFile;
+  struct HashRecord;
+  struct HeaderInfo;
 
 public:
   PublicsStream(PDBFile &File, uint32_t StreamNum);
@@ -36,15 +37,21 @@ public:
   uint32_t getSymHash() const;
   uint32_t getAddrMap() const;
   uint32_t getNumBuckets() const { return NumBuckets; }
+  std::vector<std::string> getSymbols() const;
   ArrayRef<uint32_t> getHashBuckets() const { return HashBuckets; }
   ArrayRef<uint32_t> getAddressMap() const { return AddressMap; }
   ArrayRef<uint32_t> getThunkMap() const { return ThunkMap; }
   ArrayRef<uint32_t> getSectionOffsets() const { return SectionOffsets; }
 
 private:
+  Error readSymbols();
+
+  PDBFile &Pdb;
+
   uint32_t StreamNum;
   MappedBlockStream Stream;
   uint32_t NumBuckets = 0;
+  std::vector<HashRecord> HashRecords;
   std::vector<uint32_t> HashBuckets;
   std::vector<uint32_t> AddressMap;
   std::vector<uint32_t> ThunkMap;

Added: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h?rev=270262&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h Fri May 20 14:55:17 2016
@@ -0,0 +1,39 @@
+//===- SymbolStream.cpp - PDB Symbol Stream Access --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBSYMBOLSTREAM_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBSYMBOLSTREAM_H
+
+#include "llvm/DebugInfo/CodeView/TypeStream.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/DebugInfo/PDB/Raw/ByteStream.h"
+#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace pdb {
+class PDBFile;
+
+class SymbolStream {
+public:
+  SymbolStream(PDBFile &File, uint32_t StreamNum);
+  ~SymbolStream();
+  Error reload();
+
+  Expected<std::string> getSymbolName(uint32_t Offset) const;
+
+private:
+  MappedBlockStream Stream;
+};
+}
+}
+
+#endif

Modified: llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt?rev=270262&r1=270261&r2=270262&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt Fri May 20 14:55:17 2016
@@ -41,6 +41,7 @@ add_pdb_impl_folder(Raw
   Raw/RawError.cpp
   Raw/RawSession.cpp
   Raw/StreamReader.cpp
+  Raw/SymbolStream.cpp
   Raw/TpiStream.cpp)
 
 list(APPEND LIBPDB_ADDITIONAL_HEADER_DIRS "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB")

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=270262&r1=270261&r2=270262&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp Fri May 20 14:55:17 2016
@@ -13,6 +13,7 @@
 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
 #include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Raw/SymbolStream.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -307,3 +308,17 @@ Expected<PublicsStream &> PDBFile::getPD
   }
   return *Publics;
 }
+
+Expected<SymbolStream &> PDBFile::getPDBSymbolStream() {
+  if (!Symbols) {
+    auto DbiS = getPDBDbiStream();
+    if (auto EC = DbiS.takeError())
+      return std::move(EC);
+    uint32_t SymbolStreamNum = DbiS->getSymRecordStreamIndex();
+
+    Symbols.reset(new SymbolStream(*this, SymbolStreamNum));
+    if (auto EC = Symbols->reload())
+      return std::move(EC);
+  }
+  return *Symbols;
+}

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp?rev=270262&r1=270261&r2=270262&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp Fri May 20 14:55:17 2016
@@ -27,9 +27,11 @@
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
 #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
 #include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
+#include "llvm/DebugInfo/PDB/Raw/SymbolStream.h"
 
 #include "llvm/ADT/BitVector.h"
 #include "llvm/Support/Endian.h"
@@ -56,8 +58,7 @@ struct PublicsStream::HeaderInfo {
   ulittle32_t NumSections;
 };
 
-
-// This is GSIHashHdr struct defined in
+// This is GSIHashHdr.
 struct PublicsStream::GSIHashHeader {
   enum : unsigned {
     HdrSignature = ~0U,
@@ -69,8 +70,9 @@ struct PublicsStream::GSIHashHeader {
   ulittle32_t NumBuckets;
 };
 
-struct PublicsStream::HRFile {
-  ulittle32_t Off;
+// This is HRFile.
+struct PublicsStream::HashRecord {
+  ulittle32_t Off; // Offset in the symbol record stream
   ulittle32_t CRef;
 };
 
@@ -84,7 +86,7 @@ struct SectionOffset {
 }
 
 PublicsStream::PublicsStream(PDBFile &File, uint32_t StreamNum)
-    : StreamNum(StreamNum), Stream(StreamNum, File) {}
+    : Pdb(File), StreamNum(StreamNum), Stream(StreamNum, File) {}
 
 PublicsStream::~PublicsStream() {}
 
@@ -114,12 +116,12 @@ Error PublicsStream::reload() {
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Publics Stream does not contain a header.");
 
-  // An array of HRFile follows. Read them.
-  if (HashHdr->HrSize % sizeof(HRFile))
+  // An array of HashRecord follows. Read them.
+  if (HashHdr->HrSize % sizeof(HashRecord))
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Invalid HR array size.");
-  std::vector<HRFile> HRs(HashHdr->HrSize / sizeof(HRFile));
-  if (auto EC = Reader.readArray<HRFile>(HRs))
+  HashRecords.resize(HashHdr->HrSize / sizeof(HashRecord));
+  if (auto EC = Reader.readArray<HashRecord>(HashRecords))
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Could not read an HR array");
 
@@ -178,3 +180,20 @@ Error PublicsStream::reload() {
                                 "Corrupted publics stream.");
   return Error::success();
 }
+
+std::vector<std::string> PublicsStream::getSymbols() const {
+  auto SymbolS = Pdb.getPDBSymbolStream();
+  if (SymbolS.takeError())
+    return {};
+  SymbolStream &SS = SymbolS.get();
+
+  std::vector<std::string> Ret;
+  for (const HashRecord &HR : HashRecords) {
+    // For some reason, symbol offset is biased by one.
+    Expected<std::string> Name = SS.getSymbolName(HR.Off - 1);
+    if (Name.takeError())
+      return Ret;
+    Ret.push_back(std::move(Name.get()));
+  }
+  return Ret;
+}

Added: llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp?rev=270262&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp (added)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp Fri May 20 14:55:17 2016
@@ -0,0 +1,85 @@
+//===- SymbolStream.cpp - PDB Symbol Stream Access ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Raw/SymbolStream.h"
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
+
+#include "llvm/Support/Endian.h"
+
+using namespace llvm;
+using namespace llvm::support;
+using namespace llvm::pdb;
+
+// Symbol stream is an array of symbol records. Each record starts with
+// length and type fields followed by type-specfic fields.
+namespace {
+struct SymbolHeader {
+  ulittle16_t Len; // Record length
+  ulittle16_t Type;
+};
+
+// For S_PUB32 symbol type.
+struct DataSym32 {
+  ulittle32_t TypIndex; // Type index, or Metadata token if a managed symbol
+  ulittle32_t off;
+  ulittle16_t seg;
+  char name[1];
+};
+
+// For S_PROCREF symbol type.
+struct RefSym {
+  ulittle32_t SumName;   // SUC of the name (?)
+  ulittle32_t SymOffset; // Offset of actual symbol in $$Symbols
+  ulittle16_t Mod;       // Module containing the actual symbol
+  char name[1];
+};
+}
+
+SymbolStream::SymbolStream(PDBFile &File, uint32_t StreamNum)
+    : Stream(StreamNum, File) {}
+
+SymbolStream::~SymbolStream() {}
+
+Error SymbolStream::reload() { return Error::success(); }
+
+static StringRef makeStringRef(char *p) { return {p, strlen(p)}; }
+
+Expected<std::string> SymbolStream::getSymbolName(uint32_t Off) const {
+  StreamReader Reader(Stream);
+  Reader.setOffset(Off);
+
+  // Read length field.
+  SymbolHeader Hdr;
+  if (Reader.readObject(&Hdr))
+    return make_error<RawError>(raw_error_code::corrupt_file,
+                                "Corrupted symbol stream.");
+
+  // Read the entire record.
+  std::vector<uint8_t> Buf(Hdr.Len - sizeof(Hdr.Type));
+  if (Reader.readBytes(Buf))
+    return make_error<RawError>(raw_error_code::corrupt_file,
+                                "Corrupted symbol stream.");
+
+  switch (Hdr.Type) {
+  case codeview::S_PUB32:
+    return makeStringRef(reinterpret_cast<DataSym32 *>(Buf.data())->name);
+  case codeview::S_PROCREF:
+    return makeStringRef(reinterpret_cast<RefSym *>(Buf.data())->name);
+  default:
+    return make_error<RawError>(raw_error_code::corrupt_file,
+                                "Unknown symbol type");
+  }
+  return Error::success();
+}

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=270262&r1=270261&r2=270262&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test Fri May 20 14:55:17 2016
@@ -317,6 +317,7 @@
 ; EMPTY-NEXT:   Address Map: [36, 0]
 ; EMPTY-NEXT:   Thunk Map: [4112]
 ; EMPTY-NEXT:   Section Offsets: [4096, 1]
+; EMPTY-NEXT:   Symbols: [?__purecall@@3PAXA, _main]
 ; EMPTY-NEXT: }
 
 ; BIG:      FileHeaders {

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=270262&r1=270261&r2=270262&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Fri May 20 14:55:17 2016
@@ -415,6 +415,7 @@ static Error dumpPublicsStream(ScopedPri
   P.printList("Address Map", Publics.getAddressMap());
   P.printList("Thunk Map", Publics.getThunkMap());
   P.printList("Section Offsets", Publics.getSectionOffsets());
+  P.printList("Symbols", Publics.getSymbols());
   return Error::success();
 }
 




More information about the llvm-commits mailing list