diff options
author | Alexandre Ganea <alexandre.ganea@ubisoft.com> | 2019-02-07 15:24:18 +0000 |
---|---|---|
committer | Alexandre Ganea <alexandre.ganea@ubisoft.com> | 2019-02-07 15:24:18 +0000 |
commit | 120366edc733ac85ba71e45ecb96edfa9ce9b9d3 (patch) | |
tree | 8fea50ae302f46fd965b105df265ea11a5d1f09d /llvm/tools/llvm-readobj/llvm-readobj.cpp | |
parent | 892e63319497bfbea7c93d763c43a1944d6d7ab4 (diff) | |
download | bcm5719-llvm-120366edc733ac85ba71e45ecb96edfa9ce9b9d3.tar.gz bcm5719-llvm-120366edc733ac85ba71e45ecb96edfa9ce9b9d3.zip |
[CodeView] Fix cycles in debug info when merging Types with global hashes
When type streams with forward references were merged using GHashes, cycles
were introduced in the debug info. This was caused by
GlobalTypeTableBuilder::insertRecordAs() not inserting the record on the second
pass, thus yielding an empty ArrayRef at that record slot. Later on, upon PDB
emission, TpiStreamBuilder::commit() would skip that empty record, thus
offseting all indices that came after in the stream.
This solution comes in two steps:
1. Fix the hash calculation, by doing a multiple-step resolution, iff there are
forward references in the input stream.
2. Fix merge by resolving with multiple passes, therefore moving records with
forward references at the end of the stream.
This patch also adds support for llvm-readoj --codeview-ghash.
Finally, fix dumpCodeViewMergedTypes() which previously could reference deleted
memory.
Fixes PR40221
Differential Revision: https://reviews.llvm.org/D57790
llvm-svn: 353412
Diffstat (limited to 'llvm/tools/llvm-readobj/llvm-readobj.cpp')
-rw-r--r-- | llvm/tools/llvm-readobj/llvm-readobj.cpp | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index 74f21e30d72..2c1674e064e 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -22,6 +22,7 @@ #include "Error.h" #include "ObjDumper.h" #include "WindowsResourceDumper.h" +#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" #include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h" #include "llvm/Object/Archive.h" #include "llvm/Object/COFFImportFile.h" @@ -218,6 +219,12 @@ namespace opts { CodeViewMergedTypes("codeview-merged-types", cl::desc("Display the merged CodeView type stream")); + // -codeview-ghash + cl::opt<bool> CodeViewEnableGHash( + "codeview-ghash", + cl::desc( + "Enable global hashing for CodeView type stream de-duplication")); + // -codeview-subsection-bytes cl::opt<bool> CodeViewSubsectionBytes( "codeview-subsection-bytes", @@ -416,13 +423,17 @@ static bool isMipsArch(unsigned Arch) { namespace { struct ReadObjTypeTableBuilder { ReadObjTypeTableBuilder() - : Allocator(), IDTable(Allocator), TypeTable(Allocator) {} + : Allocator(), IDTable(Allocator), TypeTable(Allocator), + GlobalIDTable(Allocator), GlobalTypeTable(Allocator) {} llvm::BumpPtrAllocator Allocator; llvm::codeview::MergingTypeTableBuilder IDTable; llvm::codeview::MergingTypeTableBuilder TypeTable; + llvm::codeview::GlobalTypeTableBuilder GlobalIDTable; + llvm::codeview::GlobalTypeTableBuilder GlobalTypeTable; + std::vector<OwningBinary<Binary>> Binaries; }; -} +} // namespace static ReadObjTypeTableBuilder CVTypes; /// Creates an format-specific object file dumper. @@ -542,7 +553,9 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) { if (opts::CodeView) Dumper->printCodeViewDebugInfo(); if (opts::CodeViewMergedTypes) - Dumper->mergeCodeViewTypes(CVTypes.IDTable, CVTypes.TypeTable); + Dumper->mergeCodeViewTypes(CVTypes.IDTable, CVTypes.TypeTable, + CVTypes.GlobalIDTable, CVTypes.GlobalTypeTable, + opts::CodeViewEnableGHash); } if (Obj->isMachO()) { if (opts::MachODataInCode) @@ -631,6 +644,8 @@ static void dumpInput(StringRef File) { dumpWindowsResourceFile(WinRes); else reportError(File, readobj_error::unrecognized_file_format); + + CVTypes.Binaries.push_back(std::move(*BinaryOrErr)); } /// Registers aliases that should only be allowed by readobj. @@ -720,7 +735,12 @@ int main(int argc, const char *argv[]) { if (opts::CodeViewMergedTypes) { ScopedPrinter W(outs()); - dumpCodeViewMergedTypes(W, CVTypes.IDTable, CVTypes.TypeTable); + if (opts::CodeViewEnableGHash) + dumpCodeViewMergedTypes(W, CVTypes.GlobalIDTable.records(), + CVTypes.GlobalTypeTable.records()); + else + dumpCodeViewMergedTypes(W, CVTypes.IDTable.records(), + CVTypes.TypeTable.records()); } return 0; |