[llvm] r310394 - [PDB] Fix linking of function symbols and local variables.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 8 11:34:45 PDT 2017


Author: zturner
Date: Tue Aug  8 11:34:44 2017
New Revision: 310394

URL: http://llvm.org/viewvc/llvm-project?rev=310394&view=rev
Log:
[PDB] Fix linking of function symbols and local variables.

The compiler outputs PROC32_ID symbols into the object files
for functions, and these symbols have an embedded type index
which, when copied to the PDB, refer to the IPI stream.  However,
the symbols themselves are also converted into regular symbols
(e.g. S_GPROC32_ID -> S_GPROC32), and type indices in the regular
symbol records refer to the TPI stream.  So this patch applies
two fixes to function records.
  1. It converts ID symbols to the proper non-ID record type.
  2. After remapping the type index from the object file's index
     space to the PDB file/IPI stream's index space, it then
     remaps that index to the TPI stream's index space by.

Besides functions, during the remapping process we were also
discarding symbol record types which we did not recognize.
In particular, we were discarding S_BPREL32 records, which is
what MSVC uses to describe local variables on the stack.  So
this patch fixes that as well by copying them to the PDB.

Differential Revision: https://reviews.llvm.org/D36426

Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
    llvm/trunk/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
    llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
    llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.h
    llvm/trunk/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h?rev=310394&r1=310393&r2=310394&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h Tue Aug  8 11:34:44 2017
@@ -52,6 +52,21 @@ public:
     return Error::success();
   }
 
+  template <typename T>
+  static Expected<T> deserializeAs(ArrayRef<uint8_t> Data) {
+    CVType CVT;
+    CVT.RecordData = Data;
+    MappingInfo I(CVT.content());
+    const RecordPrefix *Prefix =
+        reinterpret_cast<const RecordPrefix *>(Data.data());
+    TypeRecordKind K =
+        static_cast<TypeRecordKind>(uint16_t(Prefix->RecordKind));
+    T Record(K);
+    if (auto EC = deserializeAs<T>(CVT, Record))
+      return std::move(EC);
+    return Record;
+  }
+
   Error visitTypeBegin(CVType &Record) override {
     assert(!Mapping && "Already in a type mapping!");
     Mapping = llvm::make_unique<MappingInfo>(Record.content());

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h?rev=310394&r1=310393&r2=310394&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h Tue Aug  8 11:34:44 2017
@@ -30,11 +30,17 @@ void discoverTypeIndices(const CVType &T
                          SmallVectorImpl<TiReference> &Refs);
 void discoverTypeIndices(const CVType &Type,
                          SmallVectorImpl<TypeIndex> &Indices);
+void discoverTypeIndices(ArrayRef<uint8_t> RecordData,
+                         SmallVectorImpl<TypeIndex> &Indices);
 
 /// Discover type indices in symbol records. Returns false if this is an unknown
 /// record.
-bool discoverTypeIndices(const CVSymbol &Symbol,
-                         SmallVectorImpl<TiReference> &Refs);
+bool discoverTypeIndicesInSymbol(const CVSymbol &Symbol,
+                                 SmallVectorImpl<TiReference> &Refs);
+bool discoverTypeIndicesInSymbol(ArrayRef<uint8_t> RecordData,
+                                 SmallVectorImpl<TiReference> &Refs);
+bool discoverTypeIndicesInSymbol(ArrayRef<uint8_t> RecordData,
+                                 SmallVectorImpl<TypeIndex> &Indices);
 }
 }
 

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp?rev=310394&r1=310393&r2=310394&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp Tue Aug  8 11:34:44 2017
@@ -395,6 +395,7 @@ static bool discoverTypeIndices(ArrayRef
   case SymbolKind::S_CONSTANT:
     Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
     break;
+  case SymbolKind::S_BPREL32:
   case SymbolKind::S_REGREL32:
     Refs.push_back({TiRefKind::TypeRef, 4, 1}); // Type
     break;
@@ -450,17 +451,17 @@ void llvm::codeview::discoverTypeIndices
   ::discoverTypeIndices(Type.content(), Type.kind(), Refs);
 }
 
