-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[clang][PAC][NFC] Provide addition support macros to ptrauth.h #161027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-backend-x86 Author: Oliver Hunt (ojhunt) ChangesThis introduces a number of additional macros to support the use of manual pointer authentication. Full diff: https://github.com/llvm/llvm-project/pull/161027.diff 2 Files Affected:
diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst
index 96eb498bc48b6..eb4eaf08b854e 100644
--- a/clang/docs/PointerAuthentication.rst
+++ b/clang/docs/PointerAuthentication.rst
@@ -722,6 +722,40 @@ type. Implementations are not required to make all bits of the result equally
significant; in particular, some implementations are known to not leave
meaningful data in the low bits.
+``ptrauth_nop_cast``
+^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: c
+
+ ptrauth_nop_cast(__type, __value)
+
+Cast a pointer to the given type without changing any signature.
+
+This operation can be used to convert a value from one type to another without
+attempting to re-sign the value. This makes it possible to view a signed value
+of one type as another type signed with the same schema. This can be used to
+convert implicit schemas to explicit schemas, to convert to or from opaque
+types, or simply to change the effective underlying type of a signed value.
+
+The `__type` must be a pointer sized value compatible with the `__ptrauth`
+qualifier. The authentication schema must not include address diversity.
+
+The result is a bitwise identical value with the type passed as the `__type`
+argument.
+
+``ptrauth_function_pointer_type_discriminator``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: c
+
+ ptrauth_function_pointer_type_discriminator(__type)
+
+Compute the constant discriminator used by Clang to sign pointers with the
+given C function pointer type.
+
+A call to this function is an integer constant expression.
+
+
Standard ``__ptrauth`` qualifiers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h
index f902ca1e3bbd3..1544456e189b4 100644
--- a/clang/lib/Headers/ptrauth.h
+++ b/clang/lib/Headers/ptrauth.h
@@ -199,6 +199,23 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
ptrauth_auth_and_resign(__value, __old_key, __old_data, \
ptrauth_key_function_pointer, 0)
+/* Cast a value to the given type without changing any signature.
+
+ The type must be a pointer sized type compatible with the __ptrauth
+ qualifier.
+ The value must be an expression with a non-address diversified pointer
+ authentication schema, and will be converted to an rvalue prior to the cast.
+ The result has type given by the first argument.
+
+ The result has an identical bit-pattern to the input pointer. */
+#define ptrauth_nop_cast(__type, __value) \
+ ({ union { \
+ typeof(*(__value)) *__fptr; \
+ typeof(__type) __opaque; \
+ } __storage; \
+ __storage.__fptr = (__value); \
+ __storage.__opaque; })
+
/* Authenticate a data pointer.
The value must be an expression of non-function pointer type.
@@ -241,6 +258,18 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
#define ptrauth_type_discriminator(__type) \
__builtin_ptrauth_type_discriminator(__type)
+/* Compute the constant discriminator used by Clang to sign pointers with the
+ given C function pointer type.
+
+ A call to this function is an integer constant expression. */
+#if __has_feature(ptrauth_function_pointer_type_discrimination)
+#define ptrauth_function_pointer_type_discriminator(__type) \
+ __builtin_ptrauth_type_discriminator(__type)
+#else
+#define ptrauth_function_pointer_type_discriminator(__type) \
+ ((ptrauth_extra_data_t)0)
+#endif
+
/* Compute a signature for the given pair of pointer-sized values.
The order of the arguments is significant.
@@ -263,6 +292,33 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
#define ptrauth_sign_generic_data(__value, __data) \
__builtin_ptrauth_sign_generic_data(__value, __data)
+/* Define some standard __ptrauth qualifiers used in the ABI. */
+#define __ptrauth_function_pointer(__typekey) \
+ __ptrauth(ptrauth_key_function_pointer, 0, __typekey)
+#define __ptrauth_return_address \
+ __ptrauth(ptrauth_key_return_address, 1, 0)
+#define __ptrauth_block_invocation_pointer \
+ __ptrauth(ptrauth_key_function_pointer, 1, 0)
+#define __ptrauth_block_copy_helper \
+ __ptrauth(ptrauth_key_function_pointer, 1, 0)
+#define __ptrauth_block_destroy_helper \
+ __ptrauth(ptrauth_key_function_pointer, 1, 0)
+#define __ptrauth_block_byref_copy_helper \
+ __ptrauth(ptrauth_key_function_pointer, 1, 0)
+#define __ptrauth_block_byref_destroy_helper \
+ __ptrauth(ptrauth_key_function_pointer, 1, 0)
+#if __has_feature(ptrauth_signed_block_descriptors)
+#define __ptrauth_block_descriptor_pointer \
+ __ptrauth(ptrauth_key_block_descriptor_pointer, 1, 0xC0BB)
+#else
+#define __ptrauth_block_descriptor_pointer
+#endif
+
+#define __ptrauth_cxx_vtable_pointer \
+ __ptrauth(ptrauth_key_cxx_vtable_pointer, 0, 0)
+#define __ptrauth_cxx_vtt_vtable_pointer \
+ __ptrauth(ptrauth_key_cxx_vtable_pointer, 0, 0)
+
/* C++ vtable pointer signing class attribute */
#define ptrauth_cxx_vtable_pointer(key, address_discrimination, \
extra_discrimination...) \
@@ -371,7 +427,10 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
((ptrauth_extra_data_t)0); \
})
+#define ptrauth_nop_cast(__type, __value) (__type)(__value)
#define ptrauth_type_discriminator(__type) ((ptrauth_extra_data_t)0)
+#define ptrauth_function_pointer_type_discriminator(__type) \
+ ((ptrauth_extra_data_t)0)
#define ptrauth_sign_generic_data(__value, __data) \
({ \
@@ -384,9 +443,23 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
#define ptrauth_cxx_vtable_pointer(key, address_discrimination, \
extra_discrimination...)
+#define __ptrauth_function_pointer(__typekey)
+#define __ptrauth_return_address
+#define __ptrauth_block_invocation_pointer
+#define __ptrauth_block_copy_helper
+#define __ptrauth_block_destroy_helper
+#define __ptrauth_block_byref_copy_helper
+#define __ptrauth_block_byref_destroy_helper
+#define __ptrauth_block_descriptor_pointer
+#define __ptrauth_objc_method_list_imp
+#define __ptrauth_objc_method_list_pointer
#define __ptrauth_objc_isa_pointer
#define __ptrauth_objc_isa_uintptr
#define __ptrauth_objc_super_pointer
+#define __ptrauth_cxx_vtable_pointer
+#define __ptrauth_cxx_vtt_vtable_pointer
+#define __ptrauth_objc_sel
+#define __ptrauth_objc_class_ro
#endif /* __has_feature(ptrauth_intrinsics) || defined(__PTRAUTH__) */
|
@llvm/pr-subscribers-clang Author: Oliver Hunt (ojhunt) ChangesThis introduces a number of additional macros to support the use of manual pointer authentication. Full diff: https://github.com/llvm/llvm-project/pull/161027.diff 2 Files Affected:
diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst
index 96eb498bc48b6..eb4eaf08b854e 100644
--- a/clang/docs/PointerAuthentication.rst
+++ b/clang/docs/PointerAuthentication.rst
@@ -722,6 +722,40 @@ type. Implementations are not required to make all bits of the result equally
significant; in particular, some implementations are known to not leave
meaningful data in the low bits.
+``ptrauth_nop_cast``
+^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: c
+
+ ptrauth_nop_cast(__type, __value)
+
+Cast a pointer to the given type without changing any signature.
+
+This operation can be used to convert a value from one type to another without
+attempting to re-sign the value. This makes it possible to view a signed value
+of one type as another type signed with the same schema. This can be used to
+convert implicit schemas to explicit schemas, to convert to or from opaque
+types, or simply to change the effective underlying type of a signed value.
+
+The `__type` must be a pointer sized value compatible with the `__ptrauth`
+qualifier. The authentication schema must not include address diversity.
+
+The result is a bitwise identical value with the type passed as the `__type`
+argument.
+
+``ptrauth_function_pointer_type_discriminator``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: c
+
+ ptrauth_function_pointer_type_discriminator(__type)
+
+Compute the constant discriminator used by Clang to sign pointers with the
+given C function pointer type.
+
+A call to this function is an integer constant expression.
+
+
Standard ``__ptrauth`` qualifiers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h
index f902ca1e3bbd3..1544456e189b4 100644
--- a/clang/lib/Headers/ptrauth.h
+++ b/clang/lib/Headers/ptrauth.h
@@ -199,6 +199,23 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
ptrauth_auth_and_resign(__value, __old_key, __old_data, \
ptrauth_key_function_pointer, 0)
+/* Cast a value to the given type without changing any signature.
+
+ The type must be a pointer sized type compatible with the __ptrauth
+ qualifier.
+ The value must be an expression with a non-address diversified pointer
+ authentication schema, and will be converted to an rvalue prior to the cast.
+ The result has type given by the first argument.
+
+ The result has an identical bit-pattern to the input pointer. */
+#define ptrauth_nop_cast(__type, __value) \
+ ({ union { \
+ typeof(*(__value)) *__fptr; \
+ typeof(__type) __opaque; \
+ } __storage; \
+ __storage.__fptr = (__value); \
+ __storage.__opaque; })
+
/* Authenticate a data pointer.
The value must be an expression of non-function pointer type.
@@ -241,6 +258,18 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
#define ptrauth_type_discriminator(__type) \
__builtin_ptrauth_type_discriminator(__type)
+/* Compute the constant discriminator used by Clang to sign pointers with the
+ given C function pointer type.
+
+ A call to this function is an integer constant expression. */
+#if __has_feature(ptrauth_function_pointer_type_discrimination)
+#define ptrauth_function_pointer_type_discriminator(__type) \
+ __builtin_ptrauth_type_discriminator(__type)
+#else
+#define ptrauth_function_pointer_type_discriminator(__type) \
+ ((ptrauth_extra_data_t)0)
+#endif
+
/* Compute a signature for the given pair of pointer-sized values.
The order of the arguments is significant.
@@ -263,6 +292,33 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
#define ptrauth_sign_generic_data(__value, __data) \
__builtin_ptrauth_sign_generic_data(__value, __data)
+/* Define some standard __ptrauth qualifiers used in the ABI. */
+#define __ptrauth_function_pointer(__typekey) \
+ __ptrauth(ptrauth_key_function_pointer, 0, __typekey)
+#define __ptrauth_return_address \
+ __ptrauth(ptrauth_key_return_address, 1, 0)
+#define __ptrauth_block_invocation_pointer \
+ __ptrauth(ptrauth_key_function_pointer, 1, 0)
+#define __ptrauth_block_copy_helper \
+ __ptrauth(ptrauth_key_function_pointer, 1, 0)
+#define __ptrauth_block_destroy_helper \
+ __ptrauth(ptrauth_key_function_pointer, 1, 0)
+#define __ptrauth_block_byref_copy_helper \
+ __ptrauth(ptrauth_key_function_pointer, 1, 0)
+#define __ptrauth_block_byref_destroy_helper \
+ __ptrauth(ptrauth_key_function_pointer, 1, 0)
+#if __has_feature(ptrauth_signed_block_descriptors)
+#define __ptrauth_block_descriptor_pointer \
+ __ptrauth(ptrauth_key_block_descriptor_pointer, 1, 0xC0BB)
+#else
+#define __ptrauth_block_descriptor_pointer
+#endif
+
+#define __ptrauth_cxx_vtable_pointer \
+ __ptrauth(ptrauth_key_cxx_vtable_pointer, 0, 0)
+#define __ptrauth_cxx_vtt_vtable_pointer \
+ __ptrauth(ptrauth_key_cxx_vtable_pointer, 0, 0)
+
/* C++ vtable pointer signing class attribute */
#define ptrauth_cxx_vtable_pointer(key, address_discrimination, \
extra_discrimination...) \
@@ -371,7 +427,10 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
((ptrauth_extra_data_t)0); \
})
+#define ptrauth_nop_cast(__type, __value) (__type)(__value)
#define ptrauth_type_discriminator(__type) ((ptrauth_extra_data_t)0)
+#define ptrauth_function_pointer_type_discriminator(__type) \
+ ((ptrauth_extra_data_t)0)
#define ptrauth_sign_generic_data(__value, __data) \
({ \
@@ -384,9 +443,23 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
#define ptrauth_cxx_vtable_pointer(key, address_discrimination, \
extra_discrimination...)
+#define __ptrauth_function_pointer(__typekey)
+#define __ptrauth_return_address
+#define __ptrauth_block_invocation_pointer
+#define __ptrauth_block_copy_helper
+#define __ptrauth_block_destroy_helper
+#define __ptrauth_block_byref_copy_helper
+#define __ptrauth_block_byref_destroy_helper
+#define __ptrauth_block_descriptor_pointer
+#define __ptrauth_objc_method_list_imp
+#define __ptrauth_objc_method_list_pointer
#define __ptrauth_objc_isa_pointer
#define __ptrauth_objc_isa_uintptr
#define __ptrauth_objc_super_pointer
+#define __ptrauth_cxx_vtable_pointer
+#define __ptrauth_cxx_vtt_vtable_pointer
+#define __ptrauth_objc_sel
+#define __ptrauth_objc_class_ro
#endif /* __has_feature(ptrauth_intrinsics) || defined(__PTRAUTH__) */
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
This introduces a number of additional macros to support the use of manual pointer authentication.
d9c3119
to
6bc5400
Compare
Style differences a sufficiently minor that I'll take them and deal with future merge issues when they come up. |
This introduces a number of additional macros to support the use of manual pointer authentication.