Now that the signal code no longer accesses it, the only real user of it was mig-reply.c, so move the logic for managing the port there.
If we're in SHARED and outside of rtld, we know that __LIBC_NO_TLS () always evaluates to 0, and a TLS reply port will always be used, not __hurd_reply_port0. Still, the compiler does not see that __hurd_reply_port0 is never used due to its address being taken. To deal with this, explicitly compile out __hurd_reply_port0 when we know we won't use it. Also, instead of accessing the port via THREAD_SELF->reply_port, this uses THREAD_GETMEM and THREAD_SETMEM directly, avoiding possible miscompilations. Signed-off-by: Sergey Bugaev <buga...@gmail.com> --- hurd/hurd/threadvar.h | 7 ------ sysdeps/mach/hurd/mig-reply.c | 43 +++++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/hurd/hurd/threadvar.h b/hurd/hurd/threadvar.h index f5c6a278..c476d988 100644 --- a/hurd/hurd/threadvar.h +++ b/hurd/hurd/threadvar.h @@ -29,11 +29,4 @@ extern unsigned long int __hurd_sigthread_stack_base; extern unsigned long int __hurd_sigthread_stack_end; -/* Store the MiG reply port reply port until we enable TLS. */ -extern mach_port_t __hurd_reply_port0; - -/* This returns either the TLS reply port variable, or a single-thread variable - when TLS is not initialized yet. */ -#define __hurd_local_reply_port (*(__LIBC_NO_TLS () ? &__hurd_reply_port0 : &THREAD_SELF->reply_port)) - #endif /* hurd/threadvar.h */ diff --git a/sysdeps/mach/hurd/mig-reply.c b/sysdeps/mach/hurd/mig-reply.c index 33ff260e..d3c5a958 100644 --- a/sysdeps/mach/hurd/mig-reply.c +++ b/sysdeps/mach/hurd/mig-reply.c @@ -17,32 +17,55 @@ #include <mach.h> #include <mach/mig_support.h> -#include <hurd/threadvar.h> +#include <tls.h> /* These functions are called by MiG-generated code. */ +#if !defined (SHARED) || IS_IN (rtld) mach_port_t __hurd_reply_port0; +#endif + +static mach_port_t +get_reply_port (void) +{ +#if !defined (SHARED) || IS_IN (rtld) + if (__LIBC_NO_TLS ()) + return __hurd_reply_port0; +#endif + return THREAD_GETMEM (THREAD_SELF, reply_port); +} + +static void +set_reply_port (mach_port_t port) +{ +#if !defined (SHARED) || IS_IN (rtld) + if (__LIBC_NO_TLS ()) + __hurd_reply_port0 = port; + else +#endif + THREAD_SETMEM (THREAD_SELF, reply_port, port); +} /* Called by MiG to get a reply port. */ mach_port_t __mig_get_reply_port (void) { - if (__hurd_local_reply_port == MACH_PORT_NULL - || (&__hurd_local_reply_port != &__hurd_reply_port0 - && __hurd_local_reply_port == __hurd_reply_port0)) - __hurd_local_reply_port = __mach_reply_port (); - - return __hurd_local_reply_port; + mach_port_t port = get_reply_port (); + if (__glibc_unlikely (port == MACH_PORT_NULL)) + { + port = __mach_reply_port (); + set_reply_port (port); + } + return port; } weak_alias (__mig_get_reply_port, mig_get_reply_port) libc_hidden_def (__mig_get_reply_port) /* Called by MiG to deallocate the reply port. */ void -__mig_dealloc_reply_port (mach_port_t arg) +__mig_dealloc_reply_port (mach_port_t port) { - mach_port_t port = __hurd_local_reply_port; - __hurd_local_reply_port = MACH_PORT_NULL; /* So the mod_refs RPC won't use it. */ + set_reply_port (MACH_PORT_NULL); /* So the mod_refs RPC won't use it. */ if (MACH_PORT_VALID (port)) __mach_port_mod_refs (__mach_task_self (), port, -- 2.39.2