Skip to content

Commit b4926df

Browse files
authored
Merge pull request #41027 from artemcm/AddConformanceMetadataReader
Add extraction of protocol conformance descriptor info, as read from an object file image, to `TypeRefBuilder`.
2 parents 008fd71 + 5d17074 commit b4926df

File tree

16 files changed

+1409
-604
lines changed

16 files changed

+1409
-604
lines changed

include/swift/ABI/Metadata.h

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,9 @@ namespace {
540540

541541
using TypeContextDescriptor = TargetTypeContextDescriptor<InProcess>;
542542

543+
template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
544+
using ExternalTypeContextDescriptor = TargetTypeContextDescriptor<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;
545+
543546
// FIXME: https://bugs.swift.org/browse/SR-1155
544547
#pragma clang diagnostic push
545548
#pragma clang diagnostic ignored "-Winvalid-offsetof"
@@ -2106,7 +2109,10 @@ using ProtocolRequirement = TargetProtocolRequirement<InProcess>;
21062109

21072110
template<typename Runtime> struct TargetProtocolDescriptor;
21082111
using ProtocolDescriptor = TargetProtocolDescriptor<InProcess>;
2109-
2112+
2113+
template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
2114+
using ExternalProtocolDescriptor = TargetProtocolDescriptor<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;
2115+
21102116
/// A witness table for a protocol.
21112117
///
21122118
/// With the exception of the initial protocol conformance descriptor,
@@ -2722,6 +2728,16 @@ struct TargetProtocolConformanceDescriptor final
27222728
return TypeRef.getTypeDescriptor(getTypeKind());
27232729
}
27242730

2731+
constexpr inline auto
2732+
getTypeRefDescriptorOffset() const -> typename Runtime::StoredSize {
2733+
return offsetof(typename std::remove_reference<decltype(*this)>::type, TypeRef);
2734+
}
2735+
2736+
constexpr inline auto
2737+
getProtocolDescriptorOffset() const -> typename Runtime::StoredSize {
2738+
return offsetof(typename std::remove_reference<decltype(*this)>::type, Protocol);
2739+
}
2740+
27252741
TargetContextDescriptor<Runtime> * __ptrauth_swift_type_descriptor *
27262742
_getTypeDescriptorLocation() const {
27272743
if (getTypeKind() != TypeReferenceKind::IndirectTypeDescriptor)
@@ -2840,6 +2856,12 @@ using TargetProtocolConformanceRecord =
28402856

28412857
using ProtocolConformanceRecord = TargetProtocolConformanceRecord<InProcess>;
28422858

2859+
template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
2860+
using ExternalProtocolConformanceDescriptor = TargetProtocolConformanceDescriptor<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;
2861+
2862+
template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
2863+
using ExternalProtocolConformanceRecord = TargetProtocolConformanceRecord<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;
2864+
28432865
template<typename Runtime>
28442866
struct TargetGenericContext;
28452867

@@ -2876,6 +2898,11 @@ struct TargetContextDescriptor {
28762898
: 0;
28772899
}
28782900

2901+
constexpr inline auto
2902+
getParentOffset() const -> typename Runtime::StoredSize {
2903+
return offsetof(typename std::remove_reference<decltype(*this)>::type, Parent);
2904+
}
2905+
28792906
#ifndef NDEBUG
28802907
LLVM_ATTRIBUTE_DEPRECATED(void dump() const,
28812908
"only for use in the debugger");
@@ -2889,6 +2916,8 @@ struct TargetContextDescriptor {
28892916
};
28902917

28912918
using ContextDescriptor = TargetContextDescriptor<InProcess>;
2919+
template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
2920+
using ExternalContextDescriptor = TargetContextDescriptor<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;
28922921

28932922
inline bool isCImportedModuleName(llvm::StringRef name) {
28942923
// This does not include MANGLING_MODULE_CLANG_IMPORTER because that's
@@ -2908,13 +2937,21 @@ struct TargetModuleContextDescriptor final : TargetContextDescriptor<Runtime> {
29082937
return isCImportedModuleName(Name.get());
29092938
}
29102939

2940+
constexpr inline auto
2941+
getNameOffset() const -> typename Runtime::StoredSize {
2942+
return offsetof(typename std::remove_reference<decltype(*this)>::type, Name);
2943+
}
2944+
29112945
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
29122946
return cd->getKind() == ContextDescriptorKind::Module;
29132947
}
29142948
};
29152949

29162950
using ModuleContextDescriptor = TargetModuleContextDescriptor<InProcess>;
29172951

