* hurd/hurdselect.c (_hurd_select) [MACH_MSG_TRAILER_MINIMUM_SIZE]:
authorRoland McGrath <roland@gnu.org>
Sun, 17 Feb 2002 22:54:39 +0000 (22:54 +0000)
committerRoland McGrath <roland@gnu.org>
Sun, 17 Feb 2002 22:54:39 +0000 (22:54 +0000)
Use untyped Mach IPC message format.

* sysdeps/mach/hurd/ioctl.c (__ioctl) [! MACH_MSG_TYPE_BIT]: Handle
Handle untyped Mach IPC message formats.

* hurd/catch-exc.c (_S_catch_exception_raise) [EXC_MASK_ALL]:
Expect different argument conventions when this is defined.
[EXC_MASK_ALL] (_S_catch_exception_raise_state): New stub function.
[EXC_MASK_ALL] (_S_catch_exception_raise_state_identity): Likewise.
* hurd/hurdfault.c: Likewise for _hurdsig_fault_catch_exception_*.
[NDR_CHAR_ASCII] (mig_reply_header_t): #define as mig_reply_error_t
for OSF Mach variant.
(faulted): Use mig_reply_error_t for REPLY.
(_hurdsig_fault_init) [EXC_MASK_ALL]: Use EXCEPTION_STATE_IDENTITY
in __thread_set_exception_ports call.
(_hurdsig_fault_init) [MACH_PORT_RECEIVE_STATUS]: Use
__mach_port_set_attributes in place of __mach_port_set_qlimit.

* sysdeps/mach/powerpc/sysdep.h (_MACH_MACHINE_ASM_H): Define this
before include <sysdeps/mach/sysdep.h>, to inhibit <mach/machine/asm.h>
on Darwin, which includes bogons.

ChangeLog
hurd/catch-exc.c
hurd/hurdfault.c
hurd/hurdselect.c
sysdeps/mach/hurd/ioctl.c
sysdeps/mach/powerpc/sysdep.h

index baecd80..ac45b25 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,28 @@
 2002-02-17  Roland McGrath  <roland@frob.com>
 
+       * hurd/hurdselect.c (_hurd_select) [MACH_MSG_TRAILER_MINIMUM_SIZE]:
+       Use untyped Mach IPC message format.
+
+       * sysdeps/mach/hurd/ioctl.c (__ioctl) [! MACH_MSG_TYPE_BIT]: Handle
+       Handle untyped Mach IPC message formats.
+
+       * hurd/catch-exc.c (_S_catch_exception_raise) [EXC_MASK_ALL]:
+       Expect different argument conventions when this is defined.
+       [EXC_MASK_ALL] (_S_catch_exception_raise_state): New stub function.
+       [EXC_MASK_ALL] (_S_catch_exception_raise_state_identity): Likewise.
+       * hurd/hurdfault.c: Likewise for _hurdsig_fault_catch_exception_*.
+       [NDR_CHAR_ASCII] (mig_reply_header_t): #define as mig_reply_error_t
+       for OSF Mach variant.
+       (faulted): Use mig_reply_error_t for REPLY.
+       (_hurdsig_fault_init) [EXC_MASK_ALL]: Use EXCEPTION_STATE_IDENTITY
+       in __thread_set_exception_ports call.
+       (_hurdsig_fault_init) [MACH_PORT_RECEIVE_STATUS]: Use
+       __mach_port_set_attributes in place of __mach_port_set_qlimit.
+
+       * sysdeps/mach/powerpc/sysdep.h (_MACH_MACHINE_ASM_H): Define this
+       before include <sysdeps/mach/sysdep.h>, to inhibit <mach/machine/asm.h>
+       on Darwin, which includes bogons.
+
        * sysdeps/powerpc/dl-machine.h (elf_machine_rela): Move local
        variable LOADBASE so it's not declared when it's not used.
 
