Fill BADVADDR and CAUSE in sigcontext. We still don't restore them, but

it actually fixes a problem:
When /bin/sh gets a SIGSEGV, its signal handler calls brk and the offending
instruction is retried. Usually it gets another SIGSEGV, and things loops
until it pases without the SIGSEGV. This is the normal mode of operation, and
it can be reproduced on IRIX by a 10kB shell script starting by echo /*

However... the signal handler checks for BADVADDR in the saved registers
in struct sigcontext. If it does not find it, it gives up and exit instead
of retrying. Filling the field enables us to carry on normal operation
(which is to get dozens of SIGSEGV) instead of getting a failure at the
first SIGSEGV.
This commit is contained in:
manu 2002-09-25 19:39:16 +00:00
parent da13a0afc7
commit deca50b66c

View File

@ -1,4 +1,4 @@
/* $NetBSD: irix_signal.c,v 1.21 2002/09/25 19:09:50 manu Exp $ */
/* $NetBSD: irix_signal.c,v 1.22 2002/09/25 19:39:16 manu Exp $ */
/*-
* Copyright (c) 1994, 2001-2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: irix_signal.c,v 1.21 2002/09/25 19:09:50 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: irix_signal.c,v 1.22 2002/09/25 19:39:16 manu Exp $");
#include <sys/types.h>
#include <sys/signal.h>
@ -413,6 +413,8 @@ irix_set_sigcontext (scp, mask, code, p)
scp->isc_mdhi = f->f_regs[MULHI];
scp->isc_mdlo = f->f_regs[MULLO];
scp->isc_pc = f->f_regs[PC];
scp->isc_badvaddr = f->f_regs[BADVADDR];
scp->isc_cause = f->f_regs[CAUSE];
/*
* Save the floating-pointstate, if necessary, then copy it.
@ -463,6 +465,7 @@ irix_set_ucontext(ucp, mask, code, p)
ucp->iuc_mcontext.svr4___gregs[IRIX_CTX_MDLO] = f->f_regs[MULLO];
ucp->iuc_mcontext.svr4___gregs[IRIX_CTX_MDHI] = f->f_regs[MULHI];
ucp->iuc_mcontext.svr4___gregs[IRIX_CTX_EPC] = f->f_regs[PC];
ucp->iuc_mcontext.svr4___gregs[IRIX_CTX_CAUSE] = f->f_regs[CAUSE];
/*
* Save the floating-pointstate, if necessary, then copy it.