diff options
author | Roland McGrath <roland@gnu.org> | 1994-09-04 04:59:50 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1994-09-04 04:59:50 +0000 |
commit | ae6ab434da602d47c70969b0770d11f5abe962d8 (patch) | |
tree | fdcfaa2700797d702116e7e1bea47ef9eb233fd9 /hurd | |
parent | d5c5f1cff98b71bc414e2da253195b130cdcbdbd (diff) |
Initial revision
Diffstat (limited to 'hurd')
-rw-r--r-- | hurd/hurdfault.c | 135 | ||||
-rw-r--r-- | hurd/hurdfault.h | 49 |
2 files changed, 184 insertions, 0 deletions
diff --git a/hurd/hurdfault.c b/hurd/hurdfault.c new file mode 100644 index 0000000000..14a465f3d7 --- /dev/null +++ b/hurd/hurdfault.c @@ -0,0 +1,135 @@ +/* Handle faults in the signal thread. +Copyright (C) 1994 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 +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/fault.h> +#include <string.h> +#include <setjmp.h> +#include "thread_state.h" + +jmp_buf _hurdsig_fault_env; + +static mach_port_t forward_sigexc; + +int _hurdsig_fault_expect_signo; +int _hurdsig_fault_sigcode; +int _hurdsig_fault_sigerror; + +kern_return_t +_hurdsig_fault_catch_exception_raise (mach_port_t port, + thread_t thread, + task_t task, + int exception, + int code, + int subcode) +{ + int signo, sigcode, error; + + if (port != forward_sigexc || + thread != _hurd_msgport_thread || task != __mach_task_self ()) + return EPERM; /* Strange bogosity. */ + + /* Call the machine-dependent function to translate the Mach exception + codes into a signal number and subcode. */ + _hurd_exception2signal (exception, code, subcode, &signo, + &_hurdsig_fault_sigcode, &_hurdsig_fault_error); + + return signo == _hurdsig_fault_expect_signo ? 0 : EGREGIOUS; +} + +static void +faulted (void) +{ + struct + { + mach_msg_header_t header; + char buf[64]; + } request; + struct + { + mach_msg_header_t header; + mach_msg_type_t type; + int result; + } reply; + + /* Wait for the exception_raise message forwarded by the proc server. */ + + if (__mach_msg (&request->head, MACH_RCV_MSG, 0, + sizeof request, sigexc, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL) + != MACH_MSG_SUCCESS) + __libc_fatal ("msg receive failed on signal thread exc\n"); + + /* Run the exc demuxer which should call the server function above. + That function returns 0 if the exception was expected. */ + switch (_hurdsig_fault_exc_server (&request->head, &reply->head)) + { + case KERN_SUCCESS: + if (reply->header.msgh_remote_port != MACH_PORT_NULL) + __mach_msg (&reply->head, MACH_SEND_MSG, reply->header.msgh_size, + 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + break; + default: + __mach_msg_destroy (&request->head); + case MIG_NO_REPLY: + } + + _hurdsig_expect_signo = 0; + longjmp (_hurdsig_fault_env, 1); +} + +static char faultstack[1024]; + +/* Send exceptions for the signal thread to the proc server. + It will forward the message on to our message port, + and then restore the thread's state to code which + does `longjmp (_hurd_sigthread_fault_env, 1)'. */ + +void +_hurdsig_fault_init (void) +{ + error_t err; + struct machine_thread_state state; + mach_port_t sigexc; + + if (err = __mach_port_allocate (__mach_task_self (), + MACH_PORT_RIGHT_RECEIVE, &sigexc)) + __libc_fatal ("hurd: Can't create receive right for signal thread exc\n"); + if (err = __mach_port_allocate (__mach_task_self (), + MACH_PORT_RIGHT_RECEIVE, &forward_sigexc)) + __libc_fatal ("hurd: Can't create receive right for signal thread exc\n"); + + memset (&state, 0, sizeof state); + MACHINE_THREAD_STATE_SET_PC (&state, faulted); + MACHINE_THREAD_STATE_SET_SP (&state, faultstack, sizeof faultstack); + +#if 0 /* Don't confuse gdb. */ + __thread_set_special_port (_hurd_msgport_thread, + THREAD_EXCEPTION_PORT, sigexc); +#endif + + if (err = __USEPORT + (PROC, + __proc_handle_exceptions (port, + sigexc, + forward_sigexc, MACH_MSG_TYPE_MAKE_SEND, + MACHINE_THREAD_STATE_FLAVOR, + (int *) &state, MACHINE_THREAD_STATE_COUNT))) + __libc_fatal ("hurd: proc won't handle signal thread exceptions\n"); +} + diff --git a/hurd/hurdfault.h b/hurd/hurdfault.h new file mode 100644 index 0000000000..c905e4e83e --- /dev/null +++ b/hurd/hurdfault.h @@ -0,0 +1,49 @@ +/* Declarations for handling faults in the signal thread. +Copyright (C) 1994 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 +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HURD_FAULT_H +#define _HURD_FAULT_H + +#include <setjmp.h> + +/* Call this before code that might fault in the signal thread; SIGNO is + the signal expected to possibly arrive. This behaves like setjmp: it + returns zero the first time, and returns again nonzero if the signal + does arrive. */ + +#define _hurdsig_catch_fault(signo) \ + (_hurdsig_fault_expect_signo = (signo), setjmp (_hurdsig_fault_env)) + +/* Call this at the end of a section protected by _hurdsig_catch_fault. */ + +#define _hurdsig_end_catch_fault() \ + (_hurdsig_fault_expect_signo = 0) + +extern jmp_buf _hurd_sig_fault_env; +extern int _hurdsig_fault_expect_signo; + +/* If _hurdsig_catch_fault returns nonzero, these variables + contain information about the signal that arrived. */ + + + +extern int _hurdsig_fault_sigcode; +extern int _hurdsig_fault_sigerror; + +#endif /* hurd/fault.h */ |