2952+
template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
2953+
using ExternalModuleContextDescriptor = TargetModuleContextDescriptor<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;
2954+
29182955
template<typename Runtime>
29192956
inline bool TargetContextDescriptor<Runtime>::isCImportedContext() const {
29202957
return getModuleContext()->isCImportedContext();
@@ -3415,6 +3452,11 @@ struct TargetProtocolDescriptor final
34153452
NumRequirements};
34163453
}
34173454

3455+
constexpr inline auto
3456+
getNameOffset() const -> typename Runtime::StoredSize {
3457+
return offsetof(typename std::remove_reference<decltype(*this)>::type, Name);
3458+
}
3459+
34183460
/// Retrieve the requirement base descriptor address.
34193461
ConstTargetPointer<Runtime, TargetProtocolRequirement<Runtime>>
34203462
getRequirementBaseDescriptor() const {
@@ -4079,6 +4121,11 @@ class TargetTypeContextDescriptor
40794121
/// type's metadata. The returned value is measured in sizeof(StoredPointer).
40804122
int32_t getGenericArgumentOffset() const;
40814123

4124+
constexpr inline auto
4125+
getNameOffset() const -> typename Runtime::StoredSize {
4126+
return offsetof(typename std::remove_reference<decltype(*this)>::type, Name);
4127+
}
4128+
40824129
/// Return the start of the generic arguments array in the nominal
40834130
/// type's metadata. The returned value is measured in sizeof(StoredPointer).
40844131
const TargetMetadata<Runtime> * const *getGenericArguments(

include/swift/ABI/ObjectFile.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@
1212

1313
namespace swift {
1414

15-
/// Represents the six 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,
22-
reflstr
22+
reflstr,
23+
conform,
24+
protocs
2325
};
2426

2527
/// Abstract base class responsible for providing the correct reflection section
@@ -52,6 +54,10 @@ class SwiftObjectFileFormatMachO : public SwiftObjectFileFormat {
5254
return "__swift5_typeref";
5355
case reflstr:
5456
return "__swift5_reflstr";
57+
case conform:
58+
return "__swift5_proto";
59+
case protocs:
60+
return "__swift5_protos";
5561
}
5662
llvm_unreachable("Section type not found.");
5763
}
@@ -86,6 +92,10 @@ class SwiftObjectFileFormatELF : public SwiftObjectFileFormat {
8692
return "swift5_typeref";
8793
case reflstr:
8894
return "swift5_reflstr";
95+
case conform:
96+
return "swift5_protocol_conformances";
97+
case protocs:
98+
return "swift5_protocols";
8999
}
90100
llvm_unreachable("Section type not found.");
91101
}
@@ -112,6 +122,10 @@ class SwiftObjectFileFormatCOFF : public SwiftObjectFileFormat {
112122
return ".sw5tyrf";
113123
case reflstr:
114124
return ".sw5rfst";
125+
case conform:
126+
return ".sw5prtc$B";
127+
case protocs:
128+
return ".sw5prt$B";
115129
}
116130
llvm_unreachable("Section not found.");
117131
}

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: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,9 @@ class ReflectionContext
219219
for (unsigned I = 0; I < NumSect; ++I) {
220220
auto S = reinterpret_cast<typename T::Section *>(
221221
SectionsBuf + (I * sizeof(typename T::Section)));
222-
if (strncmp(S->sectname, Name.data(), strlen(Name.data())) != 0)
222+
if (strncmp(S->sectname, Name.data(), sizeof(S->sectname)) != 0)
223223
continue;
224+
224225
auto RemoteSecStart = S->addr + Slide;
225226
auto LocalSectBuf =
226227
this->getReader().readBytes(RemoteAddress(RemoteSecStart), S->size);
@@ -247,13 +248,16 @@ class ReflectionContext
247248
ObjectFileFormat.getSectionName(ReflectionSectionKind::typeref));
248249
auto ReflStrMdSec = findMachOSectionByName(
249250
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
251+
auto ConformMdSec = findMachOSectionByName(
252+
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));
250253

251254
if (FieldMdSec.first == nullptr &&
252255
AssocTySec.first == nullptr &&
253256
BuiltinTySec.first == nullptr &&
254257
CaptureSec.first == nullptr &&
255258
TypeRefMdSec.first == nullptr &&
256-
ReflStrMdSec.first == nullptr)
259+
ReflStrMdSec.first == nullptr &&
260+
ConformMdSec.first == nullptr)
257261
return false;
258262

