[compiler-rt] [compiler-rt] Retain sanitizer callbacks with MinGW GCC (PR #222711)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 10 09:52:51 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: oltolm (oltolm)

<details>
<summary>Changes</summary>

MSVC and clang-cl use /include directives emitted by WIN_FORCE_LINK. GNU tools need an ordinary used relocation instead. Keep the sanitizer initialization callbacks and ASan DSO registration object reachable when linking with MinGW GCC.

---
Full diff: https://github.com/llvm/llvm-project/pull/222711.diff


4 Files Affected:

- (modified) compiler-rt/lib/asan/asan_win.cpp (+2) 
- (modified) compiler-rt/lib/asan/asan_win_common_runtime_thunk.cpp (+1) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h (+14-6) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.cpp (+2) 


``````````diff
diff --git a/compiler-rt/lib/asan/asan_win.cpp b/compiler-rt/lib/asan/asan_win.cpp
index c671a2d6327eb..dfc44a528885e 100644
--- a/compiler-rt/lib/asan/asan_win.cpp
+++ b/compiler-rt/lib/asan/asan_win.cpp
@@ -414,6 +414,8 @@ static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) {
 IN_SECTION(".CRT$XLY")
 void(NTAPI* __asan_tls_exit)(void*, unsigned long, void*) = asan_thread_exit;
 
+extern "C" void (*const __asan_dso_reg_hook)();
+
 WIN_FORCE_LINK(__asan_dso_reg_hook)
 
 // }}}
diff --git a/compiler-rt/lib/asan/asan_win_common_runtime_thunk.cpp b/compiler-rt/lib/asan/asan_win_common_runtime_thunk.cpp
index f49296f624360..553c2d93efe0b 100644
--- a/compiler-rt/lib/asan/asan_win_common_runtime_thunk.cpp
+++ b/compiler-rt/lib/asan/asan_win_common_runtime_thunk.cpp
@@ -105,6 +105,7 @@ extern "C" IN_SECTION(".CRT$XCAB") int (*__asan_seh_interceptor)() =
 WIN_FORCE_LINK(__asan_seh_interceptor)
 }
 
+extern "C" void (*const __asan_dso_reg_hook)();
 WIN_FORCE_LINK(__asan_dso_reg_hook)
 
 #endif  // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) ||
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
index 7f36f3ae743c3..ca4918720da95 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
@@ -71,12 +71,20 @@
   __pragma(comment(linker, "/alternatename:" WIN_SYM_PREFIX STRINGIFY(Name) "="\
                                              WIN_SYM_PREFIX STRINGIFY(Default)))
 
-#define WIN_FORCE_LINK(Name)                                                   \
-  __pragma(comment(linker, "/include:" WIN_SYM_PREFIX STRINGIFY(Name)))
-
-#define WIN_EXPORT(ExportedName, Name)                                         \
-  __pragma(comment(linker, "/export:" WIN_EXPORT_PREFIX STRINGIFY(ExportedName)\
-                                  "=" WIN_EXPORT_PREFIX STRINGIFY(Name)))
+#    if !defined(__GNUC__) || defined(__clang__)
+#      define WIN_FORCE_LINK(Name) \
+        __pragma(comment(linker, "/include:" WIN_SYM_PREFIX STRINGIFY(Name)))
+#    else
+#      define WIN_FORCE_LINK(Name)                                           \
+        extern "C" __typeof__(Name) Name;                                    \
+        static __attribute__((used)) __typeof__(&Name) __force_link_##Name = \
+            &Name;
+#    endif
+
+#    define WIN_EXPORT(ExportedName, Name)                \
+      __pragma(comment(                                   \
+          linker, "/export:" WIN_EXPORT_PREFIX STRINGIFY( \
+                      ExportedName) "=" WIN_EXPORT_PREFIX STRINGIFY(Name)))
 
 // We cannot define weak functions on Windows, but we can use WIN_WEAK_ALIAS()
 // which defines an alias to a default implementation, and only works when
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.cpp
index d9cf6ac0a76af..794f61fd34418 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.cpp
@@ -91,6 +91,7 @@ extern "C" int __sanitizer_thunk_init() {
 #  pragma section(".CRT$XIB", long, read)
 extern "C" IN_SECTION(".CRT$XIB") int (*__sanitizer_thunk_init_ptr)() =
     __sanitizer_thunk_init;
+WIN_FORCE_LINK(__sanitizer_thunk_init_ptr)
 
 static void WINAPI sanitizer_thunk_thread_init(void *mod, unsigned long reason,
                                                void *reserved) {
@@ -102,5 +103,6 @@ static void WINAPI sanitizer_thunk_thread_init(void *mod, unsigned long reason,
 extern "C" IN_SECTION(".CRT$XLAB") void(
     WINAPI* __sanitizer_thunk_thread_init_ptr)(void*, unsigned long, void*) =
     sanitizer_thunk_thread_init;
+WIN_FORCE_LINK(__sanitizer_thunk_thread_init_ptr)
 #endif  // defined(SANITIZER_STATIC_RUNTIME_THUNK) ||
         // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)

``````````

</details>


https://github.com/llvm/llvm-project/pull/222711


More information about the llvm-commits mailing list