aboutsummaryrefslogtreecommitdiff
path: root/libcxx/src/include/overridable_function.h
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/src/include/overridable_function.h')
-rw-r--r--libcxx/src/include/overridable_function.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/libcxx/src/include/overridable_function.h b/libcxx/src/include/overridable_function.h
index 7b0fba1..fca66ea 100644
--- a/libcxx/src/include/overridable_function.h
+++ b/libcxx/src/include/overridable_function.h
@@ -13,6 +13,10 @@
#include <__config>
#include <cstdint>
+#if defined(__arm64e__) && __has_feature(ptrauth_calls)
+# include <ptrauth.h>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
@@ -81,6 +85,14 @@ _LIBCPP_HIDE_FROM_ABI bool __is_function_overridden(_Ret (*__fptr)(_Args...)) no
uintptr_t __end = reinterpret_cast<uintptr_t>(&__lcxx_override_end);
uintptr_t __ptr = reinterpret_cast<uintptr_t>(__fptr);
+#if defined(__arm64e__) && __has_feature(ptrauth_calls)
+ // We must pass a void* to ptrauth_strip since it only accepts a pointer type. Also, in particular,
+ // we must NOT pass a function pointer, otherwise we will strip the function pointer, and then attempt
+ // to authenticate and re-sign it when casting it to a uintptr_t again, which will fail because we just
+ // stripped the function pointer. See rdar://122927845.
+ __ptr = reinterpret_cast<uintptr_t>(ptrauth_strip(reinterpret_cast<void*>(__ptr), ptrauth_key_function_pointer));
+#endif
+
// Finally, the function was overridden if it falls outside of the section's bounds.
return __ptr < __start || __ptr > __end;
}