Skip to content

Commit b2edf20

Browse files
authored
Merge pull request swiftlang#30112 from apple/mracek/arm64e
Add arm64e and pointer authentication support for Swift
2 parents 1f62fe5 + 8a4a226 commit b2edf20

File tree

183 files changed

+5688
-848
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

183 files changed

+5688
-848
lines changed

benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ endmacro()
106106

107107
macro(configure_sdks_darwin)
108108
set(macosx_arch "x86_64")
109-
set(iphoneos_arch "arm64" "armv7")
109+
set(iphoneos_arch "arm64" "arm64e" "armv7")
110110
set(appletvos_arch "arm64")
111111
set(watchos_arch "armv7k")
112112

cmake/modules/DarwinSDKs.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ option(SWIFT_ENABLE_IOS32
33
TRUE)
44

55
if(SWIFT_ENABLE_IOS32)
6-
set(SUPPORTED_IOS_ARCHS "armv7;armv7s;arm64")
6+
set(SUPPORTED_IOS_ARCHS "armv7;armv7s;arm64;arm64e")
77
set(SUPPORTED_IOS_SIMULATOR_ARCHS "i386;x86_64")
88
else()
9-
set(SUPPORTED_IOS_ARCHS "arm64")
9+
set(SUPPORTED_IOS_ARCHS "arm64;arm64e")
1010
set(SUPPORTED_IOS_SIMULATOR_ARCHS "x86_64")
1111
endif()
1212