index 9eef252..6c58793 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1994,95,96,97,2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -25,9 +25,14 @@ kern_return_t
 _S_catch_exception_raise (mach_port_t port,
                          thread_t thread,
                          task_t task,
-                         int exception,
-                         int code,
-                         int subcode)
+#ifdef EXC_MASK_ALL            /* New interface flavor.  */
+                         exception_type_t exception,
+                         exception_data_t code,
+                         mach_msg_type_number_t codeCnt
+#else                          /* Vanilla Mach 3.0 interface.  */
+                         int exception, int code, int subcode
+#endif
+                         )
 {
   struct hurd_sigstate *ss;
   int signo;
@@ -38,8 +43,14 @@ _S_catch_exception_raise (mach_port_t port,
     return EPERM;
 
   d.exc = exception;
+#ifdef EXC_MASK_ALL
+  assert (codeCnt >= 2);
+  d.exc_code = code[0];
+  d.exc_subcode = code[1];
+#else
   d.exc_code = code;
   d.exc_subcode = subcode;
+#endif
 
   /* Call the machine-dependent function to translate the Mach exception
      codes into a signal number and subcode.  */
@@ -79,3 +90,41 @@ _S_catch_exception_raise (mach_port_t port,
 
   return KERN_SUCCESS;
 }
+
+#ifdef EXC_MASK_ALL
+/* XXX New interface flavor has additional RPCs that we could be using
+   instead.  These RPCs roll a thread_get_state/thread_set_state into
+   the message, so the signal thread ought to use these to save some calls.
+ */
+kern_return_t
+_S_catch_exception_raise_state (mach_port_t port,
+                               exception_type_t exception,
+                               exception_data_t code,
+                               mach_msg_type_number_t codeCnt,
+                               int *flavor,
+                               thread_state_t old_state,
+                               mach_msg_type_number_t old_stateCnt,
+                               thread_state_t new_state,
+                               mach_msg_type_number_t *new_stateCnt)
+{
+  abort ();
+  return KERN_FAILURE;
+}
+
+kern_return_t
+_S_catch_exception_raise_state_identity (mach_port_t exception_port,
+                                        thread_t thread,
+                                        task_t task,
+                                        exception_type_t exception,
+                                        exception_data_t code,
+                                        mach_msg_type_number_t codeCnt,
+                                        int *flavor,
+                                        thread_state_t old_state,
+                                        mach_msg_type_number_t old_stateCnt,
+                                        thread_state_t new_state,
+                                        mach_msg_type_number_t *new_stateCnt)
+{
+  abort ();
+  return KERN_FAILURE;
+}
+#endif
index e761d36..ceb2f8c 100644 (file)
@@ -40,9 +40,14 @@ kern_return_t
 _hurdsig_fault_catch_exception_raise (mach_port_t port,
                                      thread_t thread,
                                      task_t task,
-                                     int exception,
-                                     int code,
-                                     int subcode)
+#ifdef EXC_MASK_ALL            /* New interface flavor.  */
+                                     exception_type_t exception,
+                                     exception_data_t code,
+                                     mach_msg_type_number_t codeCnt
+#else                          /* Vanilla Mach 3.0 interface.  */
+                                     int exception, int code, int subcode
+#endif
+                                     )
 {
   int signo;
   struct hurd_signal_detail d;
@@ -52,8 +57,14 @@ _hurdsig_fault_catch_exception_raise (mach_port_t port,
     return EPERM;              /* Strange bogosity.  */
 
   d.exc = exception;
+#ifdef EXC_MASK_ALL
+  assert (codeCnt >= 2);
+  d.exc_code = code[0];
+  d.exc_subcode = code[1];
+#else
   d.exc_code = code;
   d.exc_subcode = subcode;
+#endif
 
   /* Call the machine-dependent function to translate the Mach exception
      codes into a signal number and subcode.  */
@@ -63,6 +74,51 @@ _hurdsig_fault_catch_exception_raise (mach_port_t port,
     ? 0 : EGREGIOUS;
 }
 
+#ifdef EXC_MASK_ALL
+/* XXX New interface flavor has additional RPCs that we could be using
+   instead.  These RPCs roll a thread_get_state/thread_set_state into
+   the message, so the signal thread ought to use these to save some calls.
+ */
+kern_return_t
+_hurdsig_fault_catch_exception_raise_state
+(mach_port_t port,
+ exception_type_t exception,
+ exception_data_t code,
+ mach_msg_type_number_t codeCnt,
+ int *flavor,
+ thread_state_t old_state,
+ mach_msg_type_number_t old_stateCnt,
+ thread_state_t new_state,
+ mach_msg_type_number_t *new_stateCnt)
+{
+  abort ();
+  return KERN_FAILURE;
+}
+
+kern_return_t
+_hurdsig_fault_catch_exception_raise_state_identity
+(mach_port_t exception_port,
+ thread_t thread,
+ task_t task,
+ exception_type_t exception,
+ exception_data_t code,
+ mach_msg_type_number_t codeCnt,
+ int *flavor,
+ thread_state_t old_state,
+ mach_msg_type_number_t old_stateCnt,
+ thread_state_t new_state,
+ mach_msg_type_number_t *new_stateCnt)
+{
+  abort ();
+  return KERN_FAILURE;
+}
+#endif
+
+
+#ifdef NDR_CHAR_ASCII          /* OSF Mach flavors have different names.  */
+# define mig_reply_header_t    mig_reply_error_t
+#endif
+
 static void
 faulted (void)
 {
@@ -71,12 +127,7 @@ faulted (void)
       mach_msg_header_t head;
       char buf[64];
     } request;
-  struct
-    {
-      mach_msg_header_t head;
-      mach_msg_type_t type;
-      int result;
-    } reply;
+  mig_reply_header_t reply;
   extern int _hurdsig_fault_exc_server (mach_msg_header_t *,
                                        mach_msg_header_t *);
 
@@ -90,14 +141,14 @@ faulted (void)
 
   /* Run the exc demuxer which should call the server function above.
      That function returns 0 if the exception was expected.  */
-  _hurdsig_fault_exc_server (&request.head, &reply.head);
-  if (reply.head.msgh_remote_port != MACH_PORT_NULL)
-    __mach_msg (&reply.head, MACH_SEND_MSG, reply.head.msgh_size,
+  _hurdsig_fault_exc_server (&request.head, &reply.Head);
+  if (reply.Head.msgh_remote_port != MACH_PORT_NULL)
+    __mach_msg (&reply.Head, MACH_SEND_MSG, reply.Head.msgh_size,
                0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-  if (reply.result == MIG_BAD_ID)
+  if (reply.RetCode == MIG_BAD_ID)
     __mach_msg_destroy (&request.head);
 
-  if (reply.result)
+  if (reply.RetCode)
     __libc_fatal ("BUG: unexpected fault in signal thread\n");
 
   _hurdsig_fault_preemptor.signals = 0;
@@ -136,7 +187,17 @@ _hurdsig_fault_init (void)
   /* Set the queue limit for this port to just one.  The proc server will
      notice if we ever get a second exception while one remains queued and
      unreceived, and decide we are hopelessly buggy.  */
+#ifdef MACH_PORT_RECEIVE_STATUS_COUNT
+  {
+    const mach_port_limits_t lim = { mpl_qlimit: 1 };
+    assert (MACH_PORT_RECEIVE_STATUS_COUNT == sizeof lim / sizeof (natural_t));
+    err = __mach_port_set_attributes (__mach_task_self (), forward_sigexc,
+                                     MACH_PORT_RECEIVE_STATUS,
+                                     &lim, MACH_PORT_RECEIVE_STATUS_COUNT);
+  }
+#else
   err = __mach_port_set_qlimit (__mach_task_self (), forward_sigexc, 1);
+#endif
   assert_perror (err);
 
   /* This state will be restored when we fault.
@@ -165,7 +226,8 @@ _hurdsig_fault_init (void)
                                                 | EXC_MASK_MACH_SYSCALL
                                                 | EXC_MASK_RPC_ALERT),
                                sigexc,
-                               EXCEPTION_DEFAULT, MACHINE_THREAD_STATE);
+                               EXCEPTION_STATE_IDENTITY,
+                               MACHINE_THREAD_STATE);
 #else
 # error thread_set_exception_ports?
 #endif
index c3dfb52..68dc746 100644 (file)
@@ -279,6 +279,22 @@ _hurd_select (int nfds,
       union
        {
          mach_msg_header_t head;
+#ifdef MACH_MSG_TRAILER_MINIMUM_SIZE
+         struct
+           {
+             mach_msg_header_t head;
+             NDR_record_t ndr;
+             error_t err;
+           } error;
+         struct
+           {
+             mach_msg_header_t head;
+             NDR_record_t ndr;
+             error_t err;
+             int result;
+             mach_msg_trailer_t trailer;
+           } success;
+#else
          struct
            {
              mach_msg_header_t head;
@@ -293,6 +309,7 @@ _hurd_select (int nfds,
              mach_msg_type_t result_type;
              int result;
            } success;
+#endif
        } msg;
       mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT);
       error_t msgerr;
@@ -303,13 +320,18 @@ _hurd_select (int nfds,
        {
          /* We got a message.  Decode it.  */
 #define IO_SELECT_REPLY_MSGID (21012 + 100) /* XXX */
+#ifdef MACH_MSG_TYPE_BIT
          const mach_msg_type_t inttype =
            { MACH_MSG_TYPE_INTEGER_T, sizeof (MACH_MSG_TYPE_INTEGER_T) * 8,
              1, 1, 0, 0 };
-         if (msg.head.msgh_id == IO_SELECT_REPLY_MSGID &&
-             msg.head.msgh_size >= sizeof msg.error &&
-             !(msg.head.msgh_bits & MACH_MSGH_BITS_COMPLEX) &&
-             *(int *) &msg.error.err_type == *(int *) &inttype)
+#endif
+         if (msg.head.msgh_id == IO_SELECT_REPLY_MSGID
+             && msg.head.msgh_size >= sizeof msg.error
+             && !(msg.head.msgh_bits & MACH_MSGH_BITS_COMPLEX)
+#ifdef MACH_MSG_TYPE_BIT
+             && *(int *) &msg.error.err_type == *(int *) &inttype
+#endif
+             )
            {
              /* This is a properly formatted message so far.
                 See if it is a success or a failure.  */
@@ -323,7 +345,9 @@ _hurd_select (int nfds,
                }
              if (msg.error.err ||
                  msg.head.msgh_size != sizeof msg.success ||
+#ifdef MACH_MSG_TYPE_BIT
                  *(int *) &msg.success.result_type != *(int *) &inttype ||
+#endif
                  (msg.success.result & SELECT_ALL) == 0)
                {
                  /* Error or bogus reply.  Simulate readiness.  */
index 6927906..0838996 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992,93,94,95,96,97,99,2000 Free Software Foundation, Inc.
+/* Copyright (C) 1992,93,94,95,96,97,99,2000,02 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
 int
 __ioctl (int fd, unsigned long int request, ...)
 {
+#ifdef MACH_MSG_TYPE_CHAR
   /* Map individual type fields to Mach IPC types.  */
   static const int mach_types[] =
     { MACH_MSG_TYPE_CHAR, MACH_MSG_TYPE_INTEGER_16, MACH_MSG_TYPE_INTEGER_32,
       MACH_MSG_TYPE_INTEGER_64 };
 #define io2mach_type(count, type) \
   ((mach_msg_type_t) { mach_types[type], typesize (type) * 8, count, 1, 0, 0 })
+#endif
 
   /* Extract the type information encoded in the request.  */
   unsigned int type = _IOC_TYPE (request);
@@ -53,17 +55,29 @@ __ioctl (int fd, unsigned long int request, ...)
 #define msg_align(x) \
   (((x) + sizeof (mach_msg_type_t) - 1) & ~(sizeof (mach_msg_type_t) - 1))
   struct
-    {
-      mig_reply_header_t header;
-      char data[3 * sizeof (mach_msg_type_t) +
-               msg_align (_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type))) +
-               msg_align (_IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type))) +
-               _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
-    } msg;
+  {
+#ifdef MACH_MSG_TYPE_BIT
+    mig_reply_header_t header;
+    char data[3 * sizeof (mach_msg_type_t) +
+            msg_align (_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type))) +
+            msg_align (_IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type))) +
+            _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
+#else  /* Untyped Mach IPC format.  */
+    mig_reply_error_t header;
+    char data[_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type)) +
+            _IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type)) +
+            _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
+    mach_msg_trailer_t trailer;
+#endif
+  } msg;
   mach_msg_header_t *const m = &msg.header.Head;
