Skip to content

Commit 59d1960

Browse files
committed
Add support for reading protocol descriptors from an indirect protocol descriptor target in an conformance descriptor.
Previously, the code assumed that such an indirect target will always point to an external symbol pointer, but it can also be an absolute pointer to an in-image protocol descriptor.
1 parent e934fe2 commit 59d1960

File tree

5 files changed

+58
-63
lines changed

5 files changed

+58
-63
lines changed

include/swift/ABI/Metadata.h

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,6 @@ struct RuntimeTarget<4> {
7979
using StoredSize = uint32_t;
8080
using StoredPointerDifference = int32_t;
8181
static constexpr size_t PointerSize = 4;
82-
83-
#if SWIFT_OBJC_INTEROP
84-
static constexpr bool ObjCInterop = true;
85-
template <typename T>
86-
using TargetAnyClassMetadata = TargetAnyClassMetadataObjCInterop<T>;
87-
#else
88-
static constexpr bool ObjCInterop = false;
89-
template <typename T>
90-
using TargetAnyClassMetadata = TargetAnyClassMetadata<T>;
91-
#endif
9282
};
9383

9484
template <>
@@ -101,16 +91,6 @@ struct RuntimeTarget<8> {
10191
using StoredSize = uint64_t;
10292
using StoredPointerDifference = int64_t;
10393
static constexpr size_t PointerSize = 8;
104-
105-
#if SWIFT_OBJC_INTEROP
106-
static constexpr bool ObjCInterop = true;
107-
template <typename T>
108-
using TargetAnyClassMetadata = TargetAnyClassMetadataObjCInterop<T>;
109-
#else
110-
static constexpr bool ObjCInterop = false;
111-
template <typename T>
112-
using TargetAnyClassMetadata = TargetAnyClassMetadata<T>;
113-
#endif
11494
};
11595

