@@ -117,12 +117,62 @@ struct TypedExternal {
117117 template <typename T, bool Nullable = true , typename Offset = int32_t >
118118 using CompactFunctionPointer = TypedInteger<T, int32_t , Nullable>;
119119
120+ template <unsigned discriminator>
121+ struct ValueWitnessFunctionPointer {
122+ StoredPointer pointer;
123+ };
124+
120125 StoredPointer
121126 getStrippedSignedPointer (const StoredSignedPointer pointer) const {
122127 return swift_ptrauth_strip (pointer);
123128 }
124129};
125130
131+ using ExternalRuntime32 =
132+ swift::TypedExternal<swift::WithObjCInterop<swift::RuntimeTarget<4 >>>;
133+ using ExternalRuntime64 =
134+ swift::TypedExternal<swift::WithObjCInterop<swift::RuntimeTarget<8 >>>;
135+
136+ // Declare a specialized version of the value witness types that use a wrapper
137+ // on the functions that captures the ptrauth discriminator.
138+ template <>
139+ class TargetValueWitnessTypes <ExternalRuntime64> {
140+ public:
141+ using StoredPointer = typename ExternalRuntime64::StoredPointer;
142+
143+ #define WANT_ALL_VALUE_WITNESSES
144+ #define DATA_VALUE_WITNESS (lowerId, upperId, type )
145+ #define FUNCTION_VALUE_WITNESS (lowerId, upperId, returnType, paramTypes ) \
146+ typedef ExternalRuntime64::ValueWitnessFunctionPointer< \
147+ SpecialPointerAuthDiscriminators::upperId> \
148+ lowerId;
149+ #define MUTABLE_VALUE_TYPE TargetPointer<ExternalRuntime64, OpaqueValue>
150+ #define IMMUTABLE_VALUE_TYPE ConstTargetPointer<ExternalRuntime64, OpaqueValue>
151+ #define MUTABLE_BUFFER_TYPE TargetPointer<ExternalRuntime64, ValueBuffer>
152+ #define IMMUTABLE_BUFFER_TYPE ConstTargetPointer<ExternalRuntime64, ValueBuffer>
153+ #define TYPE_TYPE ConstTargetPointer<ExternalRuntime64, Metadata>
154+ #define SIZE_TYPE StoredSize
155+ #define INT_TYPE int
156+ #define UINT_TYPE unsigned
157+ #define VOID_TYPE void
158+ #include " swift/ABI/ValueWitness.def"
159+
160+ // Handle the data witnesses explicitly so we can use more specific
161+ // types for the flags enums.
162+ typedef size_t size;
163+ typedef size_t stride;
164+ typedef TargetValueWitnessFlags<typename ExternalRuntime64::StoredSize> flags;
165+ typedef uint32_t extraInhabitantCount;
166+ };
167+
168+ enum class PtrauthKey : int8_t {
169+ None = -1 ,
170+ IA = 0 ,
171+ IB = 1 ,
172+ DA = 2 ,
173+ DB = 3 ,
174+ };
175+
126176template <typename T>
127177inline MetadataKind getEnumeratedMetadataKind (T kind,
128178 decltype (kind.value) dummy = 0) {
@@ -188,6 +238,26 @@ class ReaderWriter;
188238
189239template <typename Runtime>
190240class ExternalGenericMetadataBuilderContext {
241+ // Structs that provide the ptrauth info for pointers to specific tyeps.
242+ template <typename Target>
243+ struct PtrauthInfo ;
244+
245+ template <>
246+ struct PtrauthInfo <const TargetValueTypeDescriptor<Runtime>> {
247+ static constexpr PtrauthKey key = PtrauthKey::DA;
248+ static constexpr bool addressDiversified = true ;
249+ static constexpr unsigned discriminator =
250+ SpecialPointerAuthDiscriminators::TypeDescriptor;
251+ };
252+
253+ template <>
254+ struct PtrauthInfo <const TargetValueWitnessTable<Runtime>> {
255+ static constexpr PtrauthKey key = PtrauthKey::DA;
256+ static constexpr bool addressDiversified = true ;
257+ static constexpr unsigned discriminator =
258+ SpecialPointerAuthDiscriminators::ValueWitnessTable;
259+ };
260+
191261 struct Atom ;
192262
193263 struct FileTarget {
@@ -207,6 +277,10 @@ class ExternalGenericMetadataBuilderContext {
207277 unsigned offset;
208278 unsigned size;
209279
280+ PtrauthKey ptrauthKey;
281+ bool addressDiversified;
282+ unsigned discriminator;
283+
210284 std::variant<FileTarget, AtomTarget> fileOrAtom;
211285 };
212286
@@ -512,7 +586,10 @@ class ExternalGenericMetadataBuilderContext {
512586 }
513587
514588 template <typename U>
515- void writePointerImpl (void *where, Buffer<U> value) {
589+ void writePointerImpl (void *where, Buffer<U> value,
590+ PtrauthKey ptrauthKey = PtrauthKey::None,
591+ bool addressDiversified = true ,
592+ unsigned discriminator = 0 ) {
516593 if (!value) {
517594 memset (where, 0 , sizeof (StoredPointer));
518595 return ;
@@ -530,6 +607,10 @@ class ExternalGenericMetadataBuilderContext {
530607
531608 target.size = sizeof (StoredPointer);
532609
610+ target.ptrauthKey = ptrauthKey;
611+ target.addressDiversified = addressDiversified;
612+ target.discriminator = discriminator;
613+
533614 if (auto *file = value.file ) {
534615 auto contents = value.section .getContents ();
535616 if (!contents) {
@@ -624,7 +705,9 @@ class ExternalGenericMetadataBuilderContext {
624705 checkPtr (where);
625706 where->SignedValue .value = ~(uintptr_t )value.ptr ;
626707
627- writePointerImpl (where, value);
708+ writePointerImpl (where, value, PtrauthInfo<U>::key,
709+ PtrauthInfo<U>::addressDiversified,
710+ PtrauthInfo<U>::discriminator);
628711 }
629712
630713 template <typename U>
@@ -638,6 +721,15 @@ class ExternalGenericMetadataBuilderContext {
638721 void writeFunctionPointer (void *where, Buffer<const char > target) {
639722 writePointer (reinterpret_cast <StoredPointer *>(where), target);
640723 }
724+
725+ template <unsigned discriminator>
726+ void writeFunctionPointer (
727+ ExternalRuntime64::ValueWitnessFunctionPointer<discriminator> *where,
728+ Buffer<const char > target) {
729+ checkPtr (where);
730+
731+ writePointerImpl (where, target, PtrauthKey::IA, true , discriminator);
732+ }
641733 };
642734
643735 ExternalGenericMetadataBuilderContext () {
@@ -660,7 +752,11 @@ class ExternalGenericMetadataBuilderContext {
660752 return allocate<T>(count * sizeof (T));
661753 }
662754
663- void setArch (const char *arch) { this ->arch = arch; }
755+ void setArch (const char *arch) {
756+ this ->arch = arch;
757+ this ->usePtrauth = this ->arch == " arm64e" ;
758+ }
759+
664760 void setNamesToBuild (const std::vector<std::string> &names) {
665761 this ->mangledNamesToBuild = names;
666762 }
@@ -723,6 +819,9 @@ class ExternalGenericMetadataBuilderContext {
723819 // The architecture being targeted.
724820 std::string arch;
725821
822+ // Does this target use pointer authentication?
823+ bool usePtrauth = false ;
824+
726825 // The readerWriter and builder helper objects.
727826 std::unique_ptr<ReaderWriter<Runtime>> readerWriter;
728827 std::unique_ptr<Builder> builder;
@@ -2127,6 +2226,14 @@ void ExternalGenericMetadataBuilderContext<Runtime>::writeAtomContentsJSON(
21272226 J.attribute (" addend" , atomTarget.offset );
21282227 J.attribute (" kind" , ptrTargetKind);
21292228 }
2229+
2230+ if (usePtrauth && targetsCursor->ptrauthKey != PtrauthKey::None) {
2231+ J.attributeObject (" authPtr" , [&] {
2232+ J.attribute (" key" , static_cast <uint8_t >(targetsCursor->ptrauthKey ));
2233+ J.attribute (" addr" , targetsCursor->addressDiversified );
2234+ J.attribute (" diversity" , targetsCursor->discriminator );
2235+ });
2236+ }
21302237 });
21312238
21322239 bufferCursor = targetsCursor->offset + targetsCursor->size ;
@@ -2286,16 +2393,11 @@ BuilderErrorOr<unsigned> getPointerWidth(std::string arch) {
22862393
22872394} // namespace swift
22882395
2289- using ExternalRuntime32 =
2290- swift::TypedExternal<swift::WithObjCInterop<swift::RuntimeTarget<4 >>>;
2291- using ExternalRuntime64 =
2292- swift::TypedExternal<swift::WithObjCInterop<swift::RuntimeTarget<8 >>>;
2293-
22942396struct SwiftExternalMetadataBuilder {
22952397 using Builder32 =
2296- swift::ExternalGenericMetadataBuilderContext<ExternalRuntime32>;
2398+ swift::ExternalGenericMetadataBuilderContext<swift:: ExternalRuntime32>;
22972399 using Builder64 =
2298- swift::ExternalGenericMetadataBuilderContext<ExternalRuntime64>;
2400+ swift::ExternalGenericMetadataBuilderContext<swift:: ExternalRuntime64>;
22992401
23002402 std::variant<Builder32, Builder64> context;
23012403
0 commit comments