diff options
author | Reid Kleckner <rnk@google.com> | 2017-07-26 00:40:36 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2017-07-26 00:40:36 +0000 |
commit | 14d90fd05cbed5fd3fcee492f072a4e5816f20b5 (patch) | |
tree | 53164d09de3887dbb7ef6d157766a9d9c801cc5d /llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp | |
parent | b4dbe7231e7eb1852248f6ed29fb57d9e9af06de (diff) | |
download | bcm5719-llvm-14d90fd05cbed5fd3fcee492f072a4e5816f20b5.tar.gz bcm5719-llvm-14d90fd05cbed5fd3fcee492f072a4e5816f20b5.zip |
[PDB] Improve GSI hash table dumping for publics and globals
The PDB "symbol stream" actually contains symbol records for the publics
and the globals stream. The globals and publics streams are essentially
hash tables that point into a single stream of records. In order to
match cvdump's behavior, we need to only dump symbol records referenced
from the hash table. This patch implements that, and then implements
global stream dumping, since it's just a subset of public stream
dumping.
Now we shouldn't see S_PROCREF or S_GDATA32 records when dumping
publics, and instead we should see those record in the globals stream.
llvm-svn: 309066
Diffstat (limited to 'llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp')
-rw-r--r-- | llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp | 112 |
1 files changed, 74 insertions, 38 deletions
diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp index 07fc38d4406..605fff92167 100644 --- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp +++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp @@ -49,6 +49,7 @@ #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/PublicsStream.h" +#include "llvm/DebugInfo/PDB/Native/SymbolStream.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" #include "llvm/DebugInfo/PDB/Native/TpiHashing.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" @@ -129,6 +130,11 @@ Error DumpOutputStyle::dump() { return EC; } + if (opts::dump::DumpGlobals) { + if (auto EC = dumpGlobals()) + return EC; + } + if (opts::dump::DumpPublics) { if (auto EC = dumpPublics()) return EC; @@ -851,58 +857,38 @@ Error DumpOutputStyle::dumpModuleSyms() { return Error::success(); } +Error DumpOutputStyle::dumpGlobals() { + printHeader(P, "Global Symbols"); + AutoIndent Indent(P); + if (!File.hasPDBGlobalsStream()) { + P.formatLine("Globals stream not present"); + return Error::success(); + } + ExitOnError Err("Error dumping globals stream"); + auto &Globals = Err(File.getPDBGlobalsStream()); + + const GSIHashTable &Table = Globals.getGlobalsTable(); + Err(dumpSymbolsFromGSI(Table, opts::dump::DumpGlobalExtras)); + return Error::success(); +} + Error DumpOutputStyle::dumpPublics() { printHeader(P, "Public Symbols"); - AutoIndent Indent(P); if (!File.hasPDBPublicsStream()) { P.formatLine("Publics stream not present"); return Error::success(); } - ExitOnError Err("Error dumping publics stream"); - - auto &Types = Err(initializeTypes(StreamTPI)); auto &Publics = Err(File.getPDBPublicsStream()); - SymbolVisitorCallbackPipeline Pipeline; - SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb); - MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, Types); - Pipeline.addCallbackToPipeline(Deserializer); - Pipeline.addCallbackToPipeline(Dumper); - CVSymbolVisitor Visitor(Pipeline); - - auto ExpectedSymbols = Publics.getSymbolArray(); - if (!ExpectedSymbols) { - P.formatLine("Could not read public symbol record stream"); - return Error::success(); - } - - if (auto EC = Visitor.visitSymbolStream(*ExpectedSymbols, 0)) - P.formatLine("Error while processing public symbol records. {0}", - toString(std::move(EC))); + const GSIHashTable &PublicsTable = Publics.getPublicsTable(); + Err(dumpSymbolsFromGSI(PublicsTable, opts::dump::DumpPublicExtras)); - // Return early if we aren't dumping public hash table and address map info. + // Skip the rest if we aren't dumping extras. if (!opts::dump::DumpPublicExtras) return Error::success(); - P.formatLine("Hash Records"); - { - AutoIndent Indent2(P); - for (const PSHashRecord &HR : Publics.getHashRecords()) - P.formatLine("off = {0}, refcnt = {1}", uint32_t(HR.Off), - uint32_t(HR.CRef)); - } - - // FIXME: Dump the bitmap. - - P.formatLine("Hash Buckets"); - { - AutoIndent Indent2(P); - for (uint32_t Hash : Publics.getHashBuckets()) - P.formatLine("{0:x8}", Hash); - } - P.formatLine("Address Map"); { // These are offsets into the publics stream sorted by secidx:secrel. @@ -931,6 +917,56 @@ Error DumpOutputStyle::dumpPublics() { return Error::success(); } +Error DumpOutputStyle::dumpSymbolsFromGSI(const GSIHashTable &Table, + bool HashExtras) { + auto ExpectedSyms = File.getPDBSymbolStream(); + if (!ExpectedSyms) + return ExpectedSyms.takeError(); + auto ExpectedTypes = initializeTypes(StreamTPI); + if (!ExpectedTypes) + return ExpectedTypes.takeError(); + SymbolVisitorCallbackPipeline Pipeline; + SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb); + MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, *ExpectedTypes); + + Pipeline.addCallbackToPipeline(Deserializer); + Pipeline.addCallbackToPipeline(Dumper); + CVSymbolVisitor Visitor(Pipeline); + + BinaryStreamRef SymStream = + ExpectedSyms->getSymbolArray().getUnderlyingStream(); + for (uint32_t PubSymOff : Table) { + Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, PubSymOff); + if (!Sym) + return Sym.takeError(); + if (auto E = Visitor.visitSymbolRecord(*Sym, PubSymOff)) + return E; + } + + // Return early if we aren't dumping public hash table and address map info. + if (!HashExtras) + return Error::success(); + + P.formatLine("Hash Records"); + { + AutoIndent Indent2(P); + for (const PSHashRecord &HR : Table.HashRecords) + P.formatLine("off = {0}, refcnt = {1}", uint32_t(HR.Off), + uint32_t(HR.CRef)); + } + + // FIXME: Dump the bitmap. + + P.formatLine("Hash Buckets"); + { + AutoIndent Indent2(P); + for (uint32_t Hash : Table.HashBuckets) + P.formatLine("{0:x8}", Hash); + } + + return Error::success(); +} + static std::string formatSectionCharacteristics(uint32_t IndentLevel, uint32_t C) { using SC = COFF::SectionCharacteristics; |