11696
namespace reflection {

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,43 @@ class TypeRefBuilder {
859859
return typeName;
860860
}
861861

862+
std::string readProtocolNameFromProtocolDescriptor(const char *protocolDescriptorAddress) {
863+
std::string protocolName;
864+
auto protocolDescriptorBytes =
865+
OpaqueByteReader(remote::RemoteAddress(protocolDescriptorAddress),
866+
sizeof(ExternalProtocolDescriptor<PointerSize>));
867+
if (!protocolDescriptorBytes.get()) {
868+
Error = "Error reading protocol descriptor.";
869+
return protocolName;
870+
}
871+
const ExternalProtocolDescriptor<PointerSize> *protocolDescriptor =
872+
(const ExternalProtocolDescriptor<PointerSize> *)
873+
protocolDescriptorBytes.get();
874+
875+
// Compute the address of the protocol descriptor's name field and read
876+
// the offset
877+
auto protocolNameOffsetAddress = detail::applyRelativeOffset(
878+
(const char *)protocolDescriptorAddress,
879+
(int32_t)protocolDescriptor->getNameOffset());
880+
auto protocolNameOfsetBytes = OpaqueByteReader(
881+
remote::RemoteAddress(protocolNameOffsetAddress), sizeof(uint32_t));
882+
if (!protocolNameOfsetBytes.get()) {
883+
Error = "Failed to read type name offset in a protocol descriptor.";
884+
return protocolName;
885+
}
886+
auto protocolNameOffset =
887+
(const uint32_t *)protocolNameOfsetBytes.get();
888+
889+
// Using the offset above, compute the address of the name field itsel
890+
// and read it.
891+
auto protocolNameAddress =
892+
detail::applyRelativeOffset((const char *)protocolNameOffsetAddress,
893+
(int32_t)*protocolNameOffset);
894+
OpaqueStringReader(remote::RemoteAddress(protocolNameAddress),
895+
protocolName);
896+
return protocolName;
897+
}
898+
862899
std::string getConformanceProtocol(
863900
const char *conformanceDescriptorAddress,
864901
const ExternalProtocolConformanceDescriptor<PointerSize>
@@ -888,52 +925,26 @@ class TypeRefBuilder {
888925
(const void *)((uint64_t)protocolDescriptorTarget & ~(0x1));
889926
if (auto symbol = OpaquePointerReader(
890927
remote::RemoteAddress(adjustedProtocolDescriptorTarget), 8)) {
891-
892-
Demangle::Context Ctx;
893-
auto demangledRoot =
894-
Ctx.demangleSymbolAsNode(symbol->getSymbol().str());
895-
assert(demangledRoot->getKind() == Node::Kind::Global);
896-
assert(demangledRoot->getChild(0)->getKind() ==
897-
Node::Kind::ProtocolDescriptor);
898-
protocolName = nodeToString(demangledRoot->getChild(0)->getChild(0));
928+
if (!symbol->getSymbol().empty()) {
929+
Demangle::Context Ctx;
930+
auto demangledRoot =
931+
Ctx.demangleSymbolAsNode(symbol->getSymbol().str());
932+
assert(demangledRoot->getKind() == Node::Kind::Global);
933+
assert(demangledRoot->getChild(0)->getKind() ==
934+
Node::Kind::ProtocolDescriptor);
935+
protocolName = nodeToString(demangledRoot->getChild(0)->getChild(0));
936+
} else {
937+
// This is an absolute address offset.
938+
auto protocolDescriptorAddress = symbol->getOffset();
939+
protocolName = readProtocolNameFromProtocolDescriptor((const char*)protocolDescriptorAddress);
940+
}
899941
} else {
900942
Error = "Error reading external protocol address.";
901943
return protocolName;
902944
}
903945
// If direct, read the protocol descriptor and get symbol name
904946
} else {
905-
auto protocolDescriptorBytes =
906-
OpaqueByteReader(remote::RemoteAddress(protocolDescriptorTarget),
907-
sizeof(ExternalProtocolDescriptor<PointerSize>));
908-
if (!protocolDescriptorBytes.get()) {
909-
Error = "Error reading protocol descriptor.";
910-
return protocolName;
911-
}
912-
const ExternalProtocolDescriptor<PointerSize> *protocolDescriptor =
913-
(const ExternalProtocolDescriptor<PointerSize> *)
914-
protocolDescriptorBytes.get();
915-
916-
// Compute the address of the protocol descriptor's name field and read
917-
// the offset
918-
auto protocolNameOffsetAddress = detail::applyRelativeOffset(
919-
(const char *)protocolDescriptorTarget,
920-
(int32_t)protocolDescriptor->getNameOffset());
921-
auto protocolNameOfsetBytes = OpaqueByteReader(
922-
remote::RemoteAddress(protocolNameOffsetAddress), sizeof(uint32_t));
923-
if (!protocolNameOfsetBytes.get()) {
924-
Error = "Failed to read type name offset in a protocol descriptor.";
925-
return protocolName;
926-
}
927-
auto protocolNameOffset =
928-
(const uint32_t *)protocolNameOfsetBytes.get();
929-
930-
// Using the offset above, compute the address of the name field itsel
931-
// and read it.
932-
auto protocolNameAddress =
933-
detail::applyRelativeOffset((const char *)protocolNameOffsetAddress,
934-
(int32_t)*protocolNameOffset);
935-
OpaqueStringReader(remote::RemoteAddress(protocolNameAddress),
936-
protocolName);
947+
protocolName = readProtocolNameFromProtocolDescriptor((const char*)protocolDescriptorTarget);
937948
}
938949

939950
return protocolName;

include/swift/StaticMirror/ObjectFileContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===---------------- ObjectFileCOntext.h - Swift Compiler ---------------===//
1+
//===---------------- ObjectFileContext.h - Swift Compiler ---------------===//
22
//
33
// This source file is part of the Swift.org open source project
44
//

stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ swift_reflection_addReflectionInfo(SwiftReflectionContextRef ContextRef,
216216
sectionFromInfo<CaptureDescriptorIterator>(Info, Info.capture),
217217
sectionFromInfo<const void *>(Info, Info.type_references),
218218
sectionFromInfo<const void *>(Info, Info.reflection_strings),
219-
// TODO: Conformance section
220219
ReflectionSection<const void *>(nullptr, 0)};
221220

222221
Context->addReflectionInfo(ContextInfo);
@@ -237,7 +236,6 @@ void swift_reflection_addReflectionMappingInfo(
237236
Info.capture),
238237
reflectionSectionFromLocalAndRemote<const void *>(Info.type_references),
239238
reflectionSectionFromLocalAndRemote<const void *>(Info.reflection_strings),
240-
// TODO: Conformance section
241239
ReflectionSection<const void *>(nullptr, 0)};
242240

243241
Context->addReflectionInfo(ContextInfo);

test/Reflection/typeref_decoding.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,3 +740,9 @@
740740
// CHECK: (generic_argument index=0
741741
// CHECK: (reference_capture index=0))
742742

743+
// CHECK: CONFORMANCES:
744+
// CHECK: =============
745+
// CHECK: E4 : P1, P2, P3
746+
// CHECK: S4 : P1, P2
747+
// CHECK: C4 : P1, P2
748+
// CHECK: C1 : ClassBoundP

0 commit comments

Comments
 (0)