Hello,

The definitions and declarations of mig_dealloc_reply_port() are
confusing, some use an argument, some don't:

Declaration (function argument): glibc-2.19/mach/mach/mig_support.h
/* Reply-port management support functions.  */
extern void __mig_dealloc_reply_port (mach_port_t);
extern void mig_dealloc_reply_port (mach_port_t);

Definition (no function argument): glibc/sysdeps/mach/hurd/mig-reply.c
/* Called by MiG to deallocate the reply port.  */
void __mig_dealloc_reply_port (mach_port_t arg)
{
  mach_port_t port = __hurd_local_reply_port;
  __hurd_local_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,
                          MACH_PORT_RIGHT_RECEIVE, -1);
}
weak_alias (__mig_dealloc_reply_port, mig_dealloc_reply_port)

Calls in glibc (function argument): glibc/sysdeps/mach/hurd/dl-sysdep.c
  /* Deallocate the reply port and task port rights acquired by
     __mach_init.  We are done with them now, and the user will
     reacquire them for himself when he wants them.  */
  __mig_dealloc_reply_port (MACH_PORT_NULL);

Calls in mig: mig-1.4/user.c
static void
WriteMsgCheckReceive(FILE *file, const routine_t *rt, const char
*success)
{
...
  /* If we aren't using a user-supplied reply port,
     then deallocate the reply port on any message transmission
     errors. */
     fprintf(file, "\t\t%smig_dealloc_reply_port(%s);\n",
             SubrPrefix, "InP->Head.msgh_reply_port");
...
}

static void
WriteCheckIdentity(FILE *file, const routine_t *rt)
{
...
    fprintf(file, "\t\telse {\n");
    fprintf(file, "\t\t\t%smig_dealloc_reply_port(%s);\n\t",
          SubrPrefix,"InP->Head.msgh_reply_port");
    WriteMsgError(file, rt, "MIG_REPLY_MISMATCH");
...
}

WriteGlobalDecls(FILE *file)
{
...
    fprintf(file, "#define msgh_reply_port\t\tmsgh_local_port\n");
...
}

Since the mach_msg_header_t struct in mach/message.h has a
member msgh_local_port and the above the msgh_reply_port referred to
the InP struct in mig/user.c should be the same (true?) as
_hurd_local_reply_port in mig-reply.c the functionality should not
affected. Hence, no bug here??

_hurd_reply_port is defined in /usr/include/hurd/threadvar.h:
#define __hurd_local_reply_port (*(__LIBC_NO_TLS() ?
&__hurd_reply_port0 : &THREAD_SELF->reply_port))

and __LIBC_NO_TLS() is defined at compile/runtime
in sysdeps/mach/hurd/i386/tls.h:

#define __LIBC_NO_TLS() \
  ({ unsigned short ds,gs; \
     asm ("movw %%ds,%w0; movw %%gs,%w1" : "=q" (ds), "=q" (gs)); \
     ds == gs; })

which returns to ?? (probable result: &THREAD_SELF->reply_port)

However, it's confusing that the definition of _mig_dealloc_reply_port
in mig-reply.c ignores the function argument and the calls in mig and
dl-sysdeps.c do use an argument, a patch like the one below could make
things much clearer:

Index: glibc-2.19/sysdeps/mach/hurd/mig-reply.c
===================================================================
--- glibc-2.19.orig/sysdeps/mach/hurd/mig-reply.c
+++ glibc-2.19/sysdeps/mach/hurd/mig-reply.c
@@ -39,7 +39,7 @@ weak_alias (__mig_get_reply_port, mig_ge
 void
 __mig_dealloc_reply_port (mach_port_t arg)
 {
-  mach_port_t port = __hurd_local_reply_port;
+  mach_port_t port = arg;
   __hurd_local_reply_port = MACH_PORT_NULL;    /* So the mod_refs RPC
won't use it.  */
 
   if (MACH_PORT_VALID (port))

Another solution could be to remove the argument in the
mig_dealloc_reply_port definition, but that would require a change also
to mig.

Reply via email to