summaryrefslogtreecommitdiffstats
path: root/llvm/unittests
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2017-06-21 17:25:56 +0000
committerReid Kleckner <rnk@google.com>2017-06-21 17:25:56 +0000
commitd0e6e24a53b35202110e8512de3ac0f247f1ae4f (patch)
tree4a3b56611d4e087122e008bde54f34f1d71a5329 /llvm/unittests
parent84dbbfdeb92085452ebd5966e3a73379a0f4240d (diff)
downloadbcm5719-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.cpp87
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));
+}
OpenPOWER on IntegriCloud