]> granicus.if.org Git - llvm/commitdiff
[LLD/PDB] Write actual records to the globals stream.
authorZachary Turner <zturner@google.com>
Fri, 11 Aug 2017 19:00:03 +0000 (19:00 +0000)
committerZachary Turner <zturner@google.com>
Fri, 11 Aug 2017 19:00:03 +0000 (19:00 +0000)
Previously we were writing an empty globals stream.  Windows
tools interpret this as "private symbols are not present in
this PDB", even when they are, so we need to fix this.  Regardless,
without it we don't have information about global variables, so
we need to fix it anyway.  This patch does that.

With this patch, the "lm" command in WinDbg correctly reports
that we have private symbols available, but the "dv" command
still refuses to display local variables.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310743 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/CodeView/RecordName.h [moved from include/llvm/DebugInfo/CodeView/TypeName.h with 65% similarity]
include/llvm/DebugInfo/CodeView/TypeDeserializer.h
include/llvm/DebugInfo/CodeView/TypeRecord.h
include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h
lib/DebugInfo/CodeView/CMakeLists.txt
lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
lib/DebugInfo/CodeView/RecordName.cpp [moved from lib/DebugInfo/CodeView/TypeName.cpp with 76% similarity]
lib/DebugInfo/CodeView/TypeTableCollection.cpp
lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp

similarity index 65%
rename from include/llvm/DebugInfo/CodeView/TypeName.h
rename to include/llvm/DebugInfo/CodeView/RecordName.h
index a987b4afd283a528d2f4ad55560c1e92fec8242d..b022108df3d653dd25426802bd1c7679c65fa88d 100644 (file)
@@ -1,4 +1,4 @@
-//===- TypeName.h --------------------------------------------- *- C++ --*-===//
+//===- RecordName.h ------------------------------------------- *- C++ --*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,16 +7,18 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H
-#define LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H
+#ifndef LLVM_DEBUGINFO_CODEVIEW_RECORDNAME_H
+#define LLVM_DEBUGINFO_CODEVIEW_RECORDNAME_H
 
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
 #include "llvm/DebugInfo/CodeView/TypeCollection.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 
 namespace llvm {
 namespace codeview {
 std::string computeTypeName(TypeCollection &Types, TypeIndex Index);
-}
+StringRef getSymbolName(CVSymbol Sym);
+} // namespace codeview
 } // namespace llvm
 
 #endif
index 23d4f8a5e179cb5d4df9f895dcef1bbc26253849..9887d901773a05bec70453973c8a2d5ca85468e6 100644 (file)
@@ -54,14 +54,12 @@ public:
 
   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);
+    CVType CVT(static_cast<TypeLeafKind>(K), Data);
     if (auto EC = deserializeAs<T>(CVT, Record))
       return std::move(EC);
     return Record;
index 7942c0c0bc2153c7dffc57f9f508a8fca5e8dba8..f61f4f3717c92d5e75c7e13f24e1da1e5d13153b 100644 (file)
@@ -412,6 +412,10 @@ public:
     return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
   }
 
+  bool isNested() const {
+    return (Options & ClassOptions::Nested) != ClassOptions::None;
+  }
+
   uint16_t getMemberCount() const { return MemberCount; }
   ClassOptions getOptions() const { return Options; }
   TypeIndex getFieldList() const { return FieldList; }
index 2cacf9b7ff1debd9e9436f9d91fe258436c4c288..1a4f89d607dffd9d55a66e1654a7e2f9eb17228d 100644 (file)
@@ -58,6 +58,12 @@ public:
 
   void addPublicSymbol(const codeview::PublicSym32 &Pub);
 
+  void addGlobalSymbol(const codeview::ProcRefSym &Sym);
+  void addGlobalSymbol(const codeview::DataSym &Sym);
+  void addGlobalSymbol(const codeview::ConstantSym &Sym);
+  void addGlobalSymbol(const codeview::UDTSym &Sym);
+  void addGlobalSymbol(const codeview::CVSymbol &Sym);
+
 private:
   uint32_t calculatePublicsHashStreamSize() const;
   uint32_t calculateGlobalsHashStreamSize() const;
