[libcxx-commits] [libcxx] [libcxx] Use local names for the operator new impl symbols (PR #122983)
Petr Hosek via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jan 20 22:35:44 PST 2025
https://github.com/petrhosek updated https://github.com/llvm/llvm-project/pull/122983
>From 6c665275b6b94b9ea29cc75df53ce84ed28d019d Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Tue, 14 Jan 2025 14:47:47 -0800
Subject: [PATCH 1/7] [libcxx] Use local names for the operator new impl
symbols
This way the impl symbols don't even make it into the symbol table which
is important for symbolization since we want the symbolizer to always
pick up the public symbol (which has the same address as the impl one).
---
libcxx/src/include/overridable_function.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/src/include/overridable_function.h b/libcxx/src/include/overridable_function.h
index 7372e347831bb4..71feebf0c15b20 100644
--- a/libcxx/src/include/overridable_function.h
+++ b/libcxx/src/include/overridable_function.h
@@ -90,8 +90,8 @@ _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \
- static type symbol##_impl__ arglist __asm__(_LIBCPP_TOSTRING(symbol##_impl__)); \
- [[gnu::weak, gnu::alias(_LIBCPP_TOSTRING(symbol##_impl__))]] type name arglist; \
+ static type symbol##_impl__ arglist __asm__(".L" _LIBCPP_TOSTRING(symbol)); \
+ [[gnu::weak, gnu::alias(".L" _LIBCPP_TOSTRING(symbol))]] type name arglist; \
_LIBCPP_BEGIN_NAMESPACE_STD \
template <> \
inline bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \
>From 00ec430c5e0c153a952a783e614f321fe12ef449 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Tue, 14 Jan 2025 15:54:28 -0800
Subject: [PATCH 2/7] Make the impl symbols non-static
This avoids the issue with -funique-internal-linkage-names.
---
libcxx/src/include/overridable_function.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/src/include/overridable_function.h b/libcxx/src/include/overridable_function.h
index 71feebf0c15b20..0258432a9ac69f 100644
--- a/libcxx/src/include/overridable_function.h
+++ b/libcxx/src/include/overridable_function.h
@@ -90,7 +90,7 @@ _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \
- static type symbol##_impl__ arglist __asm__(".L" _LIBCPP_TOSTRING(symbol)); \
+ type symbol##_impl__ arglist __asm__(".L" _LIBCPP_TOSTRING(symbol)); \
[[gnu::weak, gnu::alias(".L" _LIBCPP_TOSTRING(symbol))]] type name arglist; \
_LIBCPP_BEGIN_NAMESPACE_STD \
template <> \
@@ -98,7 +98,7 @@ _LIBCPP_END_NAMESPACE_STD
return static_cast<type(*) arglist>(name) != symbol##_impl__; \
} \
_LIBCPP_END_NAMESPACE_STD \
- static type symbol##_impl__ arglist
+ type symbol##_impl__ arglist
#else
>From 4958c19bd1c36f41e986539ef46a5e915b3406d4 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Tue, 14 Jan 2025 19:29:58 -0800
Subject: [PATCH 3/7] Make the impl symbols static
Having global symbols with .L names is not well supported.
---
libcxx/src/include/overridable_function.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/src/include/overridable_function.h b/libcxx/src/include/overridable_function.h
index 0258432a9ac69f..71feebf0c15b20 100644
--- a/libcxx/src/include/overridable_function.h
+++ b/libcxx/src/include/overridable_function.h
@@ -90,7 +90,7 @@ _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \
- type symbol##_impl__ arglist __asm__(".L" _LIBCPP_TOSTRING(symbol)); \
+ static type symbol##_impl__ arglist __asm__(".L" _LIBCPP_TOSTRING(symbol)); \
[[gnu::weak, gnu::alias(".L" _LIBCPP_TOSTRING(symbol))]] type name arglist; \
_LIBCPP_BEGIN_NAMESPACE_STD \
template <> \
@@ -98,7 +98,7 @@ _LIBCPP_END_NAMESPACE_STD
return static_cast<type(*) arglist>(name) != symbol##_impl__; \
} \
_LIBCPP_END_NAMESPACE_STD \
- type symbol##_impl__ arglist
+ static type symbol##_impl__ arglist
#else
>From 9c0ffaeb76c79b4867341227903cdf02ce7360df Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Wed, 15 Jan 2025 00:30:02 -0800
Subject: [PATCH 4/7] Use local symbols for the implementation
---
libcxx/src/include/overridable_function.h | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/libcxx/src/include/overridable_function.h b/libcxx/src/include/overridable_function.h
index 71feebf0c15b20..5996100dc4ca34 100644
--- a/libcxx/src/include/overridable_function.h
+++ b/libcxx/src/include/overridable_function.h
@@ -42,11 +42,11 @@
// -------------------
//
// Let's say we want to check whether a weak function `f` has been overridden by the user.
-// The general mechanism works by defining a symbol `f_impl__` and a weak alias `f` via the
-// _LIBCPP_OVERRIDABLE_FUNCTION macro.
+// The general mechanism works by defining an internal symbol `.L.f` and a weak alias `f`
+// via the _LIBCPP_OVERRIDABLE_FUNCTION macro.
//
// Then, when comes the time to check whether the function has been overridden, we take
-// the address of the function `f` and we check whether it is different from `f_impl__`.
+// the address of the function `f` and we check whether it is different from `.L.f`.
// If so it means the function was overriden by the user.
//
// Important note
@@ -67,17 +67,17 @@ _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \
- static __attribute__((used)) type symbol##_impl__ arglist __asm__("_" _LIBCPP_TOSTRING(symbol)); \
+ [[gnu::used]] static type symbol arglist __asm__("_" _LIBCPP_TOSTRING(symbol)); \
__asm__(".globl _" _LIBCPP_TOSTRING(symbol)); \
__asm__(".weak_definition _" _LIBCPP_TOSTRING(symbol)); \
- extern __typeof(symbol##_impl__) name __attribute__((weak_import)); \
+ extern type name arglist __attribute__((weak_import)); \
_LIBCPP_BEGIN_NAMESPACE_STD \
template <> \
inline bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \
- return static_cast<type(*) arglist>(name) != symbol##_impl__; \
+ return static_cast<type(*) arglist>(name) != symbol; \
} \
_LIBCPP_END_NAMESPACE_STD \
- static type symbol##_impl__ arglist
+ static type symbol arglist
#elif defined(_LIBCPP_OBJECT_FORMAT_ELF)
@@ -90,15 +90,15 @@ _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \
- static type symbol##_impl__ arglist __asm__(".L" _LIBCPP_TOSTRING(symbol)); \
- [[gnu::weak, gnu::alias(".L" _LIBCPP_TOSTRING(symbol))]] type name arglist; \
+ [[gnu::weak]] type name arglist; \
+ [[gnu::alias(_LIBCPP_TOSTRING(symbol))]] static type symbol arglist __asm__(".L." _LIBCPP_TOSTRING(symbol)); \
_LIBCPP_BEGIN_NAMESPACE_STD \
template <> \
inline bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \
- return static_cast<type(*) arglist>(name) != symbol##_impl__; \
+ return static_cast<type(*) arglist>(name) != symbol; \
} \
_LIBCPP_END_NAMESPACE_STD \
- static type symbol##_impl__ arglist
+ type name arglist
#else
>From f76dd1492451f8422f9a725c9ea87f6e00aef718 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Wed, 15 Jan 2025 00:33:11 -0800
Subject: [PATCH 5/7] Use C++ attributes
---
libcxx/src/include/overridable_function.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/src/include/overridable_function.h b/libcxx/src/include/overridable_function.h
index 5996100dc4ca34..c90034eb07af3c 100644
--- a/libcxx/src/include/overridable_function.h
+++ b/libcxx/src/include/overridable_function.h
@@ -70,7 +70,7 @@ _LIBCPP_END_NAMESPACE_STD
[[gnu::used]] static type symbol arglist __asm__("_" _LIBCPP_TOSTRING(symbol)); \
__asm__(".globl _" _LIBCPP_TOSTRING(symbol)); \
__asm__(".weak_definition _" _LIBCPP_TOSTRING(symbol)); \
- extern type name arglist __attribute__((weak_import)); \
+ [[clang::weak_import]] extern type name arglist; \
_LIBCPP_BEGIN_NAMESPACE_STD \
template <> \
inline bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \
>From 7b6b05c91083b6ec67099980f38d226f2e22db5a Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Mon, 20 Jan 2025 17:19:44 -0800
Subject: [PATCH 6/7] Update the Mach-O implementation
This roughly matches the ELF version and addresses the issue #123224.
---
libcxx/src/include/overridable_function.h | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/libcxx/src/include/overridable_function.h b/libcxx/src/include/overridable_function.h
index c90034eb07af3c..51968d12fdfa55 100644
--- a/libcxx/src/include/overridable_function.h
+++ b/libcxx/src/include/overridable_function.h
@@ -42,12 +42,11 @@
// -------------------
//
// Let's say we want to check whether a weak function `f` has been overridden by the user.
-// The general mechanism works by defining an internal symbol `.L.f` and a weak alias `f`
-// via the _LIBCPP_OVERRIDABLE_FUNCTION macro.
-//
-// Then, when comes the time to check whether the function has been overridden, we take
-// the address of the function `f` and we check whether it is different from `.L.f`.
-// If so it means the function was overriden by the user.
+// The general mechanism works by defining an internal symbol and a weak alias `f` via the
+// _LIBCPP_OVERRIDABLE_FUNCTION macro. Then, when comes the time to check whether the
+// function has been overridden, we take the address of the internal symbol and the weak
+// alias `f` and check whether they're different. If so it means the function was overriden
+// by the user.
//
// Important note
// --------------
@@ -67,17 +66,14 @@ _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \
- [[gnu::used]] static type symbol arglist __asm__("_" _LIBCPP_TOSTRING(symbol)); \
- __asm__(".globl _" _LIBCPP_TOSTRING(symbol)); \
- __asm__(".weak_definition _" _LIBCPP_TOSTRING(symbol)); \
- [[clang::weak_import]] extern type name arglist; \
+ [[clang::weak_import]] extern type symbol arglist __asm__("_" _LIBCPP_TOSTRING(symbol)); \
_LIBCPP_BEGIN_NAMESPACE_STD \
template <> \
inline bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \
return static_cast<type(*) arglist>(name) != symbol; \
} \
_LIBCPP_END_NAMESPACE_STD \
- static type symbol arglist
+ type name arglist
#elif defined(_LIBCPP_OBJECT_FORMAT_ELF)
>From 82c9331823af8f0d4d6a4e3cb651792437720484 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Mon, 20 Jan 2025 22:34:56 -0800
Subject: [PATCH 7/7] Use correct attributes for functions
---
libcxx/include/__config | 8 ++++++++
libcxx/src/include/overridable_function.h | 13 ++++---------
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 658a7e16fae916..9dd33f685913a2 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -804,6 +804,14 @@ typedef __char32_t char32_t;
# define _LIBCPP_WEAK __attribute__((__weak__))
# endif
+# ifndef _LIBCPP_WEAK_IMPORT
+# define _LIBCPP_WEAK_IMPORT __attribute__((weak_import))
+# endif
+
+# ifndef _LIBCPP_ALIAS
+# define _LIBCPP_ALIAS(x) __attribute__((alias(x)))
+# endif
+
// Thread API
// clang-format off
# if _LIBCPP_HAS_THREADS && \
diff --git a/libcxx/src/include/overridable_function.h b/libcxx/src/include/overridable_function.h
index 51968d12fdfa55..27264bb1de278c 100644
--- a/libcxx/src/include/overridable_function.h
+++ b/libcxx/src/include/overridable_function.h
@@ -13,10 +13,6 @@
#include <__config>
#include <cstdint>
-#if __has_feature(ptrauth_calls)
-# include <ptrauth.h>
-#endif
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
@@ -66,14 +62,14 @@ _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \
- [[clang::weak_import]] extern type symbol arglist __asm__("_" _LIBCPP_TOSTRING(symbol)); \
+ _LIBCPP_WEAK_IMPORT extern type symbol arglist __asm__("_" _LIBCPP_TOSTRING(symbol)); \
_LIBCPP_BEGIN_NAMESPACE_STD \
template <> \
inline bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \
return static_cast<type(*) arglist>(name) != symbol; \
} \
_LIBCPP_END_NAMESPACE_STD \
- type name arglist
+ _LIBCPP_WEAK type name arglist
#elif defined(_LIBCPP_OBJECT_FORMAT_ELF)
@@ -86,15 +82,14 @@ _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \
- [[gnu::weak]] type name arglist; \
- [[gnu::alias(_LIBCPP_TOSTRING(symbol))]] static type symbol arglist __asm__(".L." _LIBCPP_TOSTRING(symbol)); \
+ _LIBCPP_ALIAS(_LIBCPP_TOSTRING(symbol)) static type symbol arglist __asm__(".L." _LIBCPP_TOSTRING(symbol)); \
_LIBCPP_BEGIN_NAMESPACE_STD \
template <> \
inline bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \
return static_cast<type(*) arglist>(name) != symbol; \
} \
_LIBCPP_END_NAMESPACE_STD \
- type name arglist
+ _LIBCPP_WEAK type name arglist
#else
More information about the libcxx-commits
mailing list