From 5d57752c8113d443789d0b9f72d5a96bb6e60b4a Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Fri, 24 Mar 2017 17:26:38 +0000 Subject: [PDB] Split item and type records when merging type streams Summary: MSVC does this when producing a PDB. Reviewers: ruiu Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D31316 llvm-svn: 298717 --- llvm/tools/llvm-readobj/COFFDumper.cpp | 49 ++++++++++++++++++++++++-------- llvm/tools/llvm-readobj/ObjDumper.h | 6 ++-- llvm/tools/llvm-readobj/llvm-readobj.cpp | 10 ++++--- 3 files changed, 47 insertions(+), 18 deletions(-) (limited to 'llvm/tools/llvm-readobj') diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index 263f66617f9..10427654167 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -79,7 +79,8 @@ public: void printCOFFBaseReloc() override; void printCOFFDebugDirectory() override; void printCodeViewDebugInfo() override; - void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVTypes) override; + void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVIDs, + llvm::codeview::TypeTableBuilder &CVTypes) override; void printStackMap() const override; private: void printSymbol(const SymbolRef &Sym); @@ -1064,7 +1065,8 @@ void COFFDumper::printFileNameForOffset(StringRef Label, uint32_t FileOffset) { W.printHex(Label, getFileNameForFileOffset(FileOffset), FileOffset); } -void COFFDumper::mergeCodeViewTypes(TypeTableBuilder &CVTypes) { +void COFFDumper::mergeCodeViewTypes(TypeTableBuilder &CVIDs, + TypeTableBuilder &CVTypes) { for (const SectionRef &S : Obj->sections()) { StringRef SectionName; error(S.getName(SectionName)); @@ -1086,7 +1088,7 @@ void COFFDumper::mergeCodeViewTypes(TypeTableBuilder &CVTypes) { error(object_error::parse_failed); } - if (auto EC = mergeTypeStreams(CVTypes, nullptr, Types)) { + if (auto EC = mergeTypeStreams(CVIDs, CVTypes, nullptr, Types)) { consumeError(std::move(EC)); return error(object_error::parse_failed); } @@ -1551,20 +1553,43 @@ void COFFDumper::printStackMap() const { } void llvm::dumpCodeViewMergedTypes(ScopedPrinter &Writer, + llvm::codeview::TypeTableBuilder &IDTable, llvm::codeview::TypeTableBuilder &CVTypes) { // Flatten it first, then run our dumper on it. - ListScope S(Writer, "MergedTypeStream"); - SmallString<0> Buf; + SmallString<0> TypeBuf; CVTypes.ForEachRecord([&](TypeIndex TI, ArrayRef Record) { - Buf.append(Record.begin(), Record.end()); + TypeBuf.append(Record.begin(), Record.end()); }); TypeDatabase TypeDB; - CVTypeDumper CVTD(TypeDB); - TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes); - if (auto EC = - CVTD.dump({Buf.str().bytes_begin(), Buf.str().bytes_end()}, TDV)) { - Writer.flush(); - error(llvm::errorToErrorCode(std::move(EC))); + { + ListScope S(Writer, "MergedTypeStream"); + CVTypeDumper CVTD(TypeDB); + TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes); + if (auto EC = CVTD.dump( + {TypeBuf.str().bytes_begin(), TypeBuf.str().bytes_end()}, TDV)) { + Writer.flush(); + error(llvm::errorToErrorCode(std::move(EC))); + } + } + + // Flatten the id stream and print it next. The ID stream refers to names from + // the type stream. + SmallString<0> IDBuf; + IDTable.ForEachRecord([&](TypeIndex TI, ArrayRef Record) { + IDBuf.append(Record.begin(), Record.end()); + }); + + { + ListScope S(Writer, "MergedIDStream"); + TypeDatabase IDDB; + CVTypeDumper CVTD(IDDB); + TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes); + TDV.setItemDB(IDDB); + if (auto EC = CVTD.dump( + {IDBuf.str().bytes_begin(), IDBuf.str().bytes_end()}, TDV)) { + Writer.flush(); + error(llvm::errorToErrorCode(std::move(EC))); + } } } diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h index 109087be79b..ff780dae578 100644 --- a/llvm/tools/llvm-readobj/ObjDumper.h +++ b/llvm/tools/llvm-readobj/ObjDumper.h @@ -68,7 +68,8 @@ public: virtual void printCOFFBaseReloc() { } virtual void printCOFFDebugDirectory() { } virtual void printCodeViewDebugInfo() { } - virtual void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVTypes) {} + virtual void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVIDs, + llvm::codeview::TypeTableBuilder &CVTypes) {} // Only implemented for MachO. virtual void printMachODataInCode() { } @@ -103,7 +104,8 @@ std::error_code createWasmDumper(const object::ObjectFile *Obj, void dumpCOFFImportFile(const object::COFFImportFile *File); void dumpCodeViewMergedTypes(ScopedPrinter &Writer, - llvm::codeview::TypeTableBuilder &CVTypes); + llvm::codeview::TypeTableBuilder &IDTable, + llvm::codeview::TypeTableBuilder &TypeTable); } // namespace llvm diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index d9178285751..bc2a62e799a 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -338,10 +338,12 @@ static bool isMipsArch(unsigned Arch) { } namespace { struct ReadObjTypeTableBuilder { - ReadObjTypeTableBuilder() : Allocator(), Builder(Allocator) {} + ReadObjTypeTableBuilder() + : Allocator(), IDTable(Allocator), TypeTable(Allocator) {} llvm::BumpPtrAllocator Allocator; - llvm::codeview::TypeTableBuilder Builder; + llvm::codeview::TypeTableBuilder IDTable; + llvm::codeview::TypeTableBuilder TypeTable; }; } static ReadObjTypeTableBuilder CVTypes; @@ -446,7 +448,7 @@ static void dumpObject(const ObjectFile *Obj) { if (opts::CodeView) Dumper->printCodeViewDebugInfo(); if (opts::CodeViewMergedTypes) - Dumper->mergeCodeViewTypes(CVTypes.Builder); + Dumper->mergeCodeViewTypes(CVTypes.IDTable, CVTypes.TypeTable); } if (Obj->isMachO()) { if (opts::MachODataInCode) @@ -551,7 +553,7 @@ int main(int argc, const char *argv[]) { if (opts::CodeViewMergedTypes) { ScopedPrinter W(outs()); - dumpCodeViewMergedTypes(W, CVTypes.Builder); + dumpCodeViewMergedTypes(W, CVTypes.IDTable, CVTypes.TypeTable); } return 0; -- cgit v1.2.3