diff options
author | Reid Kleckner <rnk@google.com> | 2017-06-21 17:25:56 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2017-06-21 17:25:56 +0000 |
commit | d0e6e24a53b35202110e8512de3ac0f247f1ae4f (patch) | |
tree | 4a3b56611d4e087122e008bde54f34f1d71a5329 /llvm/unittests | |
parent | 84dbbfdeb92085452ebd5966e3a73379a0f4240d (diff) | |
download | bcm5719-llvm-d0e6e24a53b35202110e8512de3ac0f247f1ae4f.tar.gz bcm5719-llvm-d0e6e24a53b35202110e8512de3ac0f247f1ae4f.zip |
[PDB] Add symbols to the PDB
Summary:
The main complexity in adding symbol records is that we need to
"relocate" all the type indices. Type indices do not have anything like
relocations, an opaque data structure describing where to find existing
type indices for fixups. The linker just has to "know" where the type
references are in the symbol records. I added an overload of
`discoverTypeIndices` that works on symbol records, and it seems to be
able to link the standard library.
Reviewers: zturner, ruiu
Subscribers: llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D34432
llvm-svn: 305933
Diffstat (limited to 'llvm/unittests')
-rw-r--r-- | llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp | 87 |
1 files changed, 79 insertions, 8 deletions
diff --git a/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp b/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp index 99c84906be9..fa9e9612318 100644 --- a/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp +++ b/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp @@ -10,6 +10,7 @@ #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/DebugInfo/CodeView/SymbolSerializer.h" #include "llvm/Support/Allocator.h" #include "gmock/gmock.h" @@ -26,6 +27,7 @@ public: Refs.clear(); TTB = make_unique<TypeTableBuilder>(Storage); FLRB = make_unique<FieldListRecordBuilder>(*TTB); + Symbols.clear(); } void TearDown() override { @@ -37,7 +39,19 @@ protected: template <typename... Indices> bool checkTypeReferences(uint32_t RecordIndex, Indices &&... TIs) const { EXPECT_EQ(sizeof...(Indices), countRefs(RecordIndex)); - return checkTypeReferencesImpl(RecordIndex, std::forward<Indices>(TIs)...); + + // Choose between type or symbol records. The checking code doesn't care + // which we have. + std::vector<ArrayRef<uint8_t>> CVRecords; + if (Symbols.empty()) { + CVRecords = TTB->records(); + } else { + for (const CVSymbol &S : Symbols) + CVRecords.push_back(S.data()); + } + + return checkTypeReferencesImpl(RecordIndex, CVRecords, + std::forward<Indices>(TIs)...); } template <typename... T> void writeFieldList(T &&... MemberRecords) { @@ -54,6 +68,13 @@ protected: discoverAllTypeIndices(); } + template <typename... T> void writeSymbolRecords(T &&... Records) { + writeSymbolRecordsImpl(std::forward<T>(Records)...); + ASSERT_EQ(sizeof...(T), Symbols.size()); + discoverTypeIndicesInSymbols(); + } + + std::unique_ptr<TypeTableBuilder> TTB; private: @@ -83,18 +104,20 @@ private: } template <typename... Indices> - bool checkTypeReferencesImpl(uint32_t RecordIndex) const { + bool checkTypeReferencesImpl(uint32_t RecordIndex, + ArrayRef<ArrayRef<uint8_t>> CVRecords) const { return true; } template <typename... Indices> - bool checkTypeReferencesImpl(uint32_t RecordIndex, TypeIndex TI, - Indices &&... Rest) const { - ArrayRef<uint8_t> Record = TTB->records()[RecordIndex]; + bool checkTypeReferencesImpl(uint32_t RecordIndex, + ArrayRef<ArrayRef<uint8_t>> CVRecords, + TypeIndex TI, Indices &&... Rest) const { + ArrayRef<uint8_t> Record = CVRecords[RecordIndex]; bool Success = checkOneTypeReference(RecordIndex, Record, TI); EXPECT_TRUE(Success); - return Success & - checkTypeReferencesImpl(RecordIndex, std::forward<Indices>(Rest)...); + return Success & checkTypeReferencesImpl(RecordIndex, CVRecords, + std::forward<Indices>(Rest)...); } void discoverAllTypeIndices() { @@ -105,6 +128,12 @@ private: } } + void discoverTypeIndicesInSymbols() { + Refs.resize(Symbols.size()); + for (uint32_t I = 0; I < Symbols.size(); ++I) + discoverTypeIndices(Symbols[I], Refs[I]); + } + // Helper function to write out a field list record with the given list // of member records. void writeFieldListImpl() {} @@ -124,8 +153,19 @@ private: writeTypeRecordsImpl(std::forward<Rest>(Records)...); } + // Helper function to write out a list of symbol records. + void writeSymbolRecordsImpl() {} + + template <typename RecType, typename... Rest> + void writeSymbolRecordsImpl(RecType &&Record, Rest &&... Records) { + Symbols.push_back(SymbolSerializer::writeOneSymbol(Record, Storage, + CodeViewContainer::Pdb)); + writeSymbolRecordsImpl(std::forward<Rest>(Records)...); + } + std::vector<SmallVector<TiReference, 4>> Refs; std::unique_ptr<FieldListRecordBuilder> FLRB; + std::vector<CVSymbol> Symbols; BumpPtrAllocator Storage; }; @@ -492,4 +532,35 @@ TEST_F(TypeIndexIteratorTest, ManyMembers) { OneMethod.T1, OneMethod.T2, OneMethod.T3, OneMethod.T4, NestedType.Type, StaticDataMember.Type, VirtualBaseClass.BaseType, VirtualBaseClass.VBPtrType, VFPtr.Type, Continuation.ContinuationIndex); -}
\ No newline at end of file +} + +TEST_F(TypeIndexIteratorTest, ProcSym) { + ProcSym GS(SymbolRecordKind::GlobalProcSym); + GS.FunctionType = TypeIndex(0x40); + ProcSym LS(SymbolRecordKind::ProcSym); + LS.FunctionType = TypeIndex(0x41); + writeSymbolRecords(GS, LS); + checkTypeReferences(0, GS.FunctionType); + checkTypeReferences(1, LS.FunctionType); +} + +TEST_F(TypeIndexIteratorTest, DataSym) { + DataSym DS(SymbolRecordKind::GlobalData); + DS.Type = TypeIndex(0x40); + writeSymbolRecords(DS); + checkTypeReferences(0, DS.Type); +} + +TEST_F(TypeIndexIteratorTest, CallerSym) { + CallerSym Callees(SymbolRecordKind::CalleeSym); + Callees.Indices.push_back(TypeIndex(1)); + Callees.Indices.push_back(TypeIndex(2)); + Callees.Indices.push_back(TypeIndex(3)); + CallerSym Callers(SymbolRecordKind::CallerSym); + Callers.Indices.push_back(TypeIndex(4)); + Callers.Indices.push_back(TypeIndex(5)); + Callers.Indices.push_back(TypeIndex(6)); + writeSymbolRecords(Callees, Callers); + checkTypeReferences(0, TypeIndex(1), TypeIndex(2), TypeIndex(3)); + checkTypeReferences(1, TypeIndex(4), TypeIndex(5), TypeIndex(6)); +} |