From edae2ab8afe17418d55bf693da3d3af77c7ba5ed Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 12 Dec 1994 06:43:12 +0000 Subject: [PATCH] Use `long int' for sigcode values. Use _hurdsig_catch_fault. Pass address of __sigreturn in $27, SCP value in $25. In trampoline code, use those regs. --- sysdeps/mach/hurd/alpha/trampoline.c | 83 +++++++++++++++++----------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/sysdeps/mach/hurd/alpha/trampoline.c b/sysdeps/mach/hurd/alpha/trampoline.c index 9b3228467b..455aa57c20 100644 --- a/sysdeps/mach/hurd/alpha/trampoline.c +++ b/sysdeps/mach/hurd/alpha/trampoline.c @@ -20,7 +20,8 @@ Cambridge, MA 02139, USA. */ #include #include "thread_state.h" #include - +#include "hurdfault.h" +#include struct mach_msg_trap_args { @@ -37,7 +38,7 @@ struct mach_msg_trap_args struct sigcontext * _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, - int signo, int sigcode, + int signo, long int sigcode, int rpc_wait, struct machine_thread_all_state *state) { @@ -50,7 +51,10 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, /* We have a previous sigcontext that sigreturn was about to restore when another signal arrived. We will just base our setup on that. */ - if (! setjmp (_hurd_sigthread_fault_env)) + if (_hurdsig_catch_fault (SIGSEGV)) + assert (_hurdsig_fault_sigcode >= (long int) ss->context && + _hurdsig_fault_sigcode < (long int) (ss->context + 1)); + else { memcpy (&state->basic, &ss->context->sc_alpha_thread_state, sizeof (state->basic)); @@ -97,7 +101,16 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, sigsp -= sizeof (*scp); scp = sigsp; - if (! setjmp (_hurd_sigthread_fault_env)) + if (_hurdsig_catch_fault (SIGSEGV)) + { + assert (_hurdsig_fault_sigcode >= (long int) scp && + _hurdsig_fault_sigcode < (long int) (scp + 1)); + /* We got a fault trying to write the stack frame. + We cannot set up the signal handler. + Returning NULL tells our caller, who will nuke us with a SIGILL. */ + return NULL; + } + else { /* Set up the sigcontext from the current state of the thread. */ @@ -125,11 +138,6 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, sizeof (state->fpu))) return NULL; } - else - /* We got a fault trying to write the stack frame. - We cannot set up the signal handler. - Returning NULL tells our caller, who will nuke us with a SIGILL. */ - return NULL; /* Modify the thread state to call the trampoline code on the new stack. */ if (rpc_wait) @@ -177,9 +185,12 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, /* We pass the handler function to the trampoline code in ra ($26). */ state->basic.r26 = (long int) handler; - /* In the callee-saved register t12 ($27), we save the SCP value to pass + /* In the callee-saved register t12/pv ($27), we store the + address of __sigreturn itself, for the trampoline code to use. */ + state->basic.r27 = (long int) &__sigreturn; + /* In the callee-saved register t11/ai ($25), we save the SCP value to pass to __sigreturn after the handler returns. */ - state->basic.r27 = (long int) scp; + state->basic.r25 = (long int) scp; return scp; @@ -223,15 +234,14 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, clobbered by running the handler). We use this saved value to pass to __sigreturn, so the handler can clobber the argument registers if it likes. */ - asm volatile - (/* Call the handler function, saving return address in ra ($26). */ - "jsr $26, $26\n" - /* Reset gp ($29) from the return address (here) in ra ($26). - This may be required to locate __sigreturn. */ - "ldgp $29, 0($26)\n" - /* Call __sigreturn (SCP); this cannot return. */ - "mov $27, $16\n" /* Move saved SCP to argument register. */ - "jmp $31, %0" : : "i" (&__sigreturn)); +#define A(line) asm volatile (#line) + /* Call the handler function, saving return address in ra ($26). */ + A (jsr $26, $26); + /* Reset gp ($29) from the return address (here) in ra ($26). */ + A (ldgp $29, 0($26)); + A (mov $25, $16); /* Move saved SCP to argument register. */ + /* Call __sigreturn (SCP); this cannot return. */ + A (jmp $31, $27); /* NOTREACHED */ return NULL; @@ -246,21 +256,30 @@ int _hurdsig_rcv_interrupted_p (struct machine_thread_all_state *state, mach_port_t *port) { - if (! setjmp (_hurd_sigthread_fault_env)) + if (state->basic.r0 == MACH_RCV_INTERRUPTED) { const unsigned int *pc = (void *) state->basic.pc; - if (state->basic.r0 == MACH_RCV_INTERRUPTED && - pc[-1] == ((alpha_instruction) { pal_format: - { opcode: op_pal, - function: op_chmk } }).bits) - { - /* We did just return from a mach_msg_trap system call - doing a message receive that was interrupted. - Examine the parameters to find the receive right. */ - struct mach_msg_trap_args *args = (void *) &state->basic.r16; + struct mach_msg_trap_args *args = (void *) &state->basic.r16; - *port = args->rcv_name; - return 1; + if (_hurdsig_catch_fault (SIGSEGV)) + { + assert (_hurdsig_fault_sigcode == (long int) (pc - 1) || + _hurdsig_fault_sigcode == (long int) &args->rcv_name); + /* We got a fault trying to read the PC or stack. */ + return 0; + } + else + { + if (pc[-1] == ((alpha_instruction) { pal_format: + { opcode: op_pal, + function: op_chmk } }).bits) + { + /* We did just return from a mach_msg_trap system call + doing a message receive that was interrupted. + Examine the parameters to find the receive right. */ + *port = args->rcv_name; + return 1; + } } }