summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2017-12-05 23:58:18 +0000
committerZachary Turner <zturner@google.com>2017-12-05 23:58:18 +0000
commit7c192eec2ff17d1815f0c3eef28e0846eeb0ba84 (patch)
tree064b960711b6e8c2471fe8baed33b47fc32a9e08 /tools
parent0b3e8d4de32497018fd24aa2c0fea1fef6aafaab (diff)
Teach llvm-pdbutil to dump types from object files.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319859 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r--tools/llvm-pdbutil/DumpOutputStyle.cpp101
-rw-r--r--tools/llvm-pdbutil/DumpOutputStyle.h1
-rw-r--r--tools/llvm-readobj/COFFDumper.cpp1
3 files changed, 81 insertions, 22 deletions
diff --git a/tools/llvm-pdbutil/DumpOutputStyle.cpp b/tools/llvm-pdbutil/DumpOutputStyle.cpp
index 5b02d68bc7a..84355e7bd2e 100644
--- a/tools/llvm-pdbutil/DumpOutputStyle.cpp
+++ b/tools/llvm-pdbutil/DumpOutputStyle.cpp
@@ -38,6 +38,7 @@
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeHashing.h"
#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
@@ -50,8 +51,8 @@
#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/SymbolStream.h"
#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
@@ -135,16 +136,23 @@ Error DumpOutputStyle::dump() {
return EC;
}
- if (opts::dump::DumpTypes || !opts::dump::DumpTypeIndex.empty() ||
- opts::dump::DumpTypeExtras) {
- if (auto EC = dumpTpiStream(StreamTPI))
- return EC;
- }
+ if (File.isObj()) {
+ if (opts::dump::DumpTypes || !opts::dump::DumpTypeIndex.empty() ||
+ opts::dump::DumpTypeExtras)
+ if (auto EC = dumpTypesFromObjectFile())
+ return EC;
+ } else {
+ if (opts::dump::DumpTypes || !opts::dump::DumpTypeIndex.empty() ||
+ opts::dump::DumpTypeExtras) {
+ if (auto EC = dumpTpiStream(StreamTPI))
+ return EC;
+ }
- if (opts::dump::DumpIds || !opts::dump::DumpIdIndex.empty() ||
- opts::dump::DumpIdExtras) {
- if (auto EC = dumpTpiStream(StreamIPI))
- return EC;
+ if (opts::dump::DumpIds || !opts::dump::DumpIdIndex.empty() ||
+ opts::dump::DumpIdExtras) {
+ if (auto EC = dumpTpiStream(StreamIPI))
+ return EC;
+ }
}
if (opts::dump::DumpGlobals) {
@@ -913,15 +921,17 @@ static void buildDepSet(LazyRandomTypeCollection &Types,
}
}
-static void dumpFullTypeStream(LinePrinter &Printer,
- LazyRandomTypeCollection &Types,
- TpiStream &Stream, bool Bytes, bool Extras) {
- Printer.formatLine("Showing {0:N} records", Stream.getNumTypeRecords());
- uint32_t Width =
- NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords());
+static void
+dumpFullTypeStream(LinePrinter &Printer, LazyRandomTypeCollection &Types,
+ uint32_t NumHashBuckets,
+ FixedStreamArray<support::ulittle32_t> HashValues,
+ bool Bytes, bool Extras) {
+
+ Printer.formatLine("Showing {0:N} records", Types.size());
+ uint32_t Width = NumDigits(TypeIndex::FirstNonSimpleIndex + Types.size());
MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types,
- Stream.getNumHashBuckets(), Stream.getHashValues());
+ NumHashBuckets, HashValues);
if (auto EC = codeview::visitTypeStream(Types, V)) {
Printer.formatLine("An error occurred dumping type records: {0}",
@@ -967,6 +977,55 @@ static void dumpPartialTypeStream(LinePrinter &Printer,
}
}
+Error DumpOutputStyle::dumpTypesFromObjectFile() {
+ LazyRandomTypeCollection Types(100);
+
+ for (const auto &S : getObj().sections()) {
+ StringRef SectionName;
+ if (auto EC = S.getName(SectionName))
+ return errorCodeToError(EC);
+
+ if (SectionName != ".debug$T")
+ continue;
+ StringRef Contents;
+ if (auto EC = S.getContents(Contents))
+ return errorCodeToError(EC);
+
+ uint32_t Magic;
+ BinaryStreamReader Reader(Contents, llvm::support::little);
+ if (auto EC = Reader.readInteger(Magic))
+ return EC;
+ if (Magic != COFF::DEBUG_SECTION_MAGIC)
+ return make_error<StringError>("Invalid CodeView debug section.",
+ inconvertibleErrorCode());
+
+ Types.reset(Reader, 100);
+
+ if (opts::dump::DumpTypes) {
+ dumpFullTypeStream(P, Types, 0, {}, opts::dump::DumpTypeData, false);
+ } else if (opts::dump::DumpTypeExtras) {
+ auto LocalHashes = LocallyHashedType::hashTypeCollection(Types);
+ auto GlobalHashes = GloballyHashedType::hashTypeCollection(Types);
+ assert(LocalHashes.size() == GlobalHashes.size());
+
+ P.formatLine("Local / Global hashes:");
+ TypeIndex TI(TypeIndex::FirstNonSimpleIndex);
+ for (const auto &H : zip(LocalHashes, GlobalHashes)) {
+ AutoIndent Indent2(P);
+ LocallyHashedType &L = std::get<0>(H);
+ GloballyHashedType &G = std::get<1>(H);
+
+ P.formatLine("TI: {0}, LocalHash: {1:X}, GlobalHash: {2}", TI, L, G);
+
+ ++TI;
+ }
+ P.NewLine();
+ }
+ }
+
+ return Error::success();
+}
+
Error DumpOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
assert(StreamIdx == StreamTPI || StreamIdx == StreamIPI);
@@ -977,10 +1036,7 @@ Error DumpOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
}
AutoIndent Indent(P);
- if (File.isObj()) {
- P.formatLine("Dumping types is not supported for object files");
- return Error::success();
- }
+ assert(!File.isObj());
bool Present = false;
bool DumpTypes = false;
@@ -1017,7 +1073,8 @@ Error DumpOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
if (DumpTypes || !Indices.empty()) {
if (Indices.empty())
- dumpFullTypeStream(P, Types, Stream, DumpBytes, DumpExtras);
+ dumpFullTypeStream(P, Types, Stream.getNumHashBuckets(),
+ Stream.getHashValues(), DumpBytes, DumpExtras);
else {
std::vector<TypeIndex> TiList(Indices.begin(), Indices.end());
dumpPartialTypeStream(P, Types, Stream, TiList, DumpBytes, DumpExtras,
diff --git a/tools/llvm-pdbutil/DumpOutputStyle.h b/tools/llvm-pdbutil/DumpOutputStyle.h
index 85598307863..3ce2884b271 100644
--- a/tools/llvm-pdbutil/DumpOutputStyle.h
+++ b/tools/llvm-pdbutil/DumpOutputStyle.h
@@ -80,6 +80,7 @@ private:
Error dumpXmi();
Error dumpXme();
Error dumpTpiStream(uint32_t StreamIdx);
+ Error dumpTypesFromObjectFile();
Error dumpModules();
Error dumpModuleFiles();
Error dumpModuleSymsForPdb();
diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp
index ca2a9ec1615..0c7f7db5760 100644
--- a/tools/llvm-readobj/COFFDumper.cpp
+++ b/tools/llvm-readobj/COFFDumper.cpp
@@ -38,6 +38,7 @@
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeHashing.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"