-  mach_msg_type_t *t;
   mach_msg_id_t msgid;
   unsigned int reply_size;
+#ifdef MACH_MSG_TYPE_BIT
+  mach_msg_type_t *t;
+#else
+  void *p;
+#endif
 
   void *arg;
 
@@ -74,7 +88,11 @@ __ioctl (int fd, unsigned long int request, ...)
   error_t send_rpc (io_t ioport)
     {
       error_t err;
+#ifdef MACH_MSG_TYPE_BIT
       mach_msg_type_t *t = &msg.header.RetCodeType;
+#else
+      void *p = &msg.header.RetCode;
+#endif
 
       /* Marshal the request arguments into the message buffer.
         We must redo this work each time we retry the RPC after a SIGTTOU,
@@ -92,14 +110,18 @@ __ioctl (int fd, unsigned long int request, ...)
            {
              if (count > 0)
                {
-                 void *p = &t[1];
                  const size_t len = count * typesize ((unsigned int) type);
+#ifdef MACH_MSG_TYPE_BIT
+                 void *p = &t[1];
                  *t = io2mach_type (count, type);
                  p = __mempcpy (p, argptr, len);
-                 argptr += len;
                  p = (void *) (((uintptr_t) p + sizeof (*t) - 1)
                                & ~(sizeof (*t) - 1));
                  t = p;
+#else
+                 p = __mempcpy (p, argptr, len);
+#endif
+                 argptr += len;
                }
            }
 
@@ -112,14 +134,24 @@ __ioctl (int fd, unsigned long int request, ...)
        {
          /* The RPC takes a single integer_t argument.
             Rather than pointing to the value, ARG is the value itself.  */
+#ifdef MACH_MSG_TYPE_BIT
          *t++ = io2mach_type (1, _IOTS (int));
          *((int *) t)++ = (int) arg;
+#else
+         *((int *) p)++ = (int) arg;
+#endif
        }
 
