Implement siginfo for sh3.
This commit is contained in:
parent
0e57233a47
commit
9d0d2c7461
@ -1,11 +1,11 @@
|
|||||||
# $NetBSD: Makefile.inc,v 1.3 2002/07/10 04:29:08 thorpej Exp $
|
# $NetBSD: Makefile.inc,v 1.4 2003/11/23 23:13:11 uwe Exp $
|
||||||
|
|
||||||
KMINCLUDES= arch/sh3/SYS.h
|
KMINCLUDES= arch/sh3/SYS.h
|
||||||
CPPFLAGS+= -DSOFTFLOAT
|
CPPFLAGS+= -DSOFTFLOAT # -DSOFTFLOAT_NEED_FIXUNS
|
||||||
|
|
||||||
.include <softfloat/Makefile.inc>
|
.include <softfloat/Makefile.inc>
|
||||||
|
|
||||||
#KMSRCS= bcmp.S bzero.S ffs.S strcat.S strcmp.S strcpy.S strlen.S \
|
#KMSRCS= bcmp.S bzero.S ffs.S strcat.S strcmp.S strcpy.S strlen.S \
|
||||||
# htonl.S htons.S ntohl.S ntohs.S
|
# htonl.S htons.S ntohl.S ntohs.S
|
||||||
|
|
||||||
SRCS+= __sigaction14_sigtramp.c __sigtramp1.S
|
SRCS+= __sigaction14_sigtramp.c __sigtramp1.S __sigtramp2.S
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* $NetBSD: __sigaction14_sigtramp.c,v 1.2 2003/01/18 11:14:02 thorpej Exp $ */
|
/* $NetBSD: __sigaction14_sigtramp.c,v 1.3 2003/11/23 23:13:11 uwe Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This code is derived from software contributed to The NetBSD Foundation
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "extern.h"
|
#include "extern.h"
|
||||||
|
|
||||||
@ -49,12 +50,24 @@ int
|
|||||||
__libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
|
__libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
|
||||||
{
|
{
|
||||||
extern int __sigtramp_sigcontext_1[];
|
extern int __sigtramp_sigcontext_1[];
|
||||||
|
extern int __sigtramp_siginfo_2[];
|
||||||
|
int rv;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Right here we should select the SA_SIGINFO trampoline
|
* We select the compatibility SIGCONTEXT trampoline if SA_SIGINFO
|
||||||
* if SA_SIGINFO is set in the sigaction.
|
* is not set in the sigaction.
|
||||||
*/
|
*/
|
||||||
|
if (act && (act->sa_flags & SA_SIGINFO) == 0) {
|
||||||
|
rv = __sigaction_sigtramp(sig, act, oact,
|
||||||
|
__sigtramp_sigcontext_1, 1);
|
||||||
|
/*
|
||||||
|
* EINVAL might indicate that trampoline version 1 is
|
||||||
|
* not supported by the kernel; fall back on native
|
||||||
|
* SIGINFO trampoline.
|
||||||
|
*/
|
||||||
|
if (rv >= 0 || errno != EINVAL)
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
return (__sigaction_sigtramp(sig, act, oact,
|
return __sigaction_sigtramp(sig, act, oact, __sigtramp_siginfo_2, 2);
|
||||||
__sigtramp_sigcontext_1, 1));
|
|
||||||
}
|
}
|
||||||
|
59
lib/libc/arch/sh3/sys/__sigtramp2.S
Normal file
59
lib/libc/arch/sh3/sys/__sigtramp2.S
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/* $NetBSD: __sigtramp2.S,v 1.1 2003/11/23 23:13:11 uwe Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the NetBSD
|
||||||
|
* Foundation, Inc. and its contributors.
|
||||||
|
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SYS.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The SH signal trampoline is invoked only to return from
|
||||||
|
* the signal; the kernel calls the signal handler directly.
|
||||||
|
*
|
||||||
|
* On entry, stack looks like:
|
||||||
|
*
|
||||||
|
* siginfo structure
|
||||||
|
* sp-> ucontext structure
|
||||||
|
*
|
||||||
|
* NB: This order is different from what other ports use (siginfo at
|
||||||
|
* the top of the stack), because we want to avoid wasting two
|
||||||
|
* instructions to skip to the ucontext. Not that this order really
|
||||||
|
* matters, but I think this inconsistency deserves an explanation.
|
||||||
|
*/
|
||||||
|
NENTRY(__sigtramp_siginfo_2)
|
||||||
|
mov r15, r4 /* get pointer to ucontext */
|
||||||
|
SYSTRAP(setcontext) /* and call setcontext() */
|
||||||
|
mov r0, r4 /* exit with errno */
|
||||||
|
SYSTRAP(exit) /* if sigreturn fails */
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: frame.h,v 1.11 2003/08/07 16:29:28 agc Exp $ */
|
/* $NetBSD: frame.h,v 1.12 2003/11/23 23:13:11 uwe Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1990 The Regents of the University of California.
|
* Copyright (c) 1990 The Regents of the University of California.
|
||||||
@ -128,12 +128,38 @@ struct switchframe {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Signal frame
|
* Signal frame.
|
||||||
|
*
|
||||||
|
* NB: The order of sf_uc and sf_si is different from what other ports
|
||||||
|
* use (siginfo at the top of the stack), because we want to avoid
|
||||||
|
* wasting two instructions in __sigtramp_siginfo_2 to skip to the
|
||||||
|
* ucontext. Not that this order really matters, but I think this
|
||||||
|
* inconsistency deserves an explanation.
|
||||||
*/
|
*/
|
||||||
struct sigframe {
|
struct sigframe_siginfo {
|
||||||
struct sigcontext sf_sc;
|
#if 0 /* in registers on entry to signal trampoline */
|
||||||
|
int sf_signum; /* r4 - "signum" argument for handler */
|
||||||
|
siginfo_t *sf_sip; /* r5 - "sip" argument for handler */
|
||||||
|
ucontext_t *sf_ucp; /* r6 - "ucp" argument for handler */
|
||||||
|
#endif
|
||||||
|
ucontext_t sf_uc; /* actual saved ucontext */
|
||||||
|
siginfo_t sf_si; /* actual saved siginfo */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(COMPAT_16) && defined(_KERNEL)
|
||||||
|
/*
|
||||||
|
* Old signal frame format.
|
||||||
|
*/
|
||||||
|
struct sigframe_sigcontext {
|
||||||
|
#if 0 /* in registers on entry to signal trampoline */
|
||||||
|
int sf_signum; /* r4 - "signum" argument for handler */
|
||||||
|
int sf_code; /* r5 - "code" argument for handler */
|
||||||
|
struct sigcontext *sf_scp; /* r6 - "scp" argument for handler */
|
||||||
|
#endif
|
||||||
|
struct sigcontext sf_sc; /* actual saved context */
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scheduler activations upcall frame
|
* Scheduler activations upcall frame
|
||||||
*/
|
*/
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: signal.h,v 1.7 2003/08/07 16:29:29 agc Exp $ */
|
/* $NetBSD: signal.h,v 1.8 2003/11/23 23:13:11 uwe Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
|
* Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
|
||||||
@ -38,6 +38,13 @@
|
|||||||
|
|
||||||
typedef int sig_atomic_t;
|
typedef int sig_atomic_t;
|
||||||
|
|
||||||
|
#define __HAVE_SIGINFO
|
||||||
|
#ifdef COMPAT_16
|
||||||
|
#define SIGTRAMP_VALID(vers) ((unsigned)(vers) <= 2)
|
||||||
|
#else
|
||||||
|
#define SIGTRAMP_VALID(vers) ((vers) == 2)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_NETBSD_SOURCE)
|
#if defined(_NETBSD_SOURCE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: exception.c,v 1.15 2003/10/31 03:28:13 simonb Exp $ */
|
/* $NetBSD: exception.c,v 1.16 2003/11/23 23:13:11 uwe Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1990 The Regents of the University of California.
|
* Copyright (c) 1990 The Regents of the University of California.
|
||||||
@ -79,7 +79,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: exception.c,v 1.15 2003/10/31 03:28:13 simonb Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: exception.c,v 1.16 2003/11/23 23:13:11 uwe Exp $");
|
||||||
|
|
||||||
#include "opt_ddb.h"
|
#include "opt_ddb.h"
|
||||||
#include "opt_kgdb.h"
|
#include "opt_kgdb.h"
|
||||||
@ -153,6 +153,7 @@ general_exception(struct lwp *l, struct trapframe *tf)
|
|||||||
{
|
{
|
||||||
int expevt = tf->tf_expevt;
|
int expevt = tf->tf_expevt;
|
||||||
boolean_t usermode = !KERNELMODE(tf->tf_ssr);
|
boolean_t usermode = !KERNELMODE(tf->tf_ssr);
|
||||||
|
ksiginfo_t ksi;
|
||||||
|
|
||||||
uvmexp.traps++;
|
uvmexp.traps++;
|
||||||
|
|
||||||
@ -169,12 +170,17 @@ general_exception(struct lwp *l, struct trapframe *tf)
|
|||||||
/* Check for debugger break */
|
/* Check for debugger break */
|
||||||
if (_reg_read_4(SH_(TRA)) == (_SH_TRA_BREAK << 2)) {
|
if (_reg_read_4(SH_(TRA)) == (_SH_TRA_BREAK << 2)) {
|
||||||
tf->tf_spc -= 2; /* back to the breakpoint address */
|
tf->tf_spc -= 2; /* back to the breakpoint address */
|
||||||
trapsignal(l, SIGTRAP, tf->tf_expevt);
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
ksi.ksi_signo = SIGTRAP;
|
||||||
|
ksi.ksi_code = TRAP_BRKPT;
|
||||||
|
ksi.ksi_addr = (void *)tf->tf_spc;
|
||||||
|
goto trapsignal;
|
||||||
} else {
|
} else {
|
||||||
syscall(l, tf);
|
syscall(l, tf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXPEVT_ADDR_ERR_LD:
|
case EXPEVT_ADDR_ERR_LD:
|
||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
case EXPEVT_ADDR_ERR_ST:
|
case EXPEVT_ADDR_ERR_ST:
|
||||||
@ -187,18 +193,29 @@ general_exception(struct lwp *l, struct trapframe *tf)
|
|||||||
case EXPEVT_ADDR_ERR_LD | EXP_USER:
|
case EXPEVT_ADDR_ERR_LD | EXP_USER:
|
||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
case EXPEVT_ADDR_ERR_ST | EXP_USER:
|
case EXPEVT_ADDR_ERR_ST | EXP_USER:
|
||||||
trapsignal(l, SIGSEGV, tf->tf_expevt);
|
KSI_INIT_TRAP(&ksi);
|
||||||
break;
|
/* XXX: for kernel access attempt this should be a SIGSEGV */
|
||||||
|
ksi.ksi_signo = SIGBUS;
|
||||||
|
ksi.ksi_code = BUS_ADRALN;
|
||||||
|
ksi.ksi_addr = (void *)tf->tf_spc; /* XXX: use TEA */
|
||||||
|
goto trapsignal;
|
||||||
|
|
||||||
case EXPEVT_RES_INST | EXP_USER:
|
case EXPEVT_RES_INST | EXP_USER:
|
||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
case EXPEVT_SLOT_INST | EXP_USER:
|
case EXPEVT_SLOT_INST | EXP_USER:
|
||||||
trapsignal(l, SIGILL, tf->tf_expevt);
|
KSI_INIT_TRAP(&ksi);
|
||||||
break;
|
ksi.ksi_signo = SIGILL;
|
||||||
|
ksi.ksi_code = ILL_ILLOPC; /* XXX: could be ILL_PRVOPC */
|
||||||
|
ksi.ksi_addr = (void *)tf->tf_spc;
|
||||||
|
goto trapsignal;
|
||||||
|
|
||||||
case EXPEVT_BREAK | EXP_USER:
|
case EXPEVT_BREAK | EXP_USER:
|
||||||
trapsignal(l, SIGTRAP, tf->tf_expevt);
|
KSI_INIT_TRAP(&ksi);
|
||||||
break;
|
ksi.ksi_signo = SIGTRAP;
|
||||||
|
ksi.ksi_code = TRAP_BRKPT; /* XXX: ??? */
|
||||||
|
ksi.ksi_addr = (void *)tf->tf_spc;
|
||||||
|
goto trapsignal;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
goto do_panic;
|
goto do_panic;
|
||||||
}
|
}
|
||||||
@ -207,6 +224,14 @@ general_exception(struct lwp *l, struct trapframe *tf)
|
|||||||
userret(l);
|
userret(l);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
trapsignal:
|
||||||
|
ksi.ksi_trap = tf->tf_expevt;
|
||||||
|
KERNEL_PROC_LOCK(l);
|
||||||
|
trapsignal(l, &ksi);
|
||||||
|
KERNEL_PROC_UNLOCK(l);
|
||||||
|
userret(l);
|
||||||
|
return;
|
||||||
|
|
||||||
do_panic:
|
do_panic:
|
||||||
#ifdef DDB
|
#ifdef DDB
|
||||||
if (kdb_trap(expevt, 0, tf))
|
if (kdb_trap(expevt, 0, tf))
|
||||||
@ -387,6 +412,7 @@ do { \
|
|||||||
} while(/*CONSTCOND*/0)
|
} while(/*CONSTCOND*/0)
|
||||||
struct vm_map *map;
|
struct vm_map *map;
|
||||||
pmap_t pmap;
|
pmap_t pmap;
|
||||||
|
ksiginfo_t ksi;
|
||||||
boolean_t usermode;
|
boolean_t usermode;
|
||||||
int err, track, ftype;
|
int err, track, ftype;
|
||||||
char *panic_msg;
|
char *panic_msg;
|
||||||
@ -417,7 +443,10 @@ do { \
|
|||||||
TLB_ASSERT((int)va > 0,
|
TLB_ASSERT((int)va > 0,
|
||||||
"kernel virtual protection fault (load)");
|
"kernel virtual protection fault (load)");
|
||||||
if (usermode) {
|
if (usermode) {
|
||||||
trapsignal(l, SIGSEGV, tf->tf_expevt);
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
ksi.ksi_signo = SIGSEGV;
|
||||||
|
ksi.ksi_code = SEGV_MAPERR;
|
||||||
|
ksi.ksi_addr = (void *)va;
|
||||||
goto user_fault;
|
goto user_fault;
|
||||||
} else {
|
} else {
|
||||||
TLB_ASSERT(l && l->l_md.md_pcb->pcb_onfault != NULL,
|
TLB_ASSERT(l && l->l_md.md_pcb->pcb_onfault != NULL,
|
||||||
@ -509,7 +538,13 @@ do { \
|
|||||||
|
|
||||||
/* Page not found. */
|
/* Page not found. */
|
||||||
if (usermode) {
|
if (usermode) {
|
||||||
trapsignal(l, err == ENOMEM ? SIGKILL : SIGSEGV, tf->tf_expevt);
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
if (err == ENOMEM)
|
||||||
|
ksi.ksi_signo = SIGKILL;
|
||||||
|
else {
|
||||||
|
ksi.ksi_signo = SIGSEGV;
|
||||||
|
ksi.ksi_code = SEGV_MAPERR;
|
||||||
|
}
|
||||||
goto user_fault;
|
goto user_fault;
|
||||||
} else {
|
} else {
|
||||||
TLB_ASSERT(l->l_md.md_pcb->pcb_onfault,
|
TLB_ASSERT(l->l_md.md_pcb->pcb_onfault,
|
||||||
@ -519,6 +554,10 @@ do { \
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
user_fault:
|
user_fault:
|
||||||
|
ksi.ksi_trap = tf->tf_expevt
|
||||||
|
KERNEL_PROC_LOCK(l);
|
||||||
|
trapsignal(l, &ksi);
|
||||||
|
KERNEL_PROC_UNLOCK(l);
|
||||||
userret(l);
|
userret(l);
|
||||||
ast(l, tf);
|
ast(l, tf);
|
||||||
return;
|
return;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: sh3_machdep.c,v 1.52 2003/09/26 12:02:56 simonb Exp $ */
|
/* $NetBSD: sh3_machdep.c,v 1.53 2003/11/23 23:13:11 uwe Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1996, 1997, 1998, 2002 The NetBSD Foundation, Inc.
|
* Copyright (c) 1996, 1997, 1998, 2002 The NetBSD Foundation, Inc.
|
||||||
@ -72,7 +72,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: sh3_machdep.c,v 1.52 2003/09/26 12:02:56 simonb Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: sh3_machdep.c,v 1.53 2003/11/23 23:13:11 uwe Exp $");
|
||||||
|
|
||||||
#include "opt_kgdb.h"
|
#include "opt_kgdb.h"
|
||||||
#include "opt_memsize.h"
|
#include "opt_memsize.h"
|
||||||
@ -406,8 +406,28 @@ cpu_upcall(struct lwp *l, int type, int nevents, int ninterrupted, void *sas,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send an interrupt to process.
|
* Get the base address of the signal frame either on the lwp's stack
|
||||||
*
|
* or on the signal stack and set *onstack accordingly. Caller then
|
||||||
|
* just subtracts the size of appropriate struct sigframe_foo.
|
||||||
|
*/
|
||||||
|
static void *
|
||||||
|
getframe(struct lwp *l, int sig, int *onstack)
|
||||||
|
{
|
||||||
|
struct proc *p = l->l_proc;
|
||||||
|
struct sigaltstack *sigstk= &p->p_sigctx.ps_sigstk;
|
||||||
|
|
||||||
|
/* Do we need to jump onto the signal stack? */
|
||||||
|
*onstack = (sigstk->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0
|
||||||
|
&& (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
|
||||||
|
|
||||||
|
if (*onstack)
|
||||||
|
return ((char *)sigstk->ss_sp + sigstk->ss_size);
|
||||||
|
else
|
||||||
|
return ((void *)l->l_md.md_regs->tf_r15);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef COMPAT_16
|
||||||
|
/*
|
||||||
* Stack is set up to allow sigcode stored
|
* Stack is set up to allow sigcode stored
|
||||||
* in u. to call routine, followed by kcall
|
* in u. to call routine, followed by kcall
|
||||||
* to sigreturn routine below. After sigreturn
|
* to sigreturn routine below. After sigreturn
|
||||||
@ -415,31 +435,20 @@ cpu_upcall(struct lwp *l, int type, int nevents, int ninterrupted, void *sas,
|
|||||||
* frame pointer, it returns to the user
|
* frame pointer, it returns to the user
|
||||||
* specified pc, psl.
|
* specified pc, psl.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
sendsig(int sig, const sigset_t *mask, u_long code)
|
sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask)
|
||||||
{
|
{
|
||||||
struct lwp *l = curlwp;
|
struct lwp *l = curlwp;
|
||||||
struct proc *p = l->l_proc;
|
struct proc *p = l->l_proc;
|
||||||
struct sigacts *ps = p->p_sigacts;
|
struct sigacts *ps = p->p_sigacts;
|
||||||
struct trapframe *tf;
|
struct trapframe *tf = l->l_md.md_regs;
|
||||||
struct sigframe *fp, frame;
|
int sig = ksi->ksi_info._signo;
|
||||||
int onstack;
|
|
||||||
sig_t catcher = SIGACTION(p, sig).sa_handler;
|
sig_t catcher = SIGACTION(p, sig).sa_handler;
|
||||||
|
struct sigframe_sigcontext *fp, frame;
|
||||||
|
int onstack;
|
||||||
|
|
||||||
tf = l->l_md.md_regs;
|
fp = getframe(l, sig, &onstack);
|
||||||
|
--fp;
|
||||||
/* Do we need to jump onto the signal stack? */
|
|
||||||
onstack =
|
|
||||||
(p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
|
|
||||||
(SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
|
|
||||||
|
|
||||||
/* Allocate space for the signal handler context. */
|
|
||||||
if (onstack)
|
|
||||||
fp = (struct sigframe *)((caddr_t)p->p_sigctx.ps_sigstk.ss_sp +
|
|
||||||
p->p_sigctx.ps_sigstk.ss_size);
|
|
||||||
else
|
|
||||||
fp = (struct sigframe *)tf->tf_r15;
|
|
||||||
fp--;
|
|
||||||
|
|
||||||
/* Save register context. */
|
/* Save register context. */
|
||||||
frame.sf_sc.sc_ssr = tf->tf_ssr;
|
frame.sf_sc.sc_ssr = tf->tf_ssr;
|
||||||
@ -483,11 +492,9 @@ sendsig(int sig, const sigset_t *mask, u_long code)
|
|||||||
* directly, only returning via the trampoline.
|
* directly, only returning via the trampoline.
|
||||||
*/
|
*/
|
||||||
switch (ps->sa_sigdesc[sig].sd_vers) {
|
switch (ps->sa_sigdesc[sig].sd_vers) {
|
||||||
#if 1 /* COMPAT_16 */
|
|
||||||
case 0: /* legacy on-stack sigtramp */
|
case 0: /* legacy on-stack sigtramp */
|
||||||
tf->tf_pr = (int)p->p_sigctx.ps_sigcode;
|
tf->tf_pr = (int)p->p_sigctx.ps_sigcode;
|
||||||
break;
|
break;
|
||||||
#endif /* COMPAT_16 */
|
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
tf->tf_pr = (int)ps->sa_sigdesc[sig].sd_tramp;
|
tf->tf_pr = (int)ps->sa_sigdesc[sig].sd_tramp;
|
||||||
@ -495,20 +502,94 @@ sendsig(int sig, const sigset_t *mask, u_long code)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
/* Don't know what trampoline version; kill it. */
|
/* Don't know what trampoline version; kill it. */
|
||||||
|
printf("sendsig_sigcontext: bad version %d\n",
|
||||||
|
ps->sa_sigdesc[sig].sd_vers);
|
||||||
sigexit(l, SIGILL);
|
sigexit(l, SIGILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
tf->tf_r4 = sig;
|
tf->tf_r4 = sig;
|
||||||
tf->tf_r5 = code;
|
tf->tf_r5 = ksi->ksi_code;
|
||||||
tf->tf_r6 = (int)&fp->sf_sc;
|
tf->tf_r6 = (int)&fp->sf_sc;
|
||||||
tf->tf_spc = (int)catcher;
|
tf->tf_spc = (int)catcher;
|
||||||
tf->tf_r15 = (int)fp;
|
tf->tf_r15 = (int)fp;
|
||||||
|
|
||||||
/* Remember that we're now on the signal stack. */
|
/* Remember if we're now on the signal stack. */
|
||||||
|
if (onstack)
|
||||||
|
p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||||
|
}
|
||||||
|
#endif /* COMPAT_16 */
|
||||||
|
|
||||||
|
static void
|
||||||
|
sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
|
||||||
|
{
|
||||||
|
struct lwp *l = curlwp;
|
||||||
|
struct proc *p = l->l_proc;
|
||||||
|
struct sigacts *ps = p->p_sigacts;
|
||||||
|
struct trapframe *tf = l->l_md.md_regs;
|
||||||
|
int sig = ksi->ksi_signo;
|
||||||
|
sig_t catcher = SIGACTION(p, sig).sa_handler;
|
||||||
|
struct sigframe_siginfo *fp, frame;
|
||||||
|
int onstack;
|
||||||
|
|
||||||
|
switch (ps->sa_sigdesc[sig].sd_vers) {
|
||||||
|
case 0: /* handled by sendsig_sigcontext */
|
||||||
|
case 1: /* handled by sendsig_sigcontext */
|
||||||
|
default: /* unknown version */
|
||||||
|
printf("sendsig_siginfo: bad version %d\n",
|
||||||
|
ps->sa_sigdesc[sig].sd_vers);
|
||||||
|
sigexit(l, SIGILL);
|
||||||
|
case 2:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp = getframe(l, sig, &onstack);
|
||||||
|
--fp;
|
||||||
|
|
||||||
|
frame.sf_si._info = ksi->ksi_info;
|
||||||
|
frame.sf_uc.uc_link = NULL;
|
||||||
|
frame.sf_uc.uc_sigmask = *mask;
|
||||||
|
frame.sf_uc.uc_flags = _UC_SIGMASK;
|
||||||
|
frame.sf_uc.uc_flags |= (p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK)
|
||||||
|
? _UC_SETSTACK : _UC_CLRSTACK;
|
||||||
|
memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack));
|
||||||
|
cpu_getmcontext(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags);
|
||||||
|
|
||||||
|
if (copyout(&frame, fp, sizeof(frame)) != 0) {
|
||||||
|
/*
|
||||||
|
* Process has trashed its stack; give it an illegal
|
||||||
|
* instruction to halt it in its tracks.
|
||||||
|
*/
|
||||||
|
sigexit(l, SIGILL);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
tf->tf_r4 = sig; /* "signum" argument for handler */
|
||||||
|
tf->tf_r5 = (int)&fp->sf_si; /* "sip" argument for handler */
|
||||||
|
tf->tf_r6 = (int)&fp->sf_uc; /* "ucp" argument for handler */
|
||||||
|
tf->tf_spc = (int)catcher;
|
||||||
|
tf->tf_r15 = (int)fp;
|
||||||
|
tf->tf_pr = (int)ps->sa_sigdesc[sig].sd_tramp;
|
||||||
|
|
||||||
|
/* Remember if we're now on the signal stack. */
|
||||||
if (onstack)
|
if (onstack)
|
||||||
p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
|
p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send an interrupt to process.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
|
||||||
|
{
|
||||||
|
#ifdef COMPAT_16
|
||||||
|
if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2)
|
||||||
|
sendsig_sigcontext(ksi, mask);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
sendsig_siginfo(ksi, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef COMPAT_16
|
||||||
/*
|
/*
|
||||||
* System call to cleanup state after a signal
|
* System call to cleanup state after a signal
|
||||||
* has been taken. Reset signal mask and
|
* has been taken. Reset signal mask and
|
||||||
@ -520,9 +601,9 @@ sendsig(int sig, const sigset_t *mask, u_long code)
|
|||||||
* a machine fault.
|
* a machine fault.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
sys___sigreturn14(struct lwp *l, void *v, register_t *retval)
|
compat_16_sys___sigreturn14(struct lwp *l, void *v, register_t *retval)
|
||||||
{
|
{
|
||||||
struct sys___sigreturn14_args /* {
|
struct compat_16_sys___sigreturn14_args /* {
|
||||||
syscallarg(struct sigcontext *) sigcntxp;
|
syscallarg(struct sigcontext *) sigcntxp;
|
||||||
} */ *uap = v;
|
} */ *uap = v;
|
||||||
struct sigcontext *scp, context;
|
struct sigcontext *scp, context;
|
||||||
@ -576,6 +657,7 @@ sys___sigreturn14(struct lwp *l, void *v, register_t *retval)
|
|||||||
|
|
||||||
return (EJUSTRETURN);
|
return (EJUSTRETURN);
|
||||||
}
|
}
|
||||||
|
#endif /* COMPAT_16 */
|
||||||
|
|
||||||
void
|
void
|
||||||
cpu_getmcontext(l, mcp, flags)
|
cpu_getmcontext(l, mcp, flags)
|
||||||
@ -660,6 +742,18 @@ cpu_setmcontext(l, mcp, flags)
|
|||||||
tf->tf_r15 = gr[_REG_R15];
|
tf->tf_r15 = gr[_REG_R15];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* XXX: FPU context is currently not handled by the kernel. */
|
||||||
|
if (flags & _UC_FPU) {
|
||||||
|
/* TODO */;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (flags & _UC_SETSTACK)
|
||||||
|
l->l_proc->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||||
|
if (flags & _UC_CLRSTACK)
|
||||||
|
l->l_proc->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user