summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2017-07-26 00:40:36 +0000
committerReid Kleckner <rnk@google.com>2017-07-26 00:40:36 +0000
commit14d90fd05cbed5fd3fcee492f072a4e5816f20b5 (patch)
tree53164d09de3887dbb7ef6d157766a9d9c801cc5d /llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
parentb4dbe7231e7eb1852248f6ed29fb57d9e9af06de (diff)
downloadbcm5719-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.cpp112
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;
OpenPOWER on IntegriCloud