cmake/modules/SwiftSetIfArchBitness.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ function(set_if_arch_bitness var_name)
1616
set("${var_name}" "${SIA_CASE_32_BIT}" PARENT_SCOPE)
1717
elseif("${SIA_ARCH}" STREQUAL "x86_64" OR
1818
"${SIA_ARCH}" STREQUAL "arm64" OR
19+
"${SIA_ARCH}" STREQUAL "arm64e" OR
1920
"${SIA_ARCH}" STREQUAL "aarch64" OR
2021
"${SIA_ARCH}" STREQUAL "powerpc64" OR
2122
"${SIA_ARCH}" STREQUAL "powerpc64le" OR

include/swift/ABI/Metadata.h

Lines changed: 93 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ struct RuntimeTarget;
5353
template <>
5454
struct RuntimeTarget<4> {
5555
using StoredPointer = uint32_t;
56+
// To avoid implicit conversions from StoredSignedPointer to StoredPointer.
57+
using StoredSignedPointer = struct {
58+
uint32_t SignedValue;
59+
};
5660
using StoredSize = uint32_t;
5761
using StoredPointerDifference = int32_t;
5862
static constexpr size_t PointerSize = 4;
@@ -61,6 +65,10 @@ struct RuntimeTarget<4> {
6165
template <>
6266
struct RuntimeTarget<8> {
6367
using StoredPointer = uint64_t;
68+
// To avoid implicit conversions from StoredSignedPointer to StoredPointer.
69+
using StoredSignedPointer = struct {
70+
uint64_t SignedValue;
71+
};
6472
using StoredSize = uint64_t;
6573
using StoredPointerDifference = int64_t;
6674
static constexpr size_t PointerSize = 8;
@@ -77,6 +85,7 @@ namespace reflection {
7785
struct InProcess {
7886
static constexpr size_t PointerSize = sizeof(uintptr_t);
7987
using StoredPointer = uintptr_t;
88+
using StoredSignedPointer = uintptr_t;
8089
using StoredSize = size_t;
8190
using StoredPointerDifference = ptrdiff_t;
8291

@@ -85,6 +94,9 @@ struct InProcess {
8594

8695
template <typename T>
8796
using Pointer = T*;
97+
98+
template <typename T>
99+
using SignedPointer = T;
88100

89101
template <typename T, bool Nullable = false>
90102
using FarRelativeDirectPointer = FarRelativeDirectPointer<T, Nullable>;
@@ -111,13 +123,17 @@ struct ExternalPointer {
111123
template <typename Runtime>
112124
struct External {
113125
using StoredPointer = typename Runtime::StoredPointer;
126+
using StoredSignedPointer = typename Runtime::StoredSignedPointer;
114127
using StoredSize = typename Runtime::StoredSize;
115128
using StoredPointerDifference = typename Runtime::StoredPointerDifference;
116129
static constexpr size_t PointerSize = Runtime::PointerSize;
117130
const StoredPointer PointerValue;
118131

119132
template <typename T>
120133
using Pointer = StoredPointer;
134+
135+
template <typename T>
136+
using SignedPointer = StoredSignedPointer;
121137

122138
template <typename T, bool Nullable = false>
123139
using FarRelativeDirectPointer = StoredPointer;
@@ -141,9 +157,13 @@ using ConstTargetMetadataPointer
141157
template <typename Runtime, typename T>
142158
using TargetPointer = typename Runtime::template Pointer<T>;
143159

160+
template <typename Runtime, typename T>
161+
using TargetSignedPointer = typename Runtime::template SignedPointer<T>;
162+
144163
template <typename Runtime, typename T>
145164
using ConstTargetPointer = typename Runtime::template Pointer<const T>;
146165

166+
147167
template <typename Runtime, template <typename> class Pointee,
148168
bool Nullable = true>
149169
using ConstTargetFarRelativeDirectPointer
@@ -281,7 +301,10 @@ class TargetValueWitnessTypes {
281301
#define WANT_ALL_VALUE_WITNESSES
282302
#define DATA_VALUE_WITNESS(lowerId, upperId, type)
283303
#define FUNCTION_VALUE_WITNESS(lowerId, upperId, returnType, paramTypes) \
284-
typedef TargetPointer<Runtime, returnType paramTypes> lowerId;
304+
typedef returnType (*lowerId ## Unsigned) paramTypes; \
305+
typedef TargetSignedPointer<Runtime, lowerId ## Unsigned \
306+
__ptrauth_swift_value_witness_function_pointer( \
307+
SpecialPointerAuthDiscriminators::upperId)> lowerId;
285308
#define MUTABLE_VALUE_TYPE TargetPointer<Runtime, OpaqueValue>
286309
#define IMMUTABLE_VALUE_TYPE ConstTargetPointer<Runtime, OpaqueValue>
287310
#define MUTABLE_BUFFER_TYPE TargetPointer<Runtime, ValueBuffer>
@@ -314,6 +337,9 @@ template <typename Runtime> struct TargetValueWitnessTable {
314337
#define WANT_ONLY_REQUIRED_VALUE_WITNESSES
315338
#define VALUE_WITNESS(LOWER_ID, UPPER_ID) \
316339
typename TargetValueWitnessTypes<Runtime>::LOWER_ID LOWER_ID;
340+
#define FUNCTION_VALUE_WITNESS(LOWER_ID, UPPER_ID, RET, PARAMS) \
341+
typename TargetValueWitnessTypes<Runtime>::LOWER_ID LOWER_ID;
342+
317343
#include "swift/ABI/ValueWitness.def"
318344

319345
using StoredSize = typename Runtime::StoredSize;
@@ -595,7 +621,7 @@ struct TargetMetadata {
595621
#define WANT_ONLY_REQUIRED_VALUE_WITNESSES
596622
#define FUNCTION_VALUE_WITNESS(WITNESS, UPPER, RET_TYPE, PARAM_TYPES) \
597623
template<typename...A> \
598-
_ResultOf<ValueWitnessTypes::WITNESS>::type \
624+
_ResultOf<ValueWitnessTypes::WITNESS ## Unsigned>::type \
599625
vw_##WITNESS(A &&...args) const { \
600626
return getValueWitnesses()->WITNESS(std::forward<A>(args)..., this); \
601627
}
@@ -744,7 +770,7 @@ template <typename Runtime>
744770
struct TargetHeapMetadataHeaderPrefix {
745771
/// Destroy the object, returning the allocated size of the object
746772
/// or 0 if the object shouldn't be deallocated.
747-
TargetPointer<Runtime, HeapObjectDestroyer> destroy;
773+
TargetSignedPointer<Runtime, HeapObjectDestroyer *__ptrauth_swift_heap_object_destructor> destroy;
748774
};
749775
using HeapMetadataHeaderPrefix =
750776
TargetHeapMetadataHeaderPrefix<InProcess>;
@@ -838,18 +864,26 @@ struct TargetVTableDescriptorHeader {
838864

839865
template<typename Runtime> struct TargetContextDescriptor;
840866

841-
template<typename Runtime>
867+
template<typename Runtime,
868+
template<typename _Runtime> class Context = TargetContextDescriptor>
869+
using TargetSignedContextPointer = TargetSignedPointer<Runtime,
870+
Context<Runtime> * __ptrauth_swift_type_descriptor>;
871+
872+
template<typename Runtime,
873+
template<typename _Runtime> class Context = TargetContextDescriptor>
842874
using TargetRelativeContextPointer =
843-
RelativeIndirectablePointer<const TargetContextDescriptor<Runtime>,
844-
/*nullable*/ true>;
875+
RelativeIndirectablePointer<const Context<Runtime>,
876+
/*nullable*/ true, int32_t,
877+
TargetSignedContextPointer<Runtime, Context>>;
845878

846879
using RelativeContextPointer = TargetRelativeContextPointer<InProcess>;
847880

848881
template<typename Runtime, typename IntTy,
849882
template<typename _Runtime> class Context = TargetContextDescriptor>
850883
using RelativeContextPointerIntPair =
851884
RelativeIndirectablePointerIntPair<const Context<Runtime>, IntTy,
852-
/*nullable*/ true, int32_t>;
885+
/*nullable*/ true, int32_t,
886+
TargetSignedContextPointer<Runtime, Context>>;
853887

854888
template<typename Runtime> struct TargetMethodDescriptor;
855889

@@ -1085,13 +1119,13 @@ struct TargetClassMetadata : public TargetAnyClassMetadata<Runtime> {
10851119
/// if this is an artificial subclass. We currently provide no
10861120
/// supported mechanism for making a non-artificial subclass
10871121
/// dynamically.
1088-
ConstTargetMetadataPointer<Runtime, TargetClassDescriptor> Description;
1122+
TargetSignedPointer<Runtime, const TargetClassDescriptor<Runtime> * __ptrauth_swift_type_descriptor> Description;
10891123

10901124
public:
10911125
/// A function for destroying instance variables, used to clean up after an
10921126
/// early return from a constructor. If null, no clean up will be performed
10931127
/// and all ivars must be trivial.
1094-
TargetPointer<Runtime, ClassIVarDestroyer> IVarDestroyer;
1128+
TargetSignedPointer<Runtime, ClassIVarDestroyer * __ptrauth_swift_heap_object_destructor> IVarDestroyer;
10951129

10961130
// After this come the class members, laid out as follows:
10971131
// - class members for the superclass (recursively)
@@ -1108,6 +1142,12 @@ struct TargetClassMetadata : public TargetAnyClassMetadata<Runtime> {
11081142
return Description;
11091143
}
11101144

1145+
typename Runtime::StoredSignedPointer
1146+
getDescriptionAsSignedPointer() const {
1147+
assert(isTypeMetadata());
1148+
return Description;
1149+
}
1150+
11111151
void setDescription(const TargetClassDescriptor<Runtime> *description) {
11121152
Description = description;
11131153
}
@@ -1314,7 +1354,7 @@ struct TargetForeignClassMetadata : public TargetForeignTypeMetadata<Runtime> {
13141354
using StoredPointer = typename Runtime::StoredPointer;
13151355

13161356
/// An out-of-line description of the type.
1317-
ConstTargetMetadataPointer<Runtime, TargetClassDescriptor> Description;
1357+
TargetSignedPointer<Runtime, const TargetClassDescriptor<Runtime> * __ptrauth_swift_type_descriptor> Description;
13181358

13191359
/// The superclass of the foreign class, if any.
13201360
ConstTargetMetadataPointer<Runtime, swift::TargetForeignClassMetadata>
@@ -1330,6 +1370,11 @@ struct TargetForeignClassMetadata : public TargetForeignTypeMetadata<Runtime> {
13301370
return Description;
13311371
}
13321372

1373+
typename Runtime::StoredSignedPointer
1374+
getDescriptionAsSignedPointer() const {
1375+
return Description;
1376+
}
1377+
13331378
static bool classof(const TargetMetadata<Runtime> *metadata) {
13341379
return metadata->getKind() == MetadataKind::ForeignClass;
13351380
}
@@ -1345,8 +1390,7 @@ struct TargetValueMetadata : public TargetMetadata<Runtime> {
13451390
: TargetMetadata<Runtime>(Kind), Description(description) {}
13461391

13471392
/// An out-of-line description of the type.
1348-
ConstTargetMetadataPointer<Runtime, TargetValueTypeDescriptor>
1349-
Description;
1393+
TargetSignedPointer<Runtime, const TargetValueTypeDescriptor<Runtime> * __ptrauth_swift_type_descriptor> Description;
13501394

13511395
static bool classof(const TargetMetadata<Runtime> *metadata) {
13521396
return metadata->getKind() == MetadataKind::Struct
@@ -1358,6 +1402,11 @@ struct TargetValueMetadata : public TargetMetadata<Runtime> {
13581402
getDescription() const {
13591403
return Description;
13601404
}
1405+
1406+
typename Runtime::StoredSignedPointer
1407+
getDescriptionAsSignedPointer() const {
1408+
return Description;
1409+
}
13611410
};
13621411
using ValueMetadata = TargetValueMetadata<InProcess>;
13631412

@@ -2189,7 +2238,7 @@ struct TargetTypeMetadataRecord {
21892238
DirectNominalTypeDescriptor;
21902239

21912240
/// An indirect reference to a nominal type descriptor.
2192-
RelativeDirectPointerIntPair<TargetContextDescriptor<Runtime> * const,
2241+
RelativeDirectPointerIntPair<TargetSignedPointer<Runtime, TargetContextDescriptor<Runtime> * __ptrauth_swift_type_descriptor>,
21932242
TypeReferenceKind>
21942243
IndirectNominalTypeDescriptor;
21952244

@@ -2242,24 +2291,25 @@ template<typename Runtime> class TargetGenericRequirementDescriptor;
22422291
/// pointer equivalent to \c TargetProtocolDescriptorRef.
22432292
template <typename Runtime>
22442293
class RelativeTargetProtocolDescriptorPointer {
2245-
union AnyProtocol {
2246-
TargetProtocolDescriptor<Runtime> descriptor;
2294+
union {
2295+
/// Relative pointer to a Swift protocol descriptor.
2296+
/// The \c bool value will be false to indicate that the protocol
2297+
/// is a Swift protocol, or true to indicate that this references
2298+
/// an Objective-C protocol.
2299+
RelativeContextPointerIntPair<Runtime, bool, TargetProtocolDescriptor>
2300+
swiftPointer;
2301+
#if SWIFT_OBJC_INTEROP
2302+
/// Relative pointer to an ObjC protocol descriptor.
2303+
/// The \c bool value will be false to indicate that the protocol
2304+
/// is a Swift protocol, or true to indicate that this references
2305+
/// an Objective-C protocol.
2306+
RelativeIndirectablePointerIntPair<Protocol, bool> objcPointer;
2307+
#endif
22472308
};
22482309

2249-
/// The relative pointer itself.
2250-
///
2251-
/// The \c AnyProtocol value type ensures that we can reference any
2252-
/// protocol descriptor; it will be reinterpret_cast to the appropriate
2253-
/// protocol descriptor type.
2254-
///
2255-
/// The \c bool integer value will be false to indicate that the protocol
2256-
/// is a Swift protocol, or true to indicate that this references
2257-
/// an Objective-C protocol.
2258-
RelativeIndirectablePointerIntPair<AnyProtocol, bool> pointer;
2259-
22602310
#if SWIFT_OBJC_INTEROP
22612311
bool isObjC() const {
2262-
return pointer.getInt();
2312+
return objcPointer.getInt();
22632313
}
22642314
#endif
22652315

@@ -2269,13 +2319,13 @@ class RelativeTargetProtocolDescriptorPointer {
22692319
#if SWIFT_OBJC_INTEROP
22702320
if (isObjC()) {
22712321
return TargetProtocolDescriptorRef<Runtime>::forObjC(
2272-
protocol_const_cast(pointer.getPointer()));
2322+
const_cast<Protocol*>(objcPointer.getPointer()));
22732323
}
22742324
#endif
22752325

22762326
return TargetProtocolDescriptorRef<Runtime>::forSwift(
22772327
reinterpret_cast<ConstTargetMetadataPointer<
2278-
Runtime, TargetProtocolDescriptor>>(pointer.getPointer()));
2328+
Runtime, TargetProtocolDescriptor>>(swiftPointer.getPointer()));
22792329
}
22802330

22812331
operator TargetProtocolDescriptorRef<Runtime>() const {
@@ -2293,7 +2343,7 @@ struct TargetTypeReference {
22932343

22942344
/// An indirect reference to a TypeContextDescriptor or ProtocolDescriptor.
22952345
RelativeDirectPointer<
2296-
ConstTargetMetadataPointer<Runtime, TargetContextDescriptor>>
2346+
TargetSignedPointer<Runtime, TargetContextDescriptor<Runtime> * __ptrauth_swift_type_descriptor>>
22972347
IndirectTypeDescriptor;
22982348

22992349
/// An indirect reference to an Objective-C class.
@@ -2391,7 +2441,7 @@ struct TargetProtocolConformanceDescriptor final
23912441

23922442
private:
23932443
/// The protocol being conformed to.
2394-
RelativeIndirectablePointer<ProtocolDescriptor> Protocol;
2444+
TargetRelativeContextPointer<Runtime, TargetProtocolDescriptor> Protocol;
23952445

23962446
// Some description of the type that conforms to the protocol.
23972447
TargetTypeReference<Runtime> TypeRef;
@@ -2424,7 +2474,8 @@ struct TargetProtocolConformanceDescriptor final
24242474
return TypeRef.getTypeDescriptor(getTypeKind());
24252475
}
24262476

2427-
const TargetContextDescriptor<Runtime> **_getTypeDescriptorLocation() const {
2477+
TargetContextDescriptor<Runtime> * __ptrauth_swift_type_descriptor *
2478+
_getTypeDescriptorLocation() const {
24282479
if (getTypeKind() != TypeReferenceKind::IndirectTypeDescriptor)
24292480
return nullptr;
24302481
return TypeRef.IndirectTypeDescriptor.get();
@@ -4490,11 +4541,20 @@ struct DynamicReplacementChainEntry {
44904541
struct DynamicReplacementKey {
44914542
RelativeDirectPointer<DynamicReplacementChainEntry, false> root;
44924543
uint32_t flags;
4544+
4545+
uint16_t getExtraDiscriminator() const {
4546+
return flags & 0x0000FFFF;
4547+
}
44934548
};
44944549

44954550
/// A record describing a dynamic function replacement.
44964551
class DynamicReplacementDescriptor {
4497-
RelativeIndirectablePointer<DynamicReplacementKey, false> replacedFunctionKey;
4552+
RelativeIndirectablePointer<
4553+
const DynamicReplacementKey, false, int32_t,
4554+
TargetSignedPointer<InProcess,
4555+
DynamicReplacementKey *
4556+
__ptrauth_swift_dynamic_replacement_key>>
4557+
replacedFunctionKey;
44984558
RelativeDirectPointer<void, false> replacementFunction;
44994559
RelativeDirectPointer<DynamicReplacementChainEntry, false> chainEntry;
45004560
uint32_t flags;

0 commit comments

Comments
 (0)