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.
Signed-off-by: Jeremy Drake <[email protected]> --- This is gross, but I couldn't come up with a way to make this both source and ABI (including C++ name mangling) compatible. I'd be happy to be shown a cleaner way. I built libc++ without a patch to remove constinit, and I'm working on building gcc/libstdc++ to confirm it didn't break anything there. winsup/cygwin/Makefile.am | 4 +++- winsup/cygwin/include/pthread.h | 27 ++++++++++++++++++++------- winsup/cygwin/lib/pthreadconst.S | 17 +++++++++++++++++ 3 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 winsup/cygwin/lib/pthreadconst.S diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am index 6438a41487..31747ac98c 100644 --- a/winsup/cygwin/Makefile.am +++ b/winsup/cygwin/Makefile.am @@ -78,7 +78,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 \ @@ -315,6 +316,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 8e296303d7..6910a5a886 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,31 @@ 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) +#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 +#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 0000000000..6e55a832a4 --- /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 -- 2.49.0.windows.1
