[compiler-rt] [compiler-rt] Support GNU section attributes on Windows (PR #222707)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 10 09:48:30 PDT 2026


https://github.com/oltolm created https://github.com/llvm/llvm-project/pull/222707

MSVC and Clang place sanitizer sentinels and CRT callbacks with __declspec(allocate) after declaring their sections with #pragma section. MinGW GCC uses the section attribute instead, so select the appropriate spelling for each compiler.

>From 706aed20166e814e4bc5acf113e3d2455eecb221 Mon Sep 17 00:00:00 2001
From: Oleg Tolmatcev <oleg.tolmatcev at gmail.com>
Date: Thu, 10 Sep 2026 17:54:22 +0200
Subject: [PATCH] [compiler-rt] Support GNU section attributes on Windows

MSVC and Clang place sanitizer sentinels and CRT callbacks with
__declspec(allocate) after declaring their sections with #pragma section.
MinGW GCC uses the section attribute instead, so select the appropriate
spelling for each compiler.

Co-authored-by: Hannes Domani <ssbssa at yahoo.de>
---
 compiler-rt/lib/asan/asan_globals_win.cpp     | 12 +++++++----
 compiler-rt/lib/asan/asan_win.cpp             | 12 ++++++++---
 .../lib/asan/asan_win_common_runtime_thunk.h  | 20 ++++++++++---------
 .../lib/sanitizer_common/sanitizer_win.cpp    |  4 +++-
 .../lib/sanitizer_common/sanitizer_win_defs.h |  6 +++++-
 5 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/compiler-rt/lib/asan/asan_globals_win.cpp b/compiler-rt/lib/asan/asan_globals_win.cpp
index aeef42749fa8c..8168567c0d9b2 100644
--- a/compiler-rt/lib/asan/asan_globals_win.cpp
+++ b/compiler-rt/lib/asan/asan_globals_win.cpp
@@ -16,8 +16,10 @@
 
 namespace __asan {
 
-#  pragma section(".ASAN$GA", read, write)
-#  pragma section(".ASAN$GZ", read, write)
+#  if !defined(__GNUC__) || defined(__clang__)
+#    pragma section(".ASAN$GA", read, write)
+#    pragma section(".ASAN$GZ", read, write)
+#  endif
 extern "C" alignas(sizeof(__asan_global))
     IN_SECTION(".ASAN$GA") __asan_global __asan_globals_start = {};
 extern "C" alignas(sizeof(__asan_global))
@@ -52,8 +54,10 @@ static void unregister_dso_globals() {
 }
 
 // Register globals
-#  pragma section(".CRT$XCU", long, read)
-#  pragma section(".CRT$XTX", long, read)
+#  if !defined(__GNUC__) || defined(__clang__)
+#    pragma section(".CRT$XCU", long, read)
+#    pragma section(".CRT$XTX", long, read)
+#  endif
 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)() =
diff --git a/compiler-rt/lib/asan/asan_win.cpp b/compiler-rt/lib/asan/asan_win.cpp
index c671a2d6327eb..46e3b57aa3668 100644
--- a/compiler-rt/lib/asan/asan_win.cpp
+++ b/compiler-rt/lib/asan/asan_win.cpp
@@ -384,7 +384,9 @@ bool HandleDlopenInit() {
 // beginning of C++ initialization. We set our priority to XCAB to run
 // 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)
+#    if !defined(__GNUC__) || defined(__clang__)
+#      pragma section(".CRT$XCAB", long, read)
+#    endif
 IN_SECTION(".CRT$XCAB") int (*__intercept_seh)() = __asan_set_seh_filter;
 
 // Piggyback on the TLS initialization callback directory to initialize asan as
@@ -396,7 +398,9 @@ static void NTAPI asan_thread_init(void *module, DWORD reason, void *reserved) {
     __asan_init();
 }
 
-#pragma section(".CRT$XLAB", long, read)
+#    if !defined(__GNUC__) || defined(__clang__)
+#      pragma section(".CRT$XLAB", long, read)
+#    endif
 IN_SECTION(".CRT$XLAB")
 void(NTAPI* __asan_tls_init)(void*, unsigned long, void*) = asan_thread_init;
 #  endif
@@ -410,7 +414,9 @@ static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) {
   }
 }
 
-#pragma section(".CRT$XLY", long, read)
+#  if !defined(__GNUC__) || defined(__clang__)
+#    pragma section(".CRT$XLY", long, read)
+#  endif
 IN_SECTION(".CRT$XLY")
 void(NTAPI* __asan_tls_exit)(void*, unsigned long, void*) = asan_thread_exit;
 
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 8d457f75f5526..8cba5dabe3481 100644
--- a/compiler-rt/lib/asan/asan_win_common_runtime_thunk.h
+++ b/compiler-rt/lib/asan/asan_win_common_runtime_thunk.h
@@ -18,17 +18,19 @@
     defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
 #  include "sanitizer_common/sanitizer_win_defs.h"
 
-#  pragma section(".CRT$XIB", long, \
-                  read)  // C initializer (during C init before dyninit)
-#  pragma section(".CRT$XID", long, \
-                  read)  // First C initializer after CRT initializers
-#  pragma section(".CRT$XCAB", long, \
-                  read)  // First C++ initializer after startup initializers
+#  if !defined(__GNUC__) || defined(__clang__)
+#    pragma section(".CRT$XIB", long, \
+                    read)  // C initializer (during C init before dyninit)
+#    pragma section(".CRT$XID", long, \
+                    read)  // First C initializer after CRT initializers
+#    pragma section(".CRT$XCAB", long, \
+                    read)  // First C++ initializer after startup initializers
 
-#  pragma section(".CRT$XTW", long, read)  // First ASAN globals terminator
-#  pragma section(".CRT$XTY", long, read)  // Last ASAN globals terminator
+#    pragma section(".CRT$XTW", long, read)  // First ASAN globals terminator
+#    pragma section(".CRT$XTY", long, read)  // Last ASAN globals terminator
 
-#  pragma section(".CRT$XLAB", long, read)  // First TLS initializer
+#    pragma section(".CRT$XLAB", long, read)  // First TLS initializer
+#  endif
 
 #  ifdef SANITIZER_STATIC_RUNTIME_THUNK
 extern "C" void __asan_initialize_static_thunk();
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
index 52f6cb6ea9cc0..4c4b5cf964256 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
@@ -759,7 +759,9 @@ static int RunAtexit() {
   return ret;
 }
 
-#pragma section(".CRT$XID", long, read)
+#    if !defined(__GNUC__) || defined(__clang__)
+#      pragma section(".CRT$XID", long, read)
+#    endif
 IN_SECTION(".CRT$XID") int (*__run_atexit)() = RunAtexit;
 #  endif
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
index 7f36f3ae743c3..047a7286b1ad0 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
@@ -43,7 +43,11 @@
 #define STRINGIFY_(A) #A
 #define STRINGIFY(A) STRINGIFY_(A)
 
-#  define IN_SECTION(n) __declspec(allocate(n))
+#  if !defined(__GNUC__) || defined(__clang__)
+#    define IN_SECTION(n) __declspec(allocate(n))
+#  else
+#    define IN_SECTION(n) __attribute__((section(n)))
+#  endif
 
 #  if !SANITIZER_GO
 



More information about the llvm-commits mailing list