[compiler-rt] [compiler-rt] Handle weak interfaces with MinGW GCC (PR #222706)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 10 09:48:43 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: oltolm (oltolm)
<details>
<summary>Changes</summary>
Windows weak-function emulation uses MSVC linker /alternatename directives, which GNU ld does not support. Use direct exported definitions, avoid registering unsupported DLL weak aliases, and reference UBSan's real C++ implementation.
---
Full diff: https://github.com/llvm/llvm-project/pull/222706.diff
3 Files Affected:
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h (+4-4)
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h (+24-17)
- (modified) compiler-rt/lib/ubsan/ubsan_handlers.cpp (+6-1)
``````````diff
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
index c694897b6556b..75980867d545d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
@@ -63,10 +63,10 @@
// For example:
// SANITIZER_INTERFACE_WEAK_DEF(bool, compare, int a, int b) { return a > b; }
//
-#if SANITIZER_WINDOWS
-#include "sanitizer_win_defs.h"
-# define SANITIZER_INTERFACE_WEAK_DEF(ReturnType, Name, ...) \
- WIN_WEAK_EXPORT_DEF(ReturnType, Name, __VA_ARGS__)
+#if SANITIZER_WINDOWS && (!defined(__GNUC__) || defined(__clang__))
+# include "sanitizer_win_defs.h"
+# define SANITIZER_INTERFACE_WEAK_DEF(ReturnType, Name, ...) \
+ WIN_WEAK_EXPORT_DEF(ReturnType, Name, __VA_ARGS__)
#else
# define SANITIZER_INTERFACE_WEAK_DEF(ReturnType, Name, ...) \
extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE \
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h b/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h
index 4beaab5f15b93..492ef6b2b98b2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h
@@ -69,21 +69,28 @@ void initialize_thunks(const sanitizer_thunk *begin,
# define REGISTER_WEAK_FUNCTION_ADDRESS(fn) &fn
#endif
-#define REGISTER_WEAK_FUNCTION(local_function) \
- extern "C" void local_function(); \
- extern "C" void WEAK_EXPORT_NAME(local_function)(); \
- WIN_WEAK_IMPORT_DEF(local_function) \
- REGISTER_WEAK_OPTNONE static int register_weak_##local_function() { \
- if ((uintptr_t)REGISTER_WEAK_FUNCTION_ADDRESS(local_function) != \
- (uintptr_t)REGISTER_WEAK_FUNCTION_ADDRESS( \
- WEAK_EXPORT_NAME(local_function))) { \
- return __sanitizer::register_weak( \
- SANITIZER_STRINGIFY(WEAK_EXPORT_NAME(local_function)), \
- reinterpret_cast<__sanitizer::uptr>(local_function)); \
- } \
- return 0; \
- } \
- __pragma(section(".WEAK$M", long, read)) __declspec(allocate( \
- ".WEAK$M")) int (*__sanitizer_register_weak_##local_function)() = \
- register_weak_##local_function;
+#if !defined(__GNUC__) || defined(__clang__)
+# define REGISTER_WEAK_FUNCTION(local_function) \
+ extern "C" void local_function(); \
+ extern "C" void WEAK_EXPORT_NAME(local_function)(); \
+ WIN_WEAK_IMPORT_DEF(local_function) \
+ REGISTER_WEAK_OPTNONE static int register_weak_##local_function() { \
+ if ((uintptr_t)REGISTER_WEAK_FUNCTION_ADDRESS(local_function) != \
+ (uintptr_t)REGISTER_WEAK_FUNCTION_ADDRESS( \
+ WEAK_EXPORT_NAME(local_function))) { \
+ return __sanitizer::register_weak( \
+ SANITIZER_STRINGIFY(WEAK_EXPORT_NAME(local_function)), \
+ reinterpret_cast<__sanitizer::uptr>(local_function)); \
+ } \
+ return 0; \
+ } \
+ __pragma(section(".WEAK$M", long, read)) __declspec(allocate( \
+ ".WEAK$M")) int (*__sanitizer_register_weak_##local_function)() = \
+ register_weak_##local_function;
+#else
+// GNU ld does not support /alternatename. User overrides of weak sanitizer
+// functions are not forwarded to the sanitizer DLL on this toolchain.
+# define REGISTER_WEAK_FUNCTION(local_function) \
+ extern "C" void local_function();
+#endif
#endif // SANITIZER_WIN_THUNK_INTERCEPTION_H
diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.cpp b/compiler-rt/lib/ubsan/ubsan_handlers.cpp
index 0cd8a437adf4d..af207ee6ccccf 100644
--- a/compiler-rt/lib/ubsan/ubsan_handlers.cpp
+++ b/compiler-rt/lib/ubsan/ubsan_handlers.cpp
@@ -935,7 +935,7 @@ static void handleCFIBadIcall(CFICheckFailData *Data, ValueHandle Function,
namespace __ubsan {
-#ifdef _WIN32
+#if defined(_WIN32) && (!defined(__GNUC__) || defined(__clang__))
extern "C" void __ubsan_handle_cfi_bad_type_default(CFICheckFailData *Data,
ValueHandle Vtable,
bool ValidVtable,
@@ -944,6 +944,11 @@ extern "C" void __ubsan_handle_cfi_bad_type_default(CFICheckFailData *Data,
}
WIN_WEAK_ALIAS(__ubsan_handle_cfi_bad_type, __ubsan_handle_cfi_bad_type_default)
+void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, ValueHandle Vtable,
+ bool ValidVtable, ReportOptions Opts);
+#elif defined(_WIN32)
+// GNU ld does not support /alternatename. The real implementation lives in
+// ubsan_handlers_cxx.cpp.
void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, ValueHandle Vtable,
bool ValidVtable, ReportOptions Opts);
#else
``````````
</details>
https://github.com/llvm/llvm-project/pull/222706
More information about the llvm-commits
mailing list