From: Zachary Turner Date: Fri, 5 Jan 2018 19:12:40 +0000 (+0000) Subject: [PDB] Correctly link S_FILESTATIC records. X-Git-Tag: android-x86-7.1-r4~6597 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=d9e5a1f6b3f871baa0d222430679b3fd1b647abc;p=android-x86%2Fexternal-llvm.git [PDB] Correctly link S_FILESTATIC records. This is not a record type that clang currently generates, but it is a record that is encountered in object files generated by cl. This record is unusual in that it refers directly to the string table instead of indirectly to the string table via the FileChecksums table. Because of this, it was previously overlooked and we weren't remapping the string indices at all. This would lead to crashes in MSVC when trying to display a variable whose debug info involved an S_FILESTATIC. Original bug report by Alexander Ganea Differential Revision: https://reviews.llvm.org/D41718 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321883 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/tools/llvm-pdbutil/DumpOutputStyle.cpp b/tools/llvm-pdbutil/DumpOutputStyle.cpp index dd8436728ba..365386f0a27 100644 --- a/tools/llvm-pdbutil/DumpOutputStyle.cpp +++ b/tools/llvm-pdbutil/DumpOutputStyle.cpp @@ -848,14 +848,7 @@ Error DumpOutputStyle::dumpXme() { return Error::success(); } -Error DumpOutputStyle::dumpStringTable() { - printHeader(P, "String Table"); - - if (File.isObj()) { - P.formatLine("Dumping string table is not supported for object files"); - return Error::success(); - } - +Error DumpOutputStyle::dumpStringTableFromPdb() { AutoIndent Indent(P); auto IS = getPdb().getStringTable(); if (!IS) { @@ -895,6 +888,36 @@ Error DumpOutputStyle::dumpStringTable() { return Error::success(); } +Error DumpOutputStyle::dumpStringTableFromObj() { + iterateModuleSubsections( + File, PrintScope{P, 4}, + [&](uint32_t Modi, const SymbolGroup &Strings, + DebugStringTableSubsectionRef &Strings2) { + BinaryStreamRef StringTableBuffer = Strings2.getBuffer(); + BinaryStreamReader Reader(StringTableBuffer); + while (Reader.bytesRemaining() > 0) { + StringRef Str; + uint32_t Offset = Reader.getOffset(); + cantFail(Reader.readCString(Str)); + if (Str.empty()) + continue; + + P.formatLine("{0} | {1}", fmt_align(Offset, AlignStyle::Right, 4), + Str); + } + }); + return Error::success(); +} + +Error DumpOutputStyle::dumpStringTable() { + printHeader(P, "String Table"); + + if (File.isPdb()) + return dumpStringTableFromPdb(); + + return dumpStringTableFromObj(); +} + static void buildDepSet(LazyRandomTypeCollection &Types, ArrayRef Indices, std::map &DepSet) { @@ -1124,6 +1147,7 @@ Error DumpOutputStyle::dumpModuleSymsForObj() { File, PrintScope{P, 2}, [&](uint32_t Modi, const SymbolGroup &Strings, DebugSymbolsSubsectionRef &Symbols) { + Dumper.setSymbolGroup(&Strings); for (auto Symbol : Symbols) { if (auto EC = Visitor.visitSymbolRecord(Symbol)) { SymbolError = llvm::make_unique(std::move(EC)); @@ -1165,8 +1189,8 @@ Error DumpOutputStyle::dumpModuleSymsForPdb() { SymbolVisitorCallbackPipeline Pipeline; SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb); - MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, Ids, - Types); + MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, Strings, + Ids, Types); Pipeline.addCallbackToPipeline(Deserializer); Pipeline.addCallbackToPipeline(Dumper); diff --git a/tools/llvm-pdbutil/DumpOutputStyle.h b/tools/llvm-pdbutil/DumpOutputStyle.h index 3ce2884b271..fad304c470c 100644 --- a/tools/llvm-pdbutil/DumpOutputStyle.h +++ b/tools/llvm-pdbutil/DumpOutputStyle.h @@ -75,6 +75,8 @@ private: Error dumpSymbolStats(); Error dumpUdtStats(); Error dumpStringTable(); + Error dumpStringTableFromPdb(); + Error dumpStringTableFromObj(); Error dumpLines(); Error dumpInlineeLines(); Error dumpXmi(); diff --git a/tools/llvm-pdbutil/MinimalSymbolDumper.cpp b/tools/llvm-pdbutil/MinimalSymbolDumper.cpp index 40a0e46efd4..b454ab34545 100644 --- a/tools/llvm-pdbutil/MinimalSymbolDumper.cpp +++ b/tools/llvm-pdbutil/MinimalSymbolDumper.cpp @@ -10,6 +10,7 @@ #include "MinimalSymbolDumper.h" #include "FormatUtil.h" +#include "InputFile.h" #include "LinePrinter.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" @@ -18,6 +19,7 @@ #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" #include "llvm/Support/FormatVariadic.h" using namespace llvm; @@ -450,6 +452,17 @@ Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FileStaticSym &FS) { P.format(" `{0}`", FS.Name); AutoIndent Indent(P, 7); + if (SymGroup) { + Expected FileName = + SymGroup->getNameFromStringTable(FS.ModFilenameOffset); + if (FileName) { + P.formatLine("type = {0}, file name = {1} ({2}), flags = {3}", + typeIndex(FS.Index), FS.ModFilenameOffset, *FileName, + formatLocalSymFlags(P.getIndentLevel() + 9, FS.Flags)); + } + return Error::success(); + } + P.formatLine("type = {0}, file name offset = {1}, flags = {2}", typeIndex(FS.Index), FS.ModFilenameOffset, formatLocalSymFlags(P.getIndentLevel() + 9, FS.Flags)); diff --git a/tools/llvm-pdbutil/MinimalSymbolDumper.h b/tools/llvm-pdbutil/MinimalSymbolDumper.h index d9e9861d5b3..1c26a85a4ea 100644 --- a/tools/llvm-pdbutil/MinimalSymbolDumper.h +++ b/tools/llvm-pdbutil/MinimalSymbolDumper.h @@ -19,6 +19,7 @@ class LazyRandomTypeCollection; namespace pdb { class LinePrinter; +class SymbolGroup; class MinimalSymbolDumper : public codeview::SymbolVisitorCallbacks { public: @@ -26,11 +27,19 @@ public: codeview::LazyRandomTypeCollection &Ids, codeview::LazyRandomTypeCollection &Types) : P(P), RecordBytes(RecordBytes), Ids(Ids), Types(Types) {} + MinimalSymbolDumper(LinePrinter &P, bool RecordBytes, + const SymbolGroup &SymGroup, + codeview::LazyRandomTypeCollection &Ids, + codeview::LazyRandomTypeCollection &Types) + : P(P), RecordBytes(RecordBytes), SymGroup(&SymGroup), Ids(Ids), + Types(Types) {} Error visitSymbolBegin(codeview::CVSymbol &Record) override; Error visitSymbolBegin(codeview::CVSymbol &Record, uint32_t Offset) override; Error visitSymbolEnd(codeview::CVSymbol &Record) override; + void setSymbolGroup(const SymbolGroup *Group) { SymGroup = Group; } + #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ virtual Error visitKnownRecord(codeview::CVSymbol &CVR, \ codeview::Name &Record) override; @@ -45,6 +54,7 @@ private: LinePrinter &P; bool RecordBytes; + const SymbolGroup *SymGroup = nullptr; codeview::LazyRandomTypeCollection &Ids; codeview::LazyRandomTypeCollection &Types; };