Skip to content

Commit e934fe2

Browse files
committed
Add extraction protocol conformance descriptor extraction, as read from an object file image, to TypeRefBuilder.
1 parent f3d784f commit e934fe2

File tree

13 files changed

+465
-103
lines changed

13 files changed

+465
-103
lines changed

include/swift/ABI/Metadata.h

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ 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
8292
};
8393

8494
template <>
@@ -91,6 +101,16 @@ struct RuntimeTarget<8> {
91101
using StoredSize = uint64_t;
92102
using StoredPointerDifference = int64_t;
93103
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
94114
};
95115

96116
namespace reflection {
@@ -540,6 +560,14 @@ namespace {
540560

541561
using TypeContextDescriptor = TargetTypeContextDescriptor<InProcess>;
542562

563+
template<unsigned PointerSize>
564+
using ExternalTypeContextDescriptor
565+
#if SWIFT_OBJC_INTEROP
566+
= TargetTypeContextDescriptor<External<WithObjCInterop<RuntimeTarget<PointerSize>>>>;
567+
#else
568+
= TargetTypeContextDescriptor<External<NoObjCInterop<RuntimeTarget<PointerSize>>>>;
569+
#endif
570+
543571
// FIXME: https://bugs.swift.org/browse/SR-1155
544572
#pragma clang diagnostic push
545573
#pragma clang diagnostic ignored "-Winvalid-offsetof"
@@ -2106,7 +2134,15 @@ using ProtocolRequirement = TargetProtocolRequirement<InProcess>;
21062134

21072135
template<typename Runtime> struct TargetProtocolDescriptor;
21082136
using ProtocolDescriptor = TargetProtocolDescriptor<InProcess>;
2109-
2137+
2138+
template<unsigned PointerSize>
2139+
using ExternalProtocolDescriptor
2140+
#if SWIFT_OBJC_INTEROP
2141+
= TargetProtocolDescriptor<External<WithObjCInterop<RuntimeTarget<PointerSize>>>>;
2142+
#else
2143+
= TargetProtocolDescriptor<External<NoObjCInterop<RuntimeTarget<PointerSize>>>>;
2144+
#endif
2145+
21102146
/// A witness table for a protocol.
21112147
///
21122148
/// With the exception of the initial protocol conformance descriptor,
@@ -2722,6 +2758,16 @@ struct TargetProtocolConformanceDescriptor final
27222758
return TypeRef.getTypeDescriptor(getTypeKind());
27232759
}
27242760

2761+
constexpr inline auto
2762+
getTypeDescriptorOffset() const -> typename Runtime::StoredSize {
2763+
return offsetof(typename std::remove_reference<decltype(*this)>::type, TypeRef);
2764+
}
2765+
2766+
constexpr inline auto
2767+
getProtocolDescriptorOffset() const -> typename Runtime::StoredSize {
2768+
return offsetof(typename std::remove_reference<decltype(*this)>::type, Protocol);
2769+
}
2770+
27252771
TargetContextDescriptor<Runtime> * __ptrauth_swift_type_descriptor *
27262772
_getTypeDescriptorLocation() const {
27272773
if (getTypeKind() != TypeReferenceKind::IndirectTypeDescriptor)
@@ -2840,9 +2886,21 @@ using TargetProtocolConformanceRecord =
28402886

28412887
using ProtocolConformanceRecord = TargetProtocolConformanceRecord<InProcess>;
28422888

2889+
template<unsigned PointerSize>
28432890
using ExternalProtocolConformanceDescriptor
2844-
= TargetProtocolConformanceDescriptor<External<RuntimeTarget<8>>>;
2845-
using ExternalProtocolConformanceRecord = TargetProtocolConformanceRecord<External<RuntimeTarget<8>>>;
2891+
#if SWIFT_OBJC_INTEROP
2892+
= TargetProtocolConformanceDescriptor<External<WithObjCInterop<RuntimeTarget<PointerSize>>>>;
2893+
#else
2894+
= TargetProtocolConformanceDescriptor<External<NoObjCInterop<RuntimeTarget<PointerSize>>>>;
2895+
#endif
2896+
2897+
template<unsigned PointerSize>
2898+
using ExternalProtocolConformanceRecord
2899+
#if SWIFT_OBJC_INTEROP
2900+
= TargetProtocolConformanceRecord<External<WithObjCInterop<RuntimeTarget<PointerSize>>>>;
2901+
#else
2902+
= TargetProtocolConformanceRecord<External<NoObjCInterop<RuntimeTarget<PointerSize>>>>;
2903+
#endif
28462904

28472905
template<typename Runtime>
28482906
struct TargetGenericContext;
@@ -2893,6 +2951,13 @@ struct TargetContextDescriptor {
28932951
};
28942952

28952953
using ContextDescriptor = TargetContextDescriptor<InProcess>;
2954+
template<unsigned PointerSize>
2955+
using ExternalContextDescriptor
2956+
#if SWIFT_OBJC_INTEROP
2957+
= TargetContextDescriptor<External<WithObjCInterop<RuntimeTarget<PointerSize>>>>;
2958+
#else
2959+
= TargetContextDescriptor<External<NoObjCInterop<RuntimeTarget<PointerSize>>>>;
2960+
#endif
28962961

28972962
inline bool isCImportedModuleName(llvm::StringRef name) {
28982963
// This does not include MANGLING_MODULE_CLANG_IMPORTER because that's
@@ -3417,6 +3482,11 @@ struct TargetProtocolDescriptor final
34173482
NumRequirements};
34183483
}
34193484

3485+
constexpr inline auto
3486+
getNameOffset() const -> typename Runtime::StoredSize {
3487+
return offsetof(typename std::remove_reference<decltype(*this)>::type, Name);
3488+
}
3489+
34203490
/// Retrieve the requirement base descriptor address.
34213491
ConstTargetPointer<Runtime, TargetProtocolRequirement<Runtime>>
34223492
getRequirementBaseDescriptor() const {
@@ -4081,6 +4151,11 @@ class TargetTypeContextDescriptor
40814151
/// type's metadata. The returned value is measured in sizeof(StoredPointer).
40824152
int32_t getGenericArgumentOffset() const;
40834153

4154+
constexpr inline auto
4155+
getNameOffset() const -> typename Runtime::StoredSize {
4156+
return offsetof(typename std::remove_reference<decltype(*this)>::type, Name);
4157+
}
4158+
40844159
/// Return the start of the generic arguments array in the nominal
40854160
/// type's metadata. The returned value is measured in sizeof(StoredPointer).
40864161
const TargetMetadata<Runtime> * const *getGenericArguments(

include/swift/ABI/ObjectFile.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@
1212

1313
namespace swift {
1414

15-
/// Represents the seven reflection sections used by Swift
15+
/// Represents the eight reflection sections used by Swift
1616
enum ReflectionSectionKind : uint8_t {
1717
fieldmd,
1818
assocty,
1919
builtin,
2020
capture,
2121
typeref,
2222
reflstr,
23-
conform
23+
conform,
24+
protocs
2425
};
2526

2627
/// Abstract base class responsible for providing the correct reflection section
@@ -50,6 +51,8 @@ class SwiftObjectFileFormatMachO : public SwiftObjectFileFormat {
5051
return "__swift5_reflstr";
5152
case conform:
5253
return "__swift5_proto";
54+
case protocs:
55+
return "__swift5_protos";
5356
}
5457
llvm_unreachable("Section type not found.");
5558
}
@@ -73,7 +76,9 @@ class SwiftObjectFileFormatELF : public SwiftObjectFileFormat {
7376
case reflstr:
7477
return "swift5_reflstr";
7578
case conform:
76-
return "swift5_proto";
79+
return "swift5_protocol_conformances";
80+
case protocs:
81+
return "swift5_protocols";
7782
}
7883
llvm_unreachable("Section type not found.");
7984
}
@@ -97,7 +102,9 @@ class SwiftObjectFileFormatCOFF : public SwiftObjectFileFormat {
97102
case reflstr:
98103
return ".sw5rfst";
99104
case conform:
100-
return ".sw5cnfrm"; // TODO: Figure out the real name
105+
return ".sw5prtc$B";
106+
case protocs:
107+
return ".sw5prt$B";
101108
}
102109
llvm_unreachable("Section not found.");
103110
}

include/swift/Basic/RelativePointer.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,17 @@ class RelativeDirectPointerImpl {
442442
return reinterpret_cast<PointerTy>(absolute);
443443
}
444444

445+
/// Apply the offset to a parameter, instead of `this`.
446+
PointerTy getRelative(void *base) const & {
447+
// Check for null.
448+
if (Nullable && RelativeOffset == 0)
449+
return nullptr;
450+
451+
// The value is addressed relative to `base`.
452+
uintptr_t absolute = detail::applyRelativeOffset(base, RelativeOffset);
453+
return reinterpret_cast<PointerTy>(absolute);
454+
}
455+
445456
/// A zero relative offset encodes a null reference.
446457
bool isNull() const & {
447458
return RelativeOffset == 0;
@@ -476,6 +487,10 @@ class RelativeDirectPointer<T, Nullable, Offset,
476487
return this->get();
477488
}
478489

490+
const typename super::ValueTy* getRelative(void *base) const & {
491+
return this->super::getRelative(base);
492+
}
493+
479494
using super::isNull;
480495
};
481496

include/swift/Reflection/ReflectionContext.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,22 @@ class ReflectionContext
221221
SectionsBuf + (I * sizeof(typename T::Section)));
222222
if (strncmp(S->sectname, Name.data(), strlen(Name.data())) != 0)
223223
continue;
224+
225+
// The above check verifies that `Name` is a prefix to the examined
226+
// section name, to allow for matching of sections with a suffix
227+
// like `_TEXT`, etc.
228+
// "__swift5_proto" section name is a substring of "__swift5_protos",
229+
// Ensure we don't return the latter when looking for the former.
230+
SwiftObjectFileFormatMachO ObjectFileFormat;
231+
if (Name.data() ==
232+
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform)) {
233+
auto protocolsSectionName =
234+
ObjectFileFormat.getSectionName(ReflectionSectionKind::protocs);
235+
if (strncmp(S->sectname, protocolsSectionName.data(),
236+
strlen(protocolsSectionName.data())) == 0)
237+
continue;
238+
}
239+
224240
auto RemoteSecStart = S->addr + Slide;
225241
auto LocalSectBuf =
226242
this->getReader().readBytes(RemoteAddress(RemoteSecStart), S->size);

0 commit comments

Comments
 (0)