From: Zachary Turner Date: Fri, 11 Aug 2017 19:00:03 +0000 (+0000) Subject: [LLD/PDB] Write actual records to the globals stream. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e3e384aef78b419032c1a47109c05620766d092c;p=llvm [LLD/PDB] Write actual records to the globals stream. 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 --- diff --git a/include/llvm/DebugInfo/CodeView/TypeName.h b/include/llvm/DebugInfo/CodeView/RecordName.h similarity index 65% rename from include/llvm/DebugInfo/CodeView/TypeName.h rename to include/llvm/DebugInfo/CodeView/RecordName.h index a987b4afd28..b022108df3d 100644 --- a/include/llvm/DebugInfo/CodeView/TypeName.h +++ b/include/llvm/DebugInfo/CodeView/RecordName.h @@ -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 diff --git a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h index 23d4f8a5e17..9887d901773 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h +++ b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h @@ -54,14 +54,12 @@ public: template static Expected deserializeAs(ArrayRef Data) { - CVType CVT; - CVT.RecordData = Data; - MappingInfo I(CVT.content()); const RecordPrefix *Prefix = reinterpret_cast(Data.data()); TypeRecordKind K = static_cast(uint16_t(Prefix->RecordKind)); T Record(K); + CVType CVT(static_cast(K), Data); if (auto EC = deserializeAs(CVT, Record)) return std::move(EC); return Record; diff --git a/include/llvm/DebugInfo/CodeView/TypeRecord.h b/include/llvm/DebugInfo/CodeView/TypeRecord.h index 7942c0c0bc2..f61f4f3717c 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -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; } diff --git a/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h index 2cacf9b7ff1..1a4f89d607d 100644 --- a/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h @@ -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; diff --git a/lib/DebugInfo/CodeView/CMakeLists.txt b/lib/DebugInfo/CodeView/CMakeLists.txt index b94bb0c80c7..b0cefe64fdd 100644 --- a/lib/DebugInfo/CodeView/CMakeLists.txt +++ b/lib/DebugInfo/CodeView/CMakeLists.txt @@ -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 diff --git a/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp b/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp index 5aaf3f1453a..6db921ed939 100644 --- a/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp +++ b/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp @@ -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" diff --git a/lib/DebugInfo/CodeView/TypeName.cpp b/lib/DebugInfo/CodeView/RecordName.cpp similarity index 76% rename from lib/DebugInfo/CodeView/TypeName.cpp rename to lib/DebugInfo/CodeView/RecordName.cpp index 2eb8b81862f..15fb1724d23 100644 --- a/lib/DebugInfo/CodeView/TypeName.cpp +++ b/lib/DebugInfo/CodeView/RecordName.cpp @@ -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; +} diff --git a/lib/DebugInfo/CodeView/TypeTableCollection.cpp b/lib/DebugInfo/CodeView/TypeTableCollection.cpp index 4eca5aeaa0a..456d6f19b23 100644 --- a/lib/DebugInfo/CodeView/TypeTableCollection.cpp +++ b/lib/DebugInfo/CodeView/TypeTableCollection.cpp @@ -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" diff --git a/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp index 46951a0b88e..7c88748da80 100644 --- a/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp @@ -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(Sym)); - return PSL.Name; -} - struct llvm::pdb::GSIHashStreamBuilder { std::vector 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 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,