libco: limit scope of section hack to gcc

When placing co_swap_function byte array into the text section, libco
uses the trick of appending a # to the section name. This name string is
passed directly to the generated assembly and the # is treated as
comment token by the GNU assembler. This is a hack to avoid a warning
about changed section attributes.

This hack doesn't work with other compilers like Clang or TinyCC, but
unlike GCC they don't require such hacks. I've added some compile time
checks around the hack to try to isolate it to GCC and allow other
compilers to see the unmodified section name.

Validated on the following OSes/architectures/compilers:
- Windows/amd64: gcc, clang, cl, clang-cl, tcc
- Windows/aarch64: clang, cl, clang-cl
- Linux/amd64: gcc, clang, tcc[1]
- Linux/aarch64: gcc, clang, tcc[1]
- macOS/aarch64: gcc, clang

[1] TCC only works with a fix to glibc headers that was only made very
recently. Without it, you have to #undef __attribute__ after including
glibc headers.
This commit is contained in:
invertego
2025-12-29 12:01:33 +00:00
committed by Luke Usher
parent 30a3b125c8
commit cc4db18707
+5 -19
View File
@@ -34,26 +34,12 @@
#define section(name) __declspec(allocate(".text"))
#elif defined(__APPLE__)
#define section(name) __attribute__((section("__TEXT,__" #name)))
#else
#elif defined(__GNUC__) && !defined(__clang__)
/* the # is treated as comment token by the GNU assembler. */
/* this is a hack to avoid a warning about changed section attributes. */
#define section(name) __attribute__((section("." #name "#")))
#endif
#if defined(__clang__)
#pragma clang diagnostic ignored "-Wparentheses"
#if !defined(_MSC_VER)
/* placing code in section(text) does not mark it executable with Clang. */
#undef LIBCO_MPROTECT
#define LIBCO_MPROTECT
#endif
#endif
#if defined(__aarch64__)
/* NX also seems to be consistently set under non-Windows arm64 */
#if !defined(_MSC_VER)
#undef LIBCO_MPROTECT
#define LIBCO_MPROTECT
#endif
#else
#define section(name) __attribute__((section("." #name)))
#endif
/* if defined(LIBCO_C) */