https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=1186791e9f404644832023b8fa801227c2995ab7
commit 1186791e9f404644832023b8fa801227c2995ab7 Author: Jeremy Drake <cyg...@jdrake.com> Date: Mon Jun 16 11:50:18 2025 -0700 Cygwin: make pthread initializer macros constinit compliant In order to avoid a restriction on any reinterpret_cast-like behavior in constinit expressions, use assembly and the linker to define symbols with the not-valid-address addresses. Due to being built with -mcmodel=small, this linker trick does not always work in the Cygwin DLL, specifically in the cases where they are used in comparisons (==). As a result, leave the case where the symbols would have had to have been classes rather than structs as casts of integers. If Cygwin ever needs these to be constinit compliant, it may need to move to the medium code model or add some other workaround. Signed-off-by: Jeremy Drake <cyg...@jdrake.com> (cherry picked from commit 5be6ebd4d5c3492c539e662cc8849c284a456e7d) Diff: --- winsup/cygwin/Makefile.am | 4 +++- winsup/cygwin/include/pthread.h | 31 ++++++++++++++++++++++++------- winsup/cygwin/lib/pthreadconst.S | 17 +++++++++++++++++ winsup/cygwin/release/3.6.4 | 3 +++ 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am index d47a1a2d1..383f4f34a 100644 --- a/winsup/cygwin/Makefile.am +++ b/winsup/cygwin/Makefile.am @@ -76,7 +76,8 @@ LIB_FILES= \ lib/premain1.c \ lib/premain2.c \ lib/premain3.c \ - lib/pseudo-reloc-dummy.c + lib/pseudo-reloc-dummy.c \ + lib/pthreadconst.S FHANDLER_FILES= \ fhandler/base.cc \ @@ -306,6 +307,7 @@ DLL_FILES= \ ipc.cc \ kernel32.cc \ ldap.cc \ + lib/pthreadconst.S \ libstdcxx_wrapper.cc \ loadavg.cc \ lsearch.cc \ diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h index 8e296303d..b2154651c 100644 --- a/winsup/cygwin/include/pthread.h +++ b/winsup/cygwin/include/pthread.h @@ -31,8 +31,6 @@ extern "C" #define PTHREAD_CANCEL_DEFERRED 0 #define PTHREAD_CANCEL_DISABLE 1 #define PTHREAD_CANCELED ((void *)-1) -/* this should be a value that can never be a valid address */ -#define PTHREAD_COND_INITIALIZER (pthread_cond_t)21 #define PTHREAD_CREATE_DETACHED 1 /* the default : joinable */ #define PTHREAD_CREATE_JOINABLE 0 @@ -42,10 +40,6 @@ extern "C" #define PTHREAD_MUTEX_ERRORCHECK 1 #define PTHREAD_MUTEX_NORMAL 2 #define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL -/* this should be too low to ever be a valid address */ -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP (pthread_mutex_t)18 -#define PTHREAD_NORMAL_MUTEX_INITIALIZER_NP (pthread_mutex_t)19 -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP (pthread_mutex_t)20 #define PTHREAD_MUTEX_INITIALIZER PTHREAD_NORMAL_MUTEX_INITIALIZER_NP #define PTHREAD_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, 0 } #if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT >= 0 @@ -55,12 +49,35 @@ extern "C" #endif #define PTHREAD_PROCESS_SHARED 1 #define PTHREAD_PROCESS_PRIVATE 0 -#define PTHREAD_RWLOCK_INITIALIZER (pthread_rwlock_t)22 /* process is the default */ #define PTHREAD_SCOPE_PROCESS 0 #define PTHREAD_SCOPE_SYSTEM 1 #define PTHREAD_BARRIER_SERIAL_THREAD (-1) +/* This condition matches the one in <sys/_pthreadtypes.h> */ +#if !defined(__INSIDE_CYGWIN__) || !defined(__cplusplus) +/* Constants for initializer macros */ +extern struct __pthread_mutex_t __pthread_recursive_mutex_initializer_np; +extern struct __pthread_mutex_t __pthread_normal_mutex_initializer_np; +extern struct __pthread_mutex_t __pthread_errorcheck_mutex_initializer_np; +extern struct __pthread_cond_t __pthread_cond_initializer; +extern struct __pthread_rwlock_t __pthread_rwlock_initializer; +#define PTHREAD_COND_INITIALIZER (&__pthread_cond_initializer) +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP (&__pthread_recursive_mutex_initializer_np) +#define PTHREAD_NORMAL_MUTEX_INITIALIZER_NP (&__pthread_normal_mutex_initializer_np) +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP (&__pthread_errorcheck_mutex_initializer_np) +#define PTHREAD_RWLOCK_INITIALIZER (&__pthread_rwlock_initializer) +#else +/* Inside the Cygwin DLL's C++ code, using absolute linker symbols sometimes + results in "relocation truncated to fit" errors due to being built with + -mcmodel=small. */ +#define PTHREAD_COND_INITIALIZER (pthread_cond_t)21 +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP (pthread_mutex_t)18 +#define PTHREAD_NORMAL_MUTEX_INITIALIZER_NP (pthread_mutex_t)19 +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP (pthread_mutex_t)20 +#define PTHREAD_RWLOCK_INITIALIZER (pthread_rwlock_t)22 +#endif + /* Register Fork Handlers */ int pthread_atfork (void (*)(void), void (*)(void), void (*)(void)); diff --git a/winsup/cygwin/lib/pthreadconst.S b/winsup/cygwin/lib/pthreadconst.S new file mode 100644 index 000000000..6e55a832a --- /dev/null +++ b/winsup/cygwin/lib/pthreadconst.S @@ -0,0 +1,17 @@ +#if defined(__i386__) +# define SYM(x) _##x +#else +# define SYM(x) x +#endif + +/* these should all be too low to ever be valid addresses */ +.globl SYM(__pthread_recursive_mutex_initializer_np) +.set __pthread_recursive_mutex_initializer_np, 18 +.globl SYM(__pthread_normal_mutex_initializer_np) +.set __pthread_normal_mutex_initializer_np, 19 +.globl SYM(__pthread_errorcheck_mutex_initializer_np) +.set __pthread_errorcheck_mutex_initializer_np, 20 +.globl SYM(__pthread_cond_initializer) +.set __pthread_cond_initializer, 21 +.globl SYM(__pthread_rwlock_initializer) +.set __pthread_rwlock_initializer, 22 diff --git a/winsup/cygwin/release/3.6.4 b/winsup/cygwin/release/3.6.4 index ef3aec68e..8eb693c40 100644 --- a/winsup/cygwin/release/3.6.4 +++ b/winsup/cygwin/release/3.6.4 @@ -3,3 +3,6 @@ Fixes: - Fix unexpected crash when SIGSEGV occurs too frequently. Addresses: https://cygwin.com/pipermail/cygwin/2025-May/258153.html + +- Make pthread initializer macros compatible with C++ constinit. + Addresses: https://cygwin.com/pipermail/cygwin/2025-June/258305.html