diff options
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | hurd/catch-exc.c | 57 | ||||
-rw-r--r-- | hurd/hurdfault.c | 92 | ||||
-rw-r--r-- | hurd/hurdselect.c | 32 | ||||
-rw-r--r-- | sysdeps/mach/hurd/ioctl.c | 79 | ||||
-rw-r--r-- | sysdeps/mach/powerpc/sysdep.h | 3 |
6 files changed, 247 insertions, 39 deletions
diff --git a/ChangeLog b/ChangeLog index baecd80c55..ac45b25ac6 100644 --- 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. diff --git a/hurd/catch-exc.c b/hurd/catch-exc.c index 9eef252df1..6c58793a98 100644 --- a/hurd/catch-exc.c +++ b/hurd/catch-exc.c @@ -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 diff --git a/hurd/hurdfault.c b/hurd/hurdfault.c index e761d36fe1..ceb2f8c679 100644 --- a/hurd/hurdfault.c +++ b/hurd/hurdfault.c @@ -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 diff --git a/hurd/hurdselect.c b/hurd/hurdselect.c index c3dfb52119..68dc746925 100644 --- a/hurd/hurdselect.c +++ b/hurd/hurdselect.c @@ -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. */ diff --git a/sysdeps/mach/hurd/ioctl.c b/sysdeps/mach/hurd/ioctl.c index 6927906507..08389968df 100644 --- a/sysdeps/mach/hurd/ioctl.c +++ b/sysdeps/mach/hurd/ioctl.c @@ -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 @@ -39,12 +39,14 @@ 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; } diff --git a/sysdeps/mach/powerpc/sysdep.h b/sysdeps/mach/powerpc/sysdep.h index 18091581b4..00e4570fad 100644 --- a/sysdeps/mach/powerpc/sysdep.h +++ b/sysdeps/mach/powerpc/sysdep.h @@ -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 |