index b94bb0c80c7936b75a78e3be87b1e27573f88ba0..b0cefe64fddf337d1575d099e427429f75059d6f 100644 (file)
@@ -19,6 +19,7 @@ add_llvm_library(LLVMDebugInfoCodeView
   Formatters.cpp
   LazyRandomTypeCollection.cpp
   Line.cpp
+  RecordName.cpp
   RecordSerialization.cpp
   StringsAndChecksums.cpp
   SymbolRecordMapping.cpp
@@ -27,7 +28,6 @@ add_llvm_library(LLVMDebugInfoCodeView
   TypeDumpVisitor.cpp
   TypeIndex.cpp
   TypeIndexDiscovery.cpp
-  TypeName.cpp
   TypeRecordMapping.cpp
   TypeSerializer.cpp
   TypeStreamMerger.cpp
index 5aaf3f1453a8f521bcea5620489beb1a7791f1b0..6db921ed93958be8be6f2525de5fdc25d66a7f13 100644 (file)
@@ -13,7 +13,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/TypeName.h"
+#include "llvm/DebugInfo/CodeView/RecordName.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
 #include "llvm/Support/BinaryStreamReader.h"
 #include "llvm/Support/Endian.h"
similarity index 76%
rename from lib/DebugInfo/CodeView/TypeName.cpp
rename to lib/DebugInfo/CodeView/RecordName.cpp
index 2eb8b81862f3c4a8a5dceaf327bbf67d117e0b88..15fb1724d23d4e1f58f95422ae97bf762093a9f4 100644 (file)
@@ -1,4 +1,4 @@
-//===- TypeName.cpp ------------------------------------------- *- C++ --*-===//
+//===- RecordName.cpp ----------------------------------------- *- C++ --*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,10 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/DebugInfo/CodeView/TypeName.h"
+#include "llvm/DebugInfo/CodeView/RecordName.h"
 
 #include "llvm/ADT/SmallString.h"
+#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
 #include "llvm/Support/FormatVariadic.h"
 
@@ -241,3 +243,78 @@ std::string llvm::codeview::computeTypeName(TypeCollection &Types,
   }
   return Computer.name();
 }
+
+static int getSymbolNameOffset(CVSymbol Sym) {
+  switch (Sym.kind()) {
+  // See ProcSym
+  case SymbolKind::S_GPROC32:
+  case SymbolKind::S_LPROC32:
+  case SymbolKind::S_GPROC32_ID:
+  case SymbolKind::S_LPROC32_ID:
+  case SymbolKind::S_LPROC32_DPC:
+  case SymbolKind::S_LPROC32_DPC_ID:
+    return 35;
+  // See Thunk32Sym
+  case SymbolKind::S_THUNK32:
+    return 21;
+  // See SectionSym
+  case SymbolKind::S_SECTION:
+    return 16;
+  // See CoffGroupSym
+  case SymbolKind::S_COFFGROUP:
+    return 14;
+  // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym
+  case SymbolKind::S_PUB32:
+  case SymbolKind::S_FILESTATIC:
+  case SymbolKind::S_REGREL32:
+  case SymbolKind::S_GDATA32:
+  case SymbolKind::S_LDATA32:
+  case SymbolKind::S_LMANDATA:
+  case SymbolKind::S_GMANDATA:
+  case SymbolKind::S_LTHREAD32:
+  case SymbolKind::S_GTHREAD32:
+    return 10;
+  // See RegisterSym and LocalSym
+  case SymbolKind::S_REGISTER:
+  case SymbolKind::S_LOCAL:
+    return 6;
+  // See BlockSym
+  case SymbolKind::S_BLOCK32:
+    return 18;
+  // See LabelSym
+  case SymbolKind::S_LABEL32:
+    return 7;
+  // See ObjNameSym, ExportSym, and UDTSym
+  case SymbolKind::S_OBJNAME:
+  case SymbolKind::S_EXPORT:
+  case SymbolKind::S_UDT:
+    return 4;
+  // See BPRelativeSym
+  case SymbolKind::S_BPREL32:
+    return 8;
+  default:
+    return -1;
+  }
+}
+
+StringRef llvm::codeview::getSymbolName(CVSymbol Sym) {
+  if (Sym.kind() == SymbolKind::S_CONSTANT) {
+    // S_CONSTANT is preceded by an APSInt, which has a variable length.  So we
+    // have to do a full deserialization.
+    BinaryStreamReader Reader(Sym.content(), llvm::support::little);
+    // The container doesn't matter for single records.
+    SymbolRecordMapping Mapping(Reader, CodeViewContainer::ObjectFile);
+    ConstantSym Const(SymbolKind::S_CONSTANT);
+    cantFail(Mapping.visitSymbolBegin(Sym));
+    cantFail(Mapping.visitKnownRecord(Sym, Const));
+    cantFail(Mapping.visitSymbolEnd(Sym));
+    return Const.Name;
+  }
+
+  int Offset = getSymbolNameOffset(Sym);
+  if (Offset == -1)
+    return StringRef();
+
+  StringRef StringData = toStringRef(Sym.content()).drop_front(Offset);
+  return StringData.split('\0').first;
+}
index 4eca5aeaa0ae33169b993b4534c2075e0e965e49..456d6f19b237edefec86578fec8fd82eff82dd05 100644 (file)
@@ -10,7 +10,7 @@
 #include "llvm/DebugInfo/CodeView/TypeTableCollection.h"
 
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/TypeName.h"
+#include "llvm/DebugInfo/CodeView/RecordName.h"
 #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
 #include "llvm/Support/BinaryByteStream.h"
 #include "llvm/Support/BinaryStreamReader.h"
index 46951a0b88e9541840bf698361ece825e3f68dcf..7c88748da80d87e044b750498f27d52c794ea3ae 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
 
+#include "llvm/DebugInfo/CodeView/RecordName.h"
 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
@@ -27,13 +28,6 @@ using namespace llvm::msf;
 using namespace llvm::pdb;
 using namespace llvm::codeview;
 
-static StringRef getSymbolName(const CVSymbol &Sym) {
-  assert(Sym.kind() == S_PUB32 && "handle other kinds");
-  PublicSym32 PSL =
-      cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym));
-  return PSL.Name;
-}
-
 struct llvm::pdb::GSIHashStreamBuilder {
   std::vector<CVSymbol> Records;
   uint32_t StreamIndex;
@@ -45,6 +39,13 @@ struct llvm::pdb::GSIHashStreamBuilder {
   uint32_t calculateRecordByteSize() const;
   Error commit(BinaryStreamWriter &Writer);
   void finalizeBuckets(uint32_t RecordZeroOffset);
+
+  template <typename T> void addSymbol(const T &Symbol, MSFBuilder &Msf) {
+    T Copy(Symbol);
+    Records.push_back(SymbolSerializer::writeOneSymbol(Copy, Msf.getAllocator(),
+                                                       CodeViewContainer::Pdb));
+  }
+  void addSymbol(const CVSymbol &Symbol) { Records.push_back(Symbol); }
 };
 
 uint32_t GSIHashStreamBuilder::calculateSerializedLength() const {
@@ -222,9 +223,27 @@ uint32_t GSIStreamBuilder::getGlobalsStreamIndex() const {
 }
 
 void GSIStreamBuilder::addPublicSymbol(const PublicSym32 &Pub) {
-  PublicSym32 Copy(Pub);
-  PSH->Records.push_back(SymbolSerializer::writeOneSymbol(
-      Copy, Msf.getAllocator(), CodeViewContainer::Pdb));
+  PSH->addSymbol(Pub, Msf);
+}
+
+void GSIStreamBuilder::addGlobalSymbol(const ProcRefSym &Sym) {
+  GSH->addSymbol(Sym, Msf);
+}
+
+void GSIStreamBuilder::addGlobalSymbol(const DataSym &Sym) {
+  GSH->addSymbol(Sym, Msf);
+}
+
+void GSIStreamBuilder::addGlobalSymbol(const ConstantSym &Sym) {
+  GSH->addSymbol(Sym, Msf);
+}
+
+void GSIStreamBuilder::addGlobalSymbol(const UDTSym &Sym) {
+  GSH->addSymbol(Sym, Msf);
+}
+
+void GSIStreamBuilder::addGlobalSymbol(const codeview::CVSymbol &Sym) {
+  GSH->addSymbol(Sym);
 }
 
 static Error writeRecords(BinaryStreamWriter &Writer,