diff options
Diffstat (limited to 'hurd')
-rw-r--r-- | hurd/catch-exc.c | 57 | ||||
-rw-r--r-- | hurd/hurdfault.c | 92 | ||||
-rw-r--r-- | hurd/hurdselect.c | 32 |
3 files changed, 158 insertions, 23 deletions
diff --git a/hurd/catch-exc.c b/hurd/catch-exc.c index 9eef252..6c58793 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 e761d36..ceb2f8c 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 c3dfb52..68dc746 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. */ |