-      m->msgh_size = (char *) t - (char *) &msg;
+      memset (m, 0, sizeof *m);        /* Clear unused fields.  */
+      m->msgh_size = (
+#ifdef MACH_MSG_TYPE_BIT
+                     (char *) t
+#else
+                     (char *) p
+#endif
+                     - (char *) &msg);
       m->msgh_remote_port = ioport;
       m->msgh_local_port = __mig_get_reply_port ();
-      m->msgh_seqno = 0;
       m->msgh_id = msgid;
       m->msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND,
                                     MACH_MSG_TYPE_MAKE_SEND_ONCE);
@@ -153,13 +185,15 @@ __ioctl (int fd, unsigned long int request, ...)
                MIG_SERVER_DIED : MIG_REPLY_MISMATCH);
 
       if (m->msgh_size != reply_size &&
-         m->msgh_size != sizeof (mig_reply_header_t))
+         m->msgh_size != sizeof msg.header)
        return MIG_TYPE_ERROR;
 
+#ifdef MACH_MSG_TYPE_BIT
       if (*(int *) &msg.header.RetCodeType !=
          ((union { mach_msg_type_t t; int i; })
           { t: io2mach_type (1, _IOTS (sizeof msg.header.RetCode)) }).i)
        return MIG_TYPE_ERROR;
