Skip to content

Commit

Permalink
Merge pull request swiftlang#30112 from apple/mracek/arm64e
Browse files Browse the repository at this point in the history
Add arm64e and pointer authentication support for Swift
  • Loading branch information
kubamracek authored Mar 8, 2020
2 parents 1f62fe5 + 8a4a226 commit b2edf20
Show file tree
Hide file tree
Showing 183 changed files with 5,688 additions and 848 deletions.
2 changes: 1 addition & 1 deletion benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ endmacro()

macro(configure_sdks_darwin)
set(macosx_arch "x86_64")
set(iphoneos_arch "arm64" "armv7")
set(iphoneos_arch "arm64" "arm64e" "armv7")
set(appletvos_arch "arm64")
set(watchos_arch "armv7k")

Expand Down
4 changes: 2 additions & 2 deletions cmake/modules/DarwinSDKs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ option(SWIFT_ENABLE_IOS32
TRUE)

if(SWIFT_ENABLE_IOS32)
set(SUPPORTED_IOS_ARCHS "armv7;armv7s;arm64")
set(SUPPORTED_IOS_ARCHS "armv7;armv7s;arm64;arm64e")
set(SUPPORTED_IOS_SIMULATOR_ARCHS "i386;x86_64")
else()
set(SUPPORTED_IOS_ARCHS "arm64")
set(SUPPORTED_IOS_ARCHS "arm64;arm64e")
set(SUPPORTED_IOS_SIMULATOR_ARCHS "x86_64")
endif()

