Skip to content

Commit 8d66336

Browse files
committed
[Static Mirror] Gather local type extension conformance infos correctly
Conformance Infos for nominal type declarations reference the conforming type by storing an offset to the address in the binary where the type's type descriptor is located. Conformance infos for conformances applied to an extension of a type use a different mechanism: they use an indirect reference to a dynamic symbol, which may be an external symbol **or** a resolved address to a local type descriptor. It is the latter case that the conformance-gather implementation was missing that is added in this PR. Resolves rdar://93578419
1 parent 07ffdde commit 8d66336

File tree

3 files changed

+22
-9
lines changed

3 files changed

+22
-9
lines changed

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,7 @@ class TypeRefBuilder {
855855
using ByteReader = std::function<remote::MemoryReader::ReadBytesResult (remote::RemoteAddress, unsigned)>;
856856
using StringReader = std::function<bool (remote::RemoteAddress, std::string &)>;
857857
using PointerReader = std::function<llvm::Optional<remote::RemoteAbsolutePointer> (remote::RemoteAddress, unsigned)>;
858+
using DynamicSymbolResolver = std::function<llvm::Optional<remote::RemoteAbsolutePointer> (remote::RemoteAddress)>;
858859
using IntVariableReader = std::function<llvm::Optional<uint64_t> (std::string, unsigned)>;
859860

860861
// These fields are captured from the MetadataReader template passed into the
@@ -868,6 +869,7 @@ class TypeRefBuilder {
868869
ByteReader OpaqueByteReader;
869870
StringReader OpaqueStringReader;
870871
PointerReader OpaquePointerReader;
872+
DynamicSymbolResolver OpaqueDynamicSymbolResolver;
871873
IntVariableReader OpaqueIntVariableReader;
872874

873875
public:
@@ -895,6 +897,9 @@ class TypeRefBuilder {
895897
OpaquePointerReader([&reader](remote::RemoteAddress address, unsigned size) -> llvm::Optional<remote::RemoteAbsolutePointer> {
896898
return reader.Reader->readPointer(address, size);
897899
}),
900+
OpaqueDynamicSymbolResolver([&reader](remote::RemoteAddress address) -> llvm::Optional<remote::RemoteAbsolutePointer> {
901+
return reader.Reader->getDynamicSymbol(address);
902+
}),
898903
OpaqueIntVariableReader(
899904
[&reader](std::string symbol, unsigned size) -> llvm::Optional<uint64_t> {
900905
llvm::Optional<uint64_t> result;
@@ -1019,13 +1024,16 @@ class TypeRefBuilder {
10191024
ByteReader OpaqueByteReader;
10201025
StringReader OpaqueStringReader;
10211026
PointerReader OpaquePointerReader;
1027+
DynamicSymbolResolver OpaqueDynamicSymbolResolver;
10221028

10231029
ProtocolConformanceDescriptorReader(ByteReader byteReader,
10241030
StringReader stringReader,
1025-
PointerReader pointerReader)
1031+
PointerReader pointerReader,
1032+
DynamicSymbolResolver dynamicSymbolResolver)
10261033
: Error(""), OpaqueByteReader(byteReader),
1027-
OpaqueStringReader(stringReader), OpaquePointerReader(pointerReader) {
1028-
}
1034+
OpaqueStringReader(stringReader),
1035+
OpaquePointerReader(pointerReader),
1036+
OpaqueDynamicSymbolResolver(dynamicSymbolResolver) {}
10291037

10301038
llvm::Optional<std::string>
10311039
getParentContextName(uintptr_t contextDescriptorAddress) {
@@ -1248,17 +1256,16 @@ class TypeRefBuilder {
12481256
return llvm::None;
12491257
}
12501258
auto contextDescriptorOffset =
1251-
(const uint32_t *)contextDescriptorOffsetBytes.get();
1259+
(const int32_t *)contextDescriptorOffsetBytes.get();
12521260

12531261
// Read the type descriptor itself using the address computed above
12541262
auto contextTypeDescriptorAddress = detail::applyRelativeOffset(
12551263
(const char *)contextDescriptorFieldAddress,
1256-
(int32_t)*contextDescriptorOffset);
1264+
*contextDescriptorOffset);
12571265

12581266
// Instead of a type descriptor this may just be a symbol reference, check that first
1259-
if (auto symbol = OpaquePointerReader(remote::RemoteAddress(contextTypeDescriptorAddress),
1260-
PointerSize)) {
1261-
if (!symbol->getSymbol().empty()) {
1267+
if (auto symbol = OpaqueDynamicSymbolResolver(remote::RemoteAddress(contextTypeDescriptorAddress))) {
1268+
if (!symbol->isResolved()) {
12621269
mangledTypeName = symbol->getSymbol().str();
12631270
Demangle::Context Ctx;
12641271
auto demangledRoot =
@@ -1267,6 +1274,9 @@ class TypeRefBuilder {
12671274
typeName =
12681275
nodeToString(demangledRoot->getChild(0)->getChild(0));
12691276
return std::make_pair(mangledTypeName, typeName);
1277+
} else if (symbol->getOffset()) {
1278+
// If symbol is empty and has an offset, this is the resolved remote address
1279+
contextTypeDescriptorAddress = symbol->getOffset();
12701280
}
12711281
}
12721282

@@ -1462,7 +1472,7 @@ class TypeRefBuilder {
14621472
std::unordered_map<std::string, std::vector<std::string>> typeConformances;
14631473
ProtocolConformanceDescriptorReader<ObjCInteropKind, PointerSize>
14641474
conformanceReader(OpaqueByteReader, OpaqueStringReader,
1465-
OpaquePointerReader);
1475+
OpaquePointerReader, OpaqueDynamicSymbolResolver);
14661476
for (const auto &section : ReflectionInfos) {
14671477
auto ConformanceBegin = section.Conformance.startAddress();
14681478
auto ConformanceEnd = section.Conformance.endAddress();

test/Reflection/Inputs/Conformances.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ struct foo {
3131
}
3232
}
3333
}
34+
35+
extension foo : MyProto {}

test/Reflection/conformance_descriptors.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@
1919
// CHECK-DAG: 16ConformanceCheck2C4V (ConformanceCheck.C4) : ConformanceCheck.P1, ConformanceCheck.P2
2020
// CHECK-DAG: 16ConformanceCheck2S4V (ConformanceCheck.S4) : ConformanceCheck.P1, ConformanceCheck.P2
2121
// CHECK-DAG: 16ConformanceCheck2C1C (ConformanceCheck.C1) : ConformanceCheck.ClassBoundP
22+
// CHECK-DAG: 16ConformanceCheck3fooV (ConformanceCheck.foo) : ConformanceCheck.MyProto

0 commit comments

Comments
 (0)