+#endif
       return msg.header.RetCode;
     }
 
@@ -193,7 +227,7 @@ __ioctl (int fd, unsigned long int request, ...)
   /* Compute the expected size of the reply.  There is a standard header
      consisting of the message header and the reply code.  Then, for out
      and in/out ioctls, there come the data with their type headers.  */
-  reply_size = sizeof (mig_reply_header_t);
+  reply_size = sizeof msg.header;
 
   if (_IOC_INOUT (request) & IOC_OUT)
     {
@@ -201,11 +235,15 @@ __ioctl (int fd, unsigned long int request, ...)
        {
          if (count > 0)
            {
+#ifdef MACH_MSG_TYPE_BIT
              /* Add the size of the type and data.  */
              reply_size += sizeof (mach_msg_type_t) + typesize (type) * count;
              /* Align it to word size.  */
              reply_size += sizeof (mach_msg_type_t) - 1;
              reply_size &= ~(sizeof (mach_msg_type_t) - 1);
+#else
+             reply_size += typesize (type) * count;
+#endif
            }
        }
       figure_reply (_IOT_COUNT0 (type), _IOT_TYPE0 (type));
@@ -218,7 +256,11 @@ __ioctl (int fd, unsigned long int request, ...)
      into either SIGTTOU or EIO.  */
   err = HURD_DPORT_USE (fd, _hurd_ctty_output (port, ctty, send_rpc));
 
+#ifdef MACH_MSG_TYPE_BIT
   t = (mach_msg_type_t *) msg.data;
+#else
+  p = (void *) msg.data;
+#endif
   switch (err)
     {
       /* Unpack the message buffer into the argument location.  */
@@ -228,6 +270,7 @@ __ioctl (int fd, unsigned long int request, ...)
          if (count > 0)
            {
              const size_t len = count * typesize (type);
+#ifdef MACH_MSG_TYPE_BIT
              union { mach_msg_type_t t; int i; } ipctype;
              ipctype.t = io2mach_type (count, type);
              if (*(int *) t != ipctype.i)
@@ -238,6 +281,12 @@ __ioctl (int fd, unsigned long int request, ...)
                *update += len;
              t = (void *) (((uintptr_t) t + len + sizeof (*t) - 1)
                            & ~(sizeof (*t) - 1));
+#else
+             memcpy (store, p, len);
+             p += len;
+             if (update != NULL)
+               *update += len;
+#endif
            }
          return 0;
        }
index 1809158..00e4570 100644 (file)
@@ -1,5 +1,5 @@
 /* system call details for Mach on PowerPC
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright (C) 2001,02 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -42,6 +42,7 @@
                   : : "r" (sp), "r" (pc), "r" (retval))
 
 /* Get the machine-independent Mach definitions.  */
+#define _MACH_MACHINE_ASM_H 1  /* Kludge to avoid bad Darwin header file.  */
 #include <sysdeps/mach/sysdep.h>
 
 #undef ENTRY