Expand Down
1 change: 1 addition & 0 deletions cmake/modules/SwiftSetIfArchBitness.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ function(set_if_arch_bitness var_name)
set("${var_name}" "${SIA_CASE_32_BIT}" PARENT_SCOPE)
elseif("${SIA_ARCH}" STREQUAL "x86_64" OR
"${SIA_ARCH}" STREQUAL "arm64" OR
"${SIA_ARCH}" STREQUAL "arm64e" OR
"${SIA_ARCH}" STREQUAL "aarch64" OR
"${SIA_ARCH}" STREQUAL "powerpc64" OR
"${SIA_ARCH}" STREQUAL "powerpc64le" OR
Expand Down
126 changes: 93 additions & 33 deletions include/swift/ABI/Metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ struct RuntimeTarget;
template <>
struct RuntimeTarget<4> {
using StoredPointer = uint32_t;
// To avoid implicit conversions from StoredSignedPointer to StoredPointer.
using StoredSignedPointer = struct {
uint32_t SignedValue;
};
using StoredSize = uint32_t;
using StoredPointerDifference = int32_t;
static constexpr size_t PointerSize = 4;
Expand All @@ -61,6 +65,10 @@ struct RuntimeTarget<4> {
template <>
struct RuntimeTarget<8> {
using StoredPointer = uint64_t;
// To avoid implicit conversions from StoredSignedPointer to StoredPointer.
using StoredSignedPointer = struct {
uint64_t SignedValue;
};
using StoredSize = uint64_t;
using StoredPointerDifference = int64_t;
static constexpr size_t PointerSize = 8;
Expand All @@ -77,6 +85,7 @@ namespace reflection {
struct InProcess {
static constexpr size_t PointerSize = sizeof(uintptr_t);
using StoredPointer = uintptr_t;
using StoredSignedPointer = uintptr_t;
using StoredSize = size_t;
using StoredPointerDifference = ptrdiff_t;

Expand All @@ -85,6 +94,9 @@ struct InProcess {

template <typename T>
using Pointer = T*;

template <typename T>
using SignedPointer = T;

template <typename T, bool Nullable = false>
using FarRelativeDirectPointer = FarRelativeDirectPointer<T, Nullable>;
Expand All @@ -111,13 +123,17 @@ struct ExternalPointer {
template <typename Runtime>
struct External {
using StoredPointer = typename Runtime::StoredPointer;
using StoredSignedPointer = typename Runtime::StoredSignedPointer;
using StoredSize = typename Runtime::StoredSize;
using StoredPointerDifference = typename Runtime::StoredPointerDifference;
static constexpr size_t PointerSize = Runtime::PointerSize;
const StoredPointer PointerValue;

template <typename T>
using Pointer = StoredPointer;

template <typename T>
using SignedPointer = StoredSignedPointer;

template <typename T, bool Nullable = false>
using FarRelativeDirectPointer = StoredPointer;
Expand All @@ -141,9 +157,13 @@ using ConstTargetMetadataPointer
template <typename Runtime, typename T>
using TargetPointer = typename Runtime::template Pointer<T>;

template <typename Runtime, typename T>
using TargetSignedPointer = typename Runtime::template SignedPointer<T>;

template <typename Runtime, typename T>
using ConstTargetPointer = typename Runtime::template Pointer<const T>;


template <typename Runtime, template <typename> class Pointee,
bool Nullable = true>
using ConstTargetFarRelativeDirectPointer
Expand Down Expand Up @@ -281,7 +301,10 @@ class TargetValueWitnessTypes {
#define WANT_ALL_VALUE_WITNESSES
#define DATA_VALUE_WITNESS(lowerId, upperId, type)
#define FUNCTION_VALUE_WITNESS(lowerId, upperId, returnType, paramTypes) \
typedef TargetPointer<Runtime, returnType paramTypes> lowerId;
typedef returnType (*lowerId ## Unsigned) paramTypes; \
typedef TargetSignedPointer<Runtime, lowerId ## Unsigned \
__ptrauth_swift_value_witness_function_pointer( \
SpecialPointerAuthDiscriminators::upperId)> lowerId;
#define MUTABLE_VALUE_TYPE TargetPointer<Runtime, OpaqueValue>
#define IMMUTABLE_VALUE_TYPE ConstTargetPointer<Runtime, OpaqueValue>
#define MUTABLE_BUFFER_TYPE TargetPointer<Runtime, ValueBuffer>
Expand Down Expand Up @@ -314,6 +337,9 @@ template <typename Runtime> struct TargetValueWitnessTable {
#define WANT_ONLY_REQUIRED_VALUE_WITNESSES
#define VALUE_WITNESS(LOWER_ID, UPPER_ID) \
typename TargetValueWitnessTypes<Runtime>::LOWER_ID LOWER_ID;
#define FUNCTION_VALUE_WITNESS(LOWER_ID, UPPER_ID, RET, PARAMS) \
typename TargetValueWitnessTypes<Runtime>::LOWER_ID LOWER_ID;

#include "swift/ABI/ValueWitness.def"

using StoredSize = typename Runtime::StoredSize;
Expand Down Expand Up @@ -595,7 +621,7 @@ struct TargetMetadata {
#define WANT_ONLY_REQUIRED_VALUE_WITNESSES
#define FUNCTION_VALUE_WITNESS(WITNESS, UPPER, RET_TYPE, PARAM_TYPES) \
template<typename...A> \
_ResultOf<ValueWitnessTypes::WITNESS>::type \
_ResultOf<ValueWitnessTypes::WITNESS ## Unsigned>::type \
vw_##WITNESS(A &&...args) const { \
return getValueWitnesses()->WITNESS(std::forward<A>(args)..., this); \
}
Expand Down Expand Up @@ -744,7 +770,7 @@ template <typename Runtime>
struct TargetHeapMetadataHeaderPrefix {
/// Destroy the object, returning the allocated size of the object
/// or 0 if the object shouldn't be deallocated.
TargetPointer<Runtime, HeapObjectDestroyer> destroy;
TargetSignedPointer<Runtime, HeapObjectDestroyer *__ptrauth_swift_heap_object_destructor> destroy;
};
using HeapMetadataHeaderPrefix =
TargetHeapMetadataHeaderPrefix<InProcess>;
Expand Down Expand Up @@ -838,18 +864,26 @@ struct TargetVTableDescriptorHeader {

template<typename Runtime> struct TargetContextDescriptor;

template<typename Runtime>
template<typename Runtime,
template<typename _Runtime> class Context = TargetContextDescriptor>
using TargetSignedContextPointer = TargetSignedPointer<Runtime,
Context<Runtime> * __ptrauth_swift_type_descriptor>;

template<typename Runtime,
template<typename _Runtime> class Context = TargetContextDescriptor>
using TargetRelativeContextPointer =
RelativeIndirectablePointer<const TargetContextDescriptor<Runtime>,
/*nullable*/ true>;
RelativeIndirectablePointer<const Context<Runtime>,
/*nullable*/ true, int32_t,
TargetSignedContextPointer<Runtime, Context>>;

using RelativeContextPointer = TargetRelativeContextPointer<InProcess>;

template<typename Runtime, typename IntTy,
template<typename _Runtime> class Context = TargetContextDescriptor>
using RelativeContextPointerIntPair =
RelativeIndirectablePointerIntPair<const Context<Runtime>, IntTy,
/*nullable*/ true, int32_t>;
/*nullable*/ true, int32_t,
TargetSignedContextPointer<Runtime, Context>>;

template<typename Runtime> struct TargetMethodDescriptor;

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

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

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

typename Runtime::StoredSignedPointer
getDescriptionAsSignedPointer() const {
assert(isTypeMetadata());
return Description;
}

void setDescription(const TargetClassDescriptor<Runtime> *description) {
Description = description;
}
Expand Down Expand Up @@ -1314,7 +1354,7 @@ struct TargetForeignClassMetadata : public TargetForeignTypeMetadata<Runtime> {
using StoredPointer = typename Runtime::StoredPointer;

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

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

typename Runtime::StoredSignedPointer
getDescriptionAsSignedPointer() const {
return Description;
}

static bool classof(const TargetMetadata<Runtime> *metadata) {
return metadata->getKind() == MetadataKind::ForeignClass;
}
Expand All @@ -1345,8 +1390,7 @@ struct TargetValueMetadata : public TargetMetadata<Runtime> {
: TargetMetadata<Runtime>(Kind), Description(description) {}

/// An out-of-line description of the type.
ConstTargetMetadataPointer<Runtime, TargetValueTypeDescriptor>
Description;
TargetSignedPointer<Runtime, const TargetValueTypeDescriptor<Runtime> * __ptrauth_swift_type_descriptor> Description;

static bool classof(const TargetMetadata<Runtime> *metadata) {
return metadata->getKind() == MetadataKind::Struct
Expand All @@ -1358,6 +1402,11 @@ struct TargetValueMetadata : public TargetMetadata<Runtime> {
getDescription() const {
return Description;
}

typename Runtime::StoredSignedPointer
getDescriptionAsSignedPointer() const {
return Description;
}
};
using ValueMetadata = TargetValueMetadata<InProcess>;

Expand Down Expand Up @@ -2189,7 +2238,7 @@ struct TargetTypeMetadataRecord {
DirectNominalTypeDescriptor;

/// An indirect reference to a nominal type descriptor.
RelativeDirectPointerIntPair<TargetContextDescriptor<Runtime> * const,
RelativeDirectPointerIntPair<TargetSignedPointer<Runtime, TargetContextDescriptor<Runtime> * __ptrauth_swift_type_descriptor>,
TypeReferenceKind>
IndirectNominalTypeDescriptor;

Expand Down Expand Up @@ -2242,24 +2291,25 @@ template<typename Runtime> class TargetGenericRequirementDescriptor;
/// pointer equivalent to \c TargetProtocolDescriptorRef.
template <typename Runtime>
class RelativeTargetProtocolDescriptorPointer {
union AnyProtocol {
TargetProtocolDescriptor<Runtime> descriptor;
union {
/// Relative pointer to a Swift protocol descriptor.
/// The \c bool value will be false to indicate that the protocol
/// is a Swift protocol, or true to indicate that this references
/// an Objective-C protocol.
RelativeContextPointerIntPair<Runtime, bool, TargetProtocolDescriptor>
swiftPointer;
#if SWIFT_OBJC_INTEROP
/// Relative pointer to an ObjC protocol descriptor.
/// The \c bool value will be false to indicate that the protocol
/// is a Swift protocol, or true to indicate that this references
/// an Objective-C protocol.
RelativeIndirectablePointerIntPair<Protocol, bool> objcPointer;
#endif
};

/// The relative pointer itself.
///
/// The \c AnyProtocol value type ensures that we can reference any
/// protocol descriptor; it will be reinterpret_cast to the appropriate
/// protocol descriptor type.
///
/// The \c bool integer value will be false to indicate that the protocol
/// is a Swift protocol, or true to indicate that this references
/// an Objective-C protocol.
RelativeIndirectablePointerIntPair<AnyProtocol, bool> pointer;

#if SWIFT_OBJC_INTEROP
bool isObjC() const {
return pointer.getInt();
return objcPointer.getInt();
}
#endif

Expand All @@ -2269,13 +2319,13 @@ class RelativeTargetProtocolDescriptorPointer {
#if SWIFT_OBJC_INTEROP
if (isObjC()) {
return TargetProtocolDescriptorRef<Runtime>::forObjC(
protocol_const_cast(pointer.getPointer()));
const_cast<Protocol*>(objcPointer.getPointer()));
}
#endif

return TargetProtocolDescriptorRef<Runtime>::forSwift(
reinterpret_cast<ConstTargetMetadataPointer<
Runtime, TargetProtocolDescriptor>>(pointer.getPointer()));
Runtime, TargetProtocolDescriptor>>(swiftPointer.getPointer()));
}

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

/// An indirect reference to a TypeContextDescriptor or ProtocolDescriptor.
RelativeDirectPointer<
ConstTargetMetadataPointer<Runtime, TargetContextDescriptor>>
TargetSignedPointer<Runtime, TargetContextDescriptor<Runtime> * __ptrauth_swift_type_descriptor>>
IndirectTypeDescriptor;

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

private:
/// The protocol being conformed to.
RelativeIndirectablePointer<ProtocolDescriptor> Protocol;
TargetRelativeContextPointer<Runtime, TargetProtocolDescriptor> Protocol;

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

const TargetContextDescriptor<Runtime> **_getTypeDescriptorLocation() const {
TargetContextDescriptor<Runtime> * __ptrauth_swift_type_descriptor *
_getTypeDescriptorLocation() const {
if (getTypeKind() != TypeReferenceKind::IndirectTypeDescriptor)
return nullptr;
return TypeRef.IndirectTypeDescriptor.get();
Expand Down Expand Up @@ -4490,11 +4541,20 @@ struct DynamicReplacementChainEntry {
struct DynamicReplacementKey {
RelativeDirectPointer<DynamicReplacementChainEntry, false> root;
uint32_t flags;

uint16_t getExtraDiscriminator() const {
return flags & 0x0000FFFF;
}
};

/// A record describing a dynamic function replacement.
class DynamicReplacementDescriptor {
RelativeIndirectablePointer<DynamicReplacementKey, false> replacedFunctionKey;
RelativeIndirectablePointer<
const DynamicReplacementKey, false, int32_t,
TargetSignedPointer<InProcess,
DynamicReplacementKey *
__ptrauth_swift_dynamic_replacement_key>>
replacedFunctionKey;
RelativeDirectPointer<void, false> replacementFunction;
RelativeDirectPointer<DynamicReplacementChainEntry, false> chainEntry;
uint32_t flags;
Expand Down
Loading

0 comments on commit b2edf20

Please sign in to comment.