diff options
author | Zachary Turner <zturner@google.com> | 2017-05-18 23:03:06 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2017-05-18 23:03:06 +0000 |
commit | 0c60f269fcbb9b6ebba0897ed5fc9ea6ac271038 (patch) | |
tree | 73c17db87837f286a112f7415481ff60b45c94d9 /llvm/tools/llvm-readobj/COFFDumper.cpp | |
parent | 86bf0a874c0b2cf56bd8c1493e98ef6c11a0ebd4 (diff) | |
download | bcm5719-llvm-0c60f269fcbb9b6ebba0897ed5fc9ea6ac271038.tar.gz bcm5719-llvm-0c60f269fcbb9b6ebba0897ed5fc9ea6ac271038.zip |
[CodeView] Provide a common interface for type collections.
Right now we have multiple notions of things that represent collections of
types. Most commonly used are TypeDatabase, which is supposed to keep
mappings from TypeIndex to type name when reading a type stream, which
happens when reading PDBs. And also TypeTableBuilder, which is used to
build up a collection of types dynamically which we will later serialize
(i.e. when writing PDBs).
But often you just want to do some operation on a collection of types, and
you may want to do the same operation on any kind of collection. For
example, you might want to merge two TypeTableBuilders or you might want
to merge two type streams that you loaded from various files.
This dichotomy between reading and writing is responsible for a lot of the
existing code duplication and overlapping responsibilities in the existing
CodeView library classes. For example, after building up a
TypeTableBuilder with a bunch of type records, if we want to dump it we
have to re-invent a bunch of extra glue because our dumper takes a
TypeDatabase or a CVTypeArray, which are both incompatible with
TypeTableBuilder.
This patch introduces an abstract base class called TypeCollection which
is shared between the various type collection like things. Wherever we
previously stored a TypeDatabase& in some common class, we now store a
TypeCollection&.
The advantage of this is that all the details of how the collection are
implemented, such as lazy deserialization of partial type streams, is
completely transparent and you can just treat any collection of types the
same regardless of where it came from.
Differential Revision: https://reviews.llvm.org/D33293
llvm-svn: 303388
Diffstat (limited to 'llvm/tools/llvm-readobj/COFFDumper.cpp')
-rw-r--r-- | llvm/tools/llvm-readobj/COFFDumper.cpp | 60 |
1 files changed, 24 insertions, 36 deletions
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index e76c345d7b1..0cf964a49cd 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -22,8 +22,9 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/DebugInfo/CodeView/CVTypeDumper.h" +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h" #include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h" @@ -34,18 +35,20 @@ #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h" #include "llvm/DebugInfo/CodeView/SymbolDumper.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/CodeView/TypeDatabase.h" #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/DebugInfo/CodeView/TypeTableCollection.h" #include "llvm/Object/COFF.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/COFF.h" -#include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ConvertUTF.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" @@ -70,7 +73,7 @@ class COFFDumper : public ObjDumper { public: friend class COFFObjectDumpDelegate; COFFDumper(const llvm::object::COFFObjectFile *Obj, ScopedPrinter &Writer) - : ObjDumper(Writer), Obj(Obj), Writer(Writer), TypeDB(100) {} + : ObjDumper(Writer), Obj(Obj), Writer(Writer), Types(100) {} void printFileHeaders() override; void printSections() override; @@ -106,7 +109,7 @@ private: void printFileNameForOffset(StringRef Label, uint32_t FileOffset); void printTypeIndex(StringRef FieldName, TypeIndex TI) { // Forward to CVTypeDumper for simplicity. - CVTypeDumper::printTypeIndex(Writer, FieldName, TI, TypeDB); + codeview::printTypeIndex(Writer, FieldName, TI, Types); } void printCodeViewSymbolsSubsection(StringRef Subsection, @@ -159,7 +162,8 @@ private: StringTableRef CVStringTable; ScopedPrinter &Writer; - TypeDatabase TypeDB; + BinaryByteStream TypeContents; + LazyRandomTypeCollection Types; }; class COFFObjectDumpDelegate : public SymbolDumpDelegate { @@ -975,9 +979,7 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, Subsection.bytes_end()); auto CODD = llvm::make_unique<COFFObjectDumpDelegate>(*this, Section, Obj, SectionContents); - - CVSymbolDumper CVSD(W, TypeDB, std::move(CODD), - opts::CodeViewSubsectionBytes); + CVSymbolDumper CVSD(W, Types, std::move(CODD), opts::CodeViewSubsectionBytes); CVSymbolArray Symbols; BinaryStreamReader Reader(BinaryData, llvm::support::little); if (auto EC = Reader.readArray(Symbols, Reader.getLength())) { @@ -1093,12 +1095,11 @@ void COFFDumper::printCodeViewTypeSection(StringRef SectionName, if (Magic != COFF::DEBUG_SECTION_MAGIC) return error(object_error::parse_failed); - CVTypeDumper CVTD(TypeDB); - TypeDumpVisitor TDV(TypeDB, &W, opts::CodeViewSubsectionBytes); - if (auto EC = CVTD.dump({Data.bytes_begin(), Data.bytes_end()}, TDV)) { - W.flush(); - error(llvm::errorToErrorCode(std::move(EC))); - } + Types.reset(Data); + + TypeDumpVisitor TDV(Types, &W, opts::CodeViewSubsectionBytes); + error(codeview::visitTypeStream(Types, TDV)); + W.flush(); } void COFFDumper::printSections() { @@ -1638,35 +1639,22 @@ void llvm::dumpCodeViewMergedTypes(ScopedPrinter &Writer, TypeBuf.append(Record.begin(), Record.end()); }); - TypeDatabase TypeDB(CVTypes.records().size()); + TypeTableCollection TpiTypes(CVTypes.records()); { 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(std::move(EC)); - } + TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes); + error(codeview::visitTypeStream(TpiTypes, TDV)); + Writer.flush(); } // 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<uint8_t> Record) { - IDBuf.append(Record.begin(), Record.end()); - }); - + TypeTableCollection IpiTypes(IDTable.records()); { ListScope S(Writer, "MergedIDStream"); - TypeDatabase IDDB(IDTable.records().size()); - 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(std::move(EC)); - } + TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes); + TDV.setIpiTypes(IpiTypes); + error(codeview::visitTypeStream(IpiTypes, TDV)); + Writer.flush(); } } |