[compiler-rt] [compiler-rt] Refactor Windows IN_SECTION declarations (PR #216582)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 16 10:31:52 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: oltolm (oltolm)

<details>
<summary>Changes</summary>

I have split this PR from https://github.com/llvm/llvm-project/pull/209902. It's one of the patches that enables ASan and UBSan in GCC for Windows.

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


9 Files Affected:

- (modified) compiler-rt/lib/asan/asan_globals_win.cpp (+12-11) 
- (modified) compiler-rt/lib/asan/asan_win.cpp (+5-6) 
- (modified) compiler-rt/lib/asan/asan_win_common_runtime_thunk.cpp (+4-5) 
- (modified) compiler-rt/lib/asan/asan_win_common_runtime_thunk.h (+1-1) 
- (modified) compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cpp (+4-4) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_win.cpp (+1-1) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h (+7-5) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.cpp (+9-13) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h (+4-3) 


``````````diff
diff --git a/compiler-rt/lib/asan/asan_globals_win.cpp b/compiler-rt/lib/asan/asan_globals_win.cpp
index 2b59595dcd3bf..aeef42749fa8c 100644
--- a/compiler-rt/lib/asan/asan_globals_win.cpp
+++ b/compiler-rt/lib/asan/asan_globals_win.cpp
@@ -12,16 +12,17 @@
 
 #include "asan_interface_internal.h"
 #if SANITIZER_WINDOWS
+#  include "sanitizer_common/sanitizer_win_defs.h"
 
 namespace __asan {
 
-#pragma section(".ASAN$GA", read, write)
-#pragma section(".ASAN$GZ", read, write)
+#  pragma section(".ASAN$GA", read, write)
+#  pragma section(".ASAN$GZ", read, write)
 extern "C" alignas(sizeof(__asan_global))
-    __declspec(allocate(".ASAN$GA")) __asan_global __asan_globals_start = {};
+    IN_SECTION(".ASAN$GA") __asan_global __asan_globals_start = {};
 extern "C" alignas(sizeof(__asan_global))
-    __declspec(allocate(".ASAN$GZ")) __asan_global __asan_globals_end = {};
-#pragma comment(linker, "/merge:.ASAN=.data")
+    IN_SECTION(".ASAN$GZ") __asan_global __asan_globals_end = {};
+#  pragma comment(linker, "/merge:.ASAN=.data")
 
 static void call_on_globals(void (*hook)(__asan_global *, uptr)) {
   __asan_global *start = &__asan_globals_start + 1;
@@ -51,12 +52,12 @@ static void unregister_dso_globals() {
 }
 
 // Register globals
-#pragma section(".CRT$XCU", long, read)
-#pragma section(".CRT$XTX", long, read)
-extern "C" __declspec(allocate(".CRT$XCU"))
-void (*const __asan_dso_reg_hook)() = &register_dso_globals;
-extern "C" __declspec(allocate(".CRT$XTX"))
-void (*const __asan_dso_unreg_hook)() = &unregister_dso_globals;
+#  pragma section(".CRT$XCU", long, read)
+#  pragma section(".CRT$XTX", long, read)
+extern "C" IN_SECTION(".CRT$XCU") void (*const __asan_dso_reg_hook)() =
+    &register_dso_globals;
+extern "C" IN_SECTION(".CRT$XTX") void (*const __asan_dso_unreg_hook)() =
+    &unregister_dso_globals;
 
 } // namespace __asan
 
diff --git a/compiler-rt/lib/asan/asan_win.cpp b/compiler-rt/lib/asan/asan_win.cpp
index 845408ac38abc..7bb2fd4b1416b 100644
--- a/compiler-rt/lib/asan/asan_win.cpp
+++ b/compiler-rt/lib/asan/asan_win.cpp
@@ -385,8 +385,7 @@ bool HandleDlopenInit() {
 // immediately after the CRT runs. This way, our exception filter is called
 // first and we can delegate to their filter if appropriate.
 #pragma section(".CRT$XCAB", long, read)
-__declspec(allocate(".CRT$XCAB")) int (*__intercept_seh)() =
-    __asan_set_seh_filter;
+IN_SECTION(".CRT$XCAB") int (*__intercept_seh)() = __asan_set_seh_filter;
 
 // Piggyback on the TLS initialization callback directory to initialize asan as
 // early as possible. Initializers in .CRT$XL* are called directly by ntdll,
@@ -398,8 +397,8 @@ static void NTAPI asan_thread_init(void *module, DWORD reason, void *reserved) {
 }
 
 #pragma section(".CRT$XLAB", long, read)
-__declspec(allocate(".CRT$XLAB")) void(NTAPI *__asan_tls_init)(
-    void *, unsigned long, void *) = asan_thread_init;
+IN_SECTION(".CRT$XLAB")
+void(NTAPI* __asan_tls_init)(void*, unsigned long, void*) = asan_thread_init;
 #endif
 
 static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) {
@@ -412,8 +411,8 @@ static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) {
 }
 
 #pragma section(".CRT$XLY", long, read)
-__declspec(allocate(".CRT$XLY")) void(NTAPI *__asan_tls_exit)(
-    void *, unsigned long, void *) = asan_thread_exit;
+IN_SECTION(".CRT$XLY")
+void(NTAPI* __asan_tls_exit)(void*, unsigned long, void*) = asan_thread_exit;
 
 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 056e49336d326..f49296f624360 100644
--- a/compiler-rt/lib/asan/asan_win_common_runtime_thunk.cpp
+++ b/compiler-rt/lib/asan/asan_win_common_runtime_thunk.cpp
@@ -83,12 +83,11 @@ static void WINAPI asan_thread_init(void *mod, unsigned long reason,
 // Our cloned variables must be initialized before C/C++ constructors.  If TLS
 // is used, our .CRT$XLAB initializer will run first. If not, our .CRT$XIB
 // initializer is needed as a backup.
-extern "C" __declspec(allocate(".CRT$XIB")) int (*__asan_thunk_init)() =
-    asan_thunk_init;
+extern "C" IN_SECTION(".CRT$XIB") int (*__asan_thunk_init)() = asan_thunk_init;
 WIN_FORCE_LINK(__asan_thunk_init)
 
-extern "C" __declspec(allocate(".CRT$XLAB")) void(WINAPI *__asan_tls_init)(
-    void *, unsigned long, void *) = asan_thread_init;
+extern "C" IN_SECTION(".CRT$XLAB") void(WINAPI* __asan_tls_init)(
+    void*, unsigned long, void*) = asan_thread_init;
 WIN_FORCE_LINK(__asan_tls_init)
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -101,7 +100,7 @@ static int SetSEHFilter() { return __asan_set_seh_filter(); }
 
 // Unfortunately, putting a pointer to __asan_set_seh_filter into
 // __asan_intercept_seh gets optimized out, so we have to use an extra function.
-extern "C" __declspec(allocate(".CRT$XCAB")) int (*__asan_seh_interceptor)() =
+extern "C" IN_SECTION(".CRT$XCAB") int (*__asan_seh_interceptor)() =
     SetSEHFilter;
 WIN_FORCE_LINK(__asan_seh_interceptor)
 }
diff --git a/compiler-rt/lib/asan/asan_win_common_runtime_thunk.h b/compiler-rt/lib/asan/asan_win_common_runtime_thunk.h
index 159cc152474e7..8d457f75f5526 100644
--- a/compiler-rt/lib/asan/asan_win_common_runtime_thunk.h
+++ b/compiler-rt/lib/asan/asan_win_common_runtime_thunk.h
@@ -35,4 +35,4 @@ extern "C" void __asan_initialize_static_thunk();
 #  endif
 
 #endif  // defined(SANITIZER_STATIC_RUNTIME_THUNK) ||
-        // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
\ No newline at end of file
+        // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
diff --git a/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cpp b/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cpp
index 421fe651b7d91..2a864aa4ee8c1 100644
--- a/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cpp
+++ b/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cpp
@@ -33,8 +33,8 @@ extern "C" int __cdecl atexit(void(__cdecl *f)(void));
 extern "C" void __cdecl _initterm(void *a, void *b);
 
 namespace {
-__declspec(allocate(".CRT$XTW")) void *before_global_dtors = 0;
-__declspec(allocate(".CRT$XTY")) void *after_global_dtors = 0;
+IN_SECTION(".CRT$XTW") void* before_global_dtors = 0;
+IN_SECTION(".CRT$XTY") void* after_global_dtors = 0;
 
 void UnregisterGlobals() {
   _initterm(&before_global_dtors, &after_global_dtors);
@@ -47,8 +47,8 @@ int ScheduleUnregisterGlobals() { return atexit(UnregisterGlobals); }
 // atexit() is initialized (.CRT$XIC).  As this is executed before C++
 // initializers (think ctors for globals), UnregisterGlobals gets executed after
 // dtors for C++ globals.
-extern "C" __declspec(allocate(".CRT$XID")) int (
-    *__asan_schedule_unregister_globals)() = ScheduleUnregisterGlobals;
+extern "C" IN_SECTION(".CRT$XID") int (*__asan_schedule_unregister_globals)() =
+    ScheduleUnregisterGlobals;
 WIN_FORCE_LINK(__asan_schedule_unregister_globals)
 
 #endif  // SANITIZER_DYNAMIC_RUNTIME_THUNK
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
index 3a1d1257a3481..254a675fa222c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
@@ -760,7 +760,7 @@ static int RunAtexit() {
 }
 
 #pragma section(".CRT$XID", long, read)
-__declspec(allocate(".CRT$XID")) int (*__run_atexit)() = RunAtexit;
+IN_SECTION(".CRT$XID") int (*__run_atexit)() = RunAtexit;
 #endif
 
 // ------------------ sanitizer_libc.h
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
index bfe38a3323674..0f97a1803cdf0 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
@@ -43,7 +43,9 @@
 #define STRINGIFY_(A) #A
 #define STRINGIFY(A) STRINGIFY_(A)
 
-#if !SANITIZER_GO
+#  define IN_SECTION(n) __declspec(allocate(n))
+
+#  if !SANITIZER_GO
 
 // ----------------- A workaround for the absence of weak symbols --------------
 // We don't have a direct equivalent of weak symbols when using MSVC, but we can
@@ -161,14 +163,14 @@
 //   }
 //
 
-#else // SANITIZER_GO
+#  else // SANITIZER_GO
 
 // Go neither needs nor wants weak references.
 // The shenanigans above don't work for gcc.
-# define WIN_WEAK_EXPORT_DEF(ReturnType, Name, ...)                            \
-  extern "C" ReturnType Name(__VA_ARGS__)
+#    define WIN_WEAK_EXPORT_DEF(ReturnType, Name, ...) \
+      extern "C" ReturnType Name(__VA_ARGS__)
 
-#endif // SANITIZER_GO
+#  endif // SANITIZER_GO
 
 #endif // SANITIZER_WINDOWS
 #endif // SANITIZER_WIN_DEFS_H
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 16ba155630b0a..d9cf6ac0a76af 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.cpp
@@ -61,14 +61,11 @@ void initialize_thunks(const sanitizer_thunk *first,
 #  pragma section(".WEAK$Z", read)  // weak end
 
 extern "C" {
-__declspec(allocate(
-    ".INTR$A")) sanitizer_thunk __sanitizer_intercept_thunk_begin;
-__declspec(allocate(".INTR$Z")) sanitizer_thunk __sanitizer_intercept_thunk_end;
-
-__declspec(allocate(
-    ".WEAK$A")) sanitizer_thunk __sanitizer_register_weak_thunk_begin;
-__declspec(allocate(
-    ".WEAK$Z")) sanitizer_thunk __sanitizer_register_weak_thunk_end;
+IN_SECTION(".INTR$A") sanitizer_thunk __sanitizer_intercept_thunk_begin;
+IN_SECTION(".INTR$Z") sanitizer_thunk __sanitizer_intercept_thunk_end;
+
+IN_SECTION(".WEAK$A") sanitizer_thunk __sanitizer_register_weak_thunk_begin;
+IN_SECTION(".WEAK$Z") sanitizer_thunk __sanitizer_register_weak_thunk_end;
 }
 
 extern "C" int __sanitizer_thunk_init() {
@@ -92,7 +89,7 @@ extern "C" int __sanitizer_thunk_init() {
 // We want to call dll_thunk_init before C/C++ initializers / constructors are
 // executed, otherwise functions like memset might be invoked.
 #  pragma section(".CRT$XIB", long, read)
-__declspec(allocate(".CRT$XIB")) int (*__sanitizer_thunk_init_ptr)() =
+extern "C" IN_SECTION(".CRT$XIB") int (*__sanitizer_thunk_init_ptr)() =
     __sanitizer_thunk_init;
 
 static void WINAPI sanitizer_thunk_thread_init(void *mod, unsigned long reason,
@@ -102,9 +99,8 @@ static void WINAPI sanitizer_thunk_thread_init(void *mod, unsigned long reason,
 }
 
 #  pragma section(".CRT$XLAB", long, read)
-__declspec(allocate(".CRT$XLAB")) void(
-    WINAPI *__sanitizer_thunk_thread_init_ptr)(void *, unsigned long, void *) =
+extern "C" IN_SECTION(".CRT$XLAB") void(
+    WINAPI* __sanitizer_thunk_thread_init_ptr)(void*, unsigned long, void*) =
     sanitizer_thunk_thread_init;
-
 #endif  // defined(SANITIZER_STATIC_RUNTIME_THUNK) ||
-        // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
\ No newline at end of file
+        // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
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 278450d68ac51..4beaab5f15b93 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h
@@ -14,6 +14,7 @@
 #include <stdint.h>
 
 #include "sanitizer_internal_defs.h"
+#include "sanitizer_win_defs.h"
 
 extern "C" {
 __declspec(dllimport) bool __cdecl __sanitizer_override_function(
@@ -53,8 +54,8 @@ void initialize_thunks(const sanitizer_thunk *begin,
         sanitizer_export,                                              \
         reinterpret_cast<__sanitizer::uptr>(local_function));          \
   }                                                                    \
-  __pragma(section(".INTR$M", long, read)) __declspec(allocate(        \
-      ".INTR$M")) int (*__sanitizer_static_thunk_##local_function)() = \
+  __pragma(section(".INTR$M", long, read)) IN_SECTION(".INTR$M") int ( \
+      *__sanitizer_static_thunk_##local_function)() =                  \
       intercept_##local_function;
 
 // ------------------ Weak symbol registration macros ---------------------- //
@@ -85,4 +86,4 @@ void initialize_thunks(const sanitizer_thunk *begin,
   __pragma(section(".WEAK$M", long, read)) __declspec(allocate(         \
       ".WEAK$M")) int (*__sanitizer_register_weak_##local_function)() = \
       register_weak_##local_function;
-#endif  // SANITIZER_WIN_STATIC_RUNTIME_THUNK_H
+#endif  // SANITIZER_WIN_THUNK_INTERCEPTION_H

``````````

</details>


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


More information about the llvm-commits mailing list