259263
ReflectionInfo info = {
@@ -262,7 +266,8 @@ class ReflectionContext
262266
{BuiltinTySec.first, BuiltinTySec.second},
263267
{CaptureSec.first, CaptureSec.second},
264268
{TypeRefMdSec.first, TypeRefMdSec.second},
265-
{ReflStrMdSec.first, ReflStrMdSec.second}};
269+
{ReflStrMdSec.first, ReflStrMdSec.second},
270+
{ConformMdSec.first, ConformMdSec.second}};
266271

267272
this->addReflectionInfo(info);
268273

@@ -365,13 +370,16 @@ class ReflectionContext
365370
ObjectFileFormat.getSectionName(ReflectionSectionKind::typeref));
366371
auto ReflStrMdSec = findCOFFSectionByName(
367372
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
373+
auto ConformMdSec = findCOFFSectionByName(
374+
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));
368375

369376
if (FieldMdSec.first == nullptr &&
370377
AssocTySec.first == nullptr &&
371378
BuiltinTySec.first == nullptr &&
372379
CaptureSec.first == nullptr &&
373380
TypeRefMdSec.first == nullptr &&
374-
ReflStrMdSec.first == nullptr)
381+
ReflStrMdSec.first == nullptr &&
382+
ConformMdSec.first == nullptr)
375383
return false;
376384

377385
ReflectionInfo Info = {
@@ -380,7 +388,8 @@ class ReflectionContext
380388
{BuiltinTySec.first, BuiltinTySec.second},
381389
{CaptureSec.first, CaptureSec.second},
382390
{TypeRefMdSec.first, TypeRefMdSec.second},
383-
{ReflStrMdSec.first, ReflStrMdSec.second}};
391+
{ReflStrMdSec.first, ReflStrMdSec.second},
392+
{ConformMdSec.first, ConformMdSec.second}};
384393
this->addReflectionInfo(Info);
385394
return true;
386395
}
@@ -544,6 +553,8 @@ class ReflectionContext
544553
ObjectFileFormat.getSectionName(ReflectionSectionKind::typeref));
545554
auto ReflStrMdSec = findELFSectionByName(
546555
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
556+
auto ConformMdSec = findELFSectionByName(
557+
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));
547558

548559
if (Error)
549560
return false;
@@ -555,7 +566,8 @@ class ReflectionContext
555566
BuiltinTySec.first == nullptr &&
556567
CaptureSec.first == nullptr &&
557568
TypeRefMdSec.first == nullptr &&
558-
ReflStrMdSec.first == nullptr)
569+
ReflStrMdSec.first == nullptr &&
570+
ConformMdSec.first == nullptr)
559571
return false;
560572

561573
ReflectionInfo info = {
@@ -564,7 +576,8 @@ class ReflectionContext
564576
{BuiltinTySec.first, BuiltinTySec.second},
565577
{CaptureSec.first, CaptureSec.second},
566578
{TypeRefMdSec.first, TypeRefMdSec.second},
567-
{ReflStrMdSec.first, ReflStrMdSec.second}};
579+
{ReflStrMdSec.first, ReflStrMdSec.second},
580+
{ConformMdSec.first, ConformMdSec.second}};
568581

569582
this->addReflectionInfo(info);
570583
return true;
@@ -665,7 +678,9 @@ class ReflectionContext
665678
auto Sections = {
666679
ReflectionSectionKind::fieldmd, ReflectionSectionKind::assocty,
667680
ReflectionSectionKind::builtin, ReflectionSectionKind::capture,
668-
ReflectionSectionKind::typeref, ReflectionSectionKind::reflstr};
681+
ReflectionSectionKind::typeref, ReflectionSectionKind::reflstr,
682+
ReflectionSectionKind::conform
683+
};
669684

670685
llvm::SmallVector<std::pair<RemoteRef<void>, uint64_t>, 6> Pairs;
671686
for (auto Section : Sections) {
@@ -687,7 +702,8 @@ class ReflectionContext
687702
ReflectionInfo Info = {
688703
{Pairs[0].first, Pairs[0].second}, {Pairs[1].first, Pairs[1].second},
689704
{Pairs[2].first, Pairs[2].second}, {Pairs[3].first, Pairs[3].second},
690-
{Pairs[4].first, Pairs[4].second}, {Pairs[5].first, Pairs[5].second}};
705+
{Pairs[4].first, Pairs[4].second}, {Pairs[5].first, Pairs[5].second},
706+
{Pairs[6].first, Pairs[6].second}};
691707
this->addReflectionInfo(Info);
692708
return true;
693709
}

0 commit comments

Comments
 (0)