[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)() = ®ister_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)() =
+ ®ister_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