-void llvm::codeview::discoverTypeIndices(const CVType &Type,
-                                         SmallVectorImpl<TypeIndex> &Indices) {
-
+static void resolveTypeIndexReferences(ArrayRef<uint8_t> RecordData,
+                                       ArrayRef<TiReference> Refs,
+                                       SmallVectorImpl<TypeIndex> &Indices) {
   Indices.clear();
 
-  SmallVector<TiReference, 4> Refs;
-  discoverTypeIndices(Type, Refs);
   if (Refs.empty())
     return;
 
-  BinaryStreamReader Reader(Type.content(), support::little);
+  RecordData = RecordData.drop_front(sizeof(RecordPrefix));
+
+  BinaryStreamReader Reader(RecordData, support::little);
   for (const auto &Ref : Refs) {
     Reader.setOffset(Ref.Offset);
     FixedStreamArray<TypeIndex> Run;
@@ -469,6 +470,18 @@ void llvm::codeview::discoverTypeIndices
   }
 }
 
+void llvm::codeview::discoverTypeIndices(const CVType &Type,
+                                         SmallVectorImpl<TypeIndex> &Indices) {
+  return discoverTypeIndices(Type.RecordData, Indices);
+}
+
+void llvm::codeview::discoverTypeIndices(ArrayRef<uint8_t> RecordData,
+                                         SmallVectorImpl<TypeIndex> &Indices) {
+  SmallVector<TiReference, 4> Refs;
+  discoverTypeIndices(RecordData, Refs);
+  resolveTypeIndexReferences(RecordData, Refs, Indices);
+}
+
 void llvm::codeview::discoverTypeIndices(ArrayRef<uint8_t> RecordData,
                                          SmallVectorImpl<TiReference> &Refs) {
   const RecordPrefix *P =
@@ -477,8 +490,26 @@ void llvm::codeview::discoverTypeIndices
   ::discoverTypeIndices(RecordData.drop_front(sizeof(RecordPrefix)), K, Refs);
 }
 
-bool llvm::codeview::discoverTypeIndices(const CVSymbol &Sym,
-                                         SmallVectorImpl<TiReference> &Refs) {
+bool llvm::codeview::discoverTypeIndicesInSymbol(
+    const CVSymbol &Sym, SmallVectorImpl<TiReference> &Refs) {
   SymbolKind K = Sym.kind();
   return ::discoverTypeIndices(Sym.content(), K, Refs);
 }
+
+bool llvm::codeview::discoverTypeIndicesInSymbol(
+    ArrayRef<uint8_t> RecordData, SmallVectorImpl<TiReference> &Refs) {
+  const RecordPrefix *P =
+      reinterpret_cast<const RecordPrefix *>(RecordData.data());
+  SymbolKind K = static_cast<SymbolKind>(uint16_t(P->RecordKind));
+  return ::discoverTypeIndices(RecordData.drop_front(sizeof(RecordPrefix)), K,
+                               Refs);
+}
+
+bool llvm::codeview::discoverTypeIndicesInSymbol(
+    ArrayRef<uint8_t> RecordData, SmallVectorImpl<TypeIndex> &Indices) {
+  SmallVector<TiReference, 2> Refs;
+  if (!discoverTypeIndicesInSymbol(RecordData, Refs))
+    return false;
+  resolveTypeIndexReferences(RecordData, Refs, Indices);
+  return true;
+}

Modified: llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp?rev=310394&r1=310393&r2=310394&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp Tue Aug  8 11:34:44 2017
@@ -837,6 +837,7 @@ Error DumpOutputStyle::dumpModuleSyms()
 
   ExitOnError Err("Unexpected error processing symbols: ");
 
+  auto &Ids = Err(initializeTypes(StreamIPI));
   auto &Types = Err(initializeTypes(StreamTPI));
 
   iterateModules(
@@ -852,7 +853,8 @@ Error DumpOutputStyle::dumpModuleSyms()
 
         SymbolVisitorCallbackPipeline Pipeline;
         SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
-        MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, Types);
+        MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, Ids,
+                                   Types);
 
         Pipeline.addCallbackToPipeline(Deserializer);
         Pipeline.addCallbackToPipeline(Dumper);
@@ -936,9 +938,13 @@ Error DumpOutputStyle::dumpSymbolsFromGS
   auto ExpectedTypes = initializeTypes(StreamTPI);
   if (!ExpectedTypes)
     return ExpectedTypes.takeError();
+  auto ExpectedIds = initializeTypes(StreamIPI);
+  if (!ExpectedIds)
+    return ExpectedIds.takeError();
   SymbolVisitorCallbackPipeline Pipeline;
   SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
-  MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, *ExpectedTypes);
+  MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, *ExpectedIds,
+                             *ExpectedTypes);
 
   Pipeline.addCallbackToPipeline(Deserializer);
   Pipeline.addCallbackToPipeline(Dumper);

Modified: llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp?rev=310394&r1=310393&r2=310394&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp Tue Aug  8 11:34:44 2017
@@ -389,10 +389,12 @@ Error MinimalSymbolDumper::visitSymbolEn
   return Error::success();
 }
 
-std::string MinimalSymbolDumper::typeIndex(TypeIndex TI) const {
+std::string MinimalSymbolDumper::typeOrIdIndex(codeview::TypeIndex TI,
+                                               bool IsType) const {
   if (TI.isSimple())
     return formatv("{0}", TI).str();
-  StringRef Name = Types.getTypeName(TI);
+  auto &Container = IsType ? Types : Ids;
+  StringRef Name = Container.getTypeName(TI);
   if (Name.size() > 32) {
     Name = Name.take_front(32);
     return formatv("{0} ({1}...)", TI, Name);
@@ -400,6 +402,14 @@ std::string MinimalSymbolDumper::typeInd
     return formatv("{0} ({1})", TI, Name);
 }
 
+std::string MinimalSymbolDumper::idIndex(codeview::TypeIndex TI) const {
+  return typeOrIdIndex(TI, false);
+}
+
+std::string MinimalSymbolDumper::typeIndex(TypeIndex TI) const {
+  return typeOrIdIndex(TI, true);
+}
+
 Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
   P.format(" `{0}`", Block.Name);
   AutoIndent Indent(P, 7);
@@ -727,9 +737,19 @@ Error MinimalSymbolDumper::visitKnownRec
                Proc.Parent, Proc.End,
                formatSegmentOffset(Proc.Segment, Proc.CodeOffset),
                Proc.CodeSize);
-  // FIXME: It seems FunctionType is sometimes an id and sometimes a type.
+  bool IsType = true;
+  switch (Proc.getKind()) {
+  case SymbolRecordKind::GlobalProcIdSym:
+  case SymbolRecordKind::ProcIdSym:
+  case SymbolRecordKind::DPCProcIdSym:
+    IsType = false;
+    break;
+  default:
+    break;
+  }
   P.formatLine("type = `{0}`, debug start = {1}, debug end = {2}, flags = {3}",
-               typeIndex(Proc.FunctionType), Proc.DbgStart, Proc.DbgEnd,
+               typeOrIdIndex(Proc.FunctionType, IsType), Proc.DbgStart,
+               Proc.DbgEnd,
                formatProcSymFlags(P.getIndentLevel() + 9, Proc.Flags));
   return Error::success();
 }

Modified: llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.h?rev=310394&r1=310393&r2=310394&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.h Tue Aug  8 11:34:44 2017
@@ -23,8 +23,9 @@ class LinePrinter;
 class MinimalSymbolDumper : public codeview::SymbolVisitorCallbacks {
 public:
   MinimalSymbolDumper(LinePrinter &P, bool RecordBytes,
+                      codeview::LazyRandomTypeCollection &Ids,
                       codeview::LazyRandomTypeCollection &Types)
-      : P(P), Types(Types) {}
+      : P(P), Ids(Ids), Types(Types) {}
 
   Error visitSymbolBegin(codeview::CVSymbol &Record) override;
   Error visitSymbolBegin(codeview::CVSymbol &Record, uint32_t Offset) override;
@@ -37,9 +38,13 @@ public:
 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
 
 private:
+  std::string typeOrIdIndex(codeview::TypeIndex TI, bool IsType) const;
+
   std::string typeIndex(codeview::TypeIndex TI) const;
+  std::string idIndex(codeview::TypeIndex TI) const;
 
   LinePrinter &P;
+  codeview::LazyRandomTypeCollection &Ids;
   codeview::LazyRandomTypeCollection &Types;
 };
 } // namespace pdb

Modified: llvm/trunk/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp?rev=310394&r1=310393&r2=310394&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp Tue Aug  8 11:34:44 2017
@@ -131,7 +131,7 @@ private:
   void discoverTypeIndicesInSymbols() {
     Refs.resize(Symbols.size());
     for (uint32_t I = 0; I < Symbols.size(); ++I)
-      discoverTypeIndices(Symbols[I], Refs[I]);
+      discoverTypeIndicesInSymbol(Symbols[I], Refs[I]);
   }
 
   // Helper function to write out a field list record with the given list




More information about the llvm-commits mailing list