summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2000-11-23 08:55:30 +0000
committermarcel <marcel@FreeBSD.org>2000-11-23 08:55:30 +0000
commitcde8d159637481ca81846c9518f53cd29dc16c16 (patch)
tree447c84b8e2199bb385d74f2dbe99427d9ba92890
parent0fd34587296e65de5fd6a027091f2e32636c2099 (diff)
downloadFreeBSD-src-cde8d159637481ca81846c9518f53cd29dc16c16.zip
FreeBSD-src-cde8d159637481ca81846c9518f53cd29dc16c16.tar.gz
o Change the argument of linux_sigreturn to be a pointer to a
struct sigframe. We need more than only the signal context. o Properly convert the signal mask when setting up the signal frame in linux_sendsig and properly convert it back in linux_sigreturn. Do some cleanups and improve style while here.
-rw-r--r--sys/i386/linux/linux.h19
-rw-r--r--sys/i386/linux/linux_locore.s10
-rw-r--r--sys/i386/linux/linux_proto.h4
-rw-r--r--sys/i386/linux/linux_syscall.h2
-rw-r--r--sys/i386/linux/linux_sysent.c2
-rw-r--r--sys/i386/linux/linux_sysvec.c112
6 files changed, 72 insertions, 77 deletions
diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h
index 6d3e5a8..d253897 100644
--- a/sys/i386/linux/linux.h
+++ b/sys/i386/linux/linux.h
@@ -335,23 +335,22 @@ struct linux_fpstate {
* It is appended to the frame to not interfere with the rest of it.
*/
struct linux_sigframe {
- int sf_sig;
- struct linux_sigcontext sf_sc;
- struct linux_fpstate fpstate;
- u_int extramask[LINUX_NSIG_WORDS-1];
- linux_handler_t sf_handler;
+ int sf_sig;
+ struct linux_sigcontext sf_sc;
+ struct linux_fpstate sf_fpstate;
+ u_int sf_extramask[LINUX_NSIG_WORDS-1];
+ linux_handler_t sf_handler;
};
struct linux_rt_sigframe {
int sf_sig;
- linux_siginfo_t *sf_siginfo;;
- struct linux_ucontext *sf_ucontext;
- linux_siginfo_t sf_si;
- struct linux_ucontext sf_sc;
+ linux_siginfo_t *sf_siginfo;
+ struct linux_ucontext *sf_ucontext;
+ linux_siginfo_t sf_si;
+ struct linux_ucontext sf_sc;
linux_handler_t sf_handler;
};
-
extern int bsd_to_linux_signal[];
extern int linux_to_bsd_signal[];
extern struct sysentvec linux_sysvec;
diff --git a/sys/i386/linux/linux_locore.s b/sys/i386/linux/linux_locore.s
index 074021e..f3d93f4 100644
--- a/sys/i386/linux/linux_locore.s
+++ b/sys/i386/linux/linux_locore.s
@@ -9,23 +9,23 @@ NON_GPROF_ENTRY(linux_sigcode)
call *LINUX_SIGF_HANDLER(%esp)
leal LINUX_SIGF_SC(%esp),%ebx /* linux scp */
movl LINUX_SC_GS(%ebx),%gs
+ movl %esp, %ebx /* pass sigframe */
push %eax /* fake ret addr */
movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */
int $0x80 /* enter kernel with args */
0: jmp 0b
ALIGN_TEXT
/* XXXXX */
-
_linux_rt_sigcode:
call *LINUX_RT_SIGF_HANDLER(%esp)
leal LINUX_RT_SIGF_UC(%esp),%ebx /* linux ucp */
movl LINUX_SC_GS(%ebx),%gs
push %eax /* fake ret addr */
- movl $LINUX_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */
+ movl $LINUX_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */
int $0x80 /* enter kernel with args */
0: jmp 0b
ALIGN_TEXT
-/* XXXXX */
+/* XXXXX */
_linux_esigcode:
.data
@@ -34,7 +34,3 @@ _linux_szsigcode:
.long _linux_esigcode-_linux_sigcode
_linux_sznonrtsigcode:
.long _linux_rt_sigcode-_linux_sigcode
- .text
-
-
-
diff --git a/sys/i386/linux/linux_proto.h b/sys/i386/linux/linux_proto.h
index 6540a52..2a61ac5 100644
--- a/sys/i386/linux/linux_proto.h
+++ b/sys/i386/linux/linux_proto.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.36 2000/11/09 07:27:55 marcel Exp
+ * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.38 2000/11/23 08:53:19 marcel Exp
*/
#ifndef _LINUX_SYSPROTO_H_
@@ -322,7 +322,7 @@ struct linux_ipc_args {
caddr_t ptr; char ptr_[PAD_(caddr_t)];
};
struct linux_sigreturn_args {
- struct linux_sigcontext * scp; char scp_[PAD_(struct linux_sigcontext *)];
+ struct linux_sigframe * sfp; char sfp_[PAD_(struct linux_sigframe *)];
};
struct linux_clone_args {
int flags; char flags_[PAD_(int)];
diff --git a/sys/i386/linux/linux_syscall.h b/sys/i386/linux/linux_syscall.h
index 4d99a07..645438c 100644
--- a/sys/i386/linux/linux_syscall.h
+++ b/sys/i386/linux/linux_syscall.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.36 2000/11/09 07:27:55 marcel Exp
+ * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.38 2000/11/23 08:53:19 marcel Exp
*/
#define LINUX_SYS_linux_setup 0
diff --git a/sys/i386/linux/linux_sysent.c b/sys/i386/linux/linux_sysent.c
index 29c8626..c0dbc729 100644
--- a/sys/i386/linux/linux_sysent.c
+++ b/sys/i386/linux/linux_sysent.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.36 2000/11/09 07:27:55 marcel Exp
+ * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.38 2000/11/23 08:53:19 marcel Exp
*/
#include "opt_compat.h"
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index e836d02..9925292 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -202,7 +202,6 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
register struct proc *p = curproc;
register struct trapframe *regs;
struct linux_rt_sigframe *fp, frame;
- struct sigacts *psp = p->p_sigacts;
int oonstack;
regs = p->p_md.md_regs;
@@ -216,7 +215,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
* Allocate space for the signal handler context.
*/
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
- SIGISMEMBER(psp->ps_sigonstack, sig)) {
+ SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) {
fp = (struct linux_rt_sigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct linux_rt_sigframe));
p->p_sigstk.ss_flags |= SS_ONSTACK;
@@ -257,17 +256,28 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame.sf_handler = catcher;
frame.sf_sig = sig;
-
frame.sf_siginfo = &fp->sf_si;
frame.sf_ucontext = &fp->sf_sc;
+
/* Fill siginfo structure. */
frame.sf_si.lsi_signo = sig;
frame.sf_si.lsi_code = code;
frame.sf_si.lsi_addr = (void *)regs->tf_err;
+
/*
* Build the signal context to be used by sigreturn.
*/
- frame.sf_sc.uc_mcontext.sc_mask = mask->__bits[0];
+ frame.sf_sc.uc_flags = 0; /* XXX ??? */
+ frame.sf_sc.uc_link = NULL; /* XXX ??? */
+
+ frame.sf_sc.uc_stack.ss_sp = p->p_sigstk.ss_sp;
+ frame.sf_sc.uc_stack.ss_flags =
+ bsd_to_linux_sigaltstack(p->p_sigstk.ss_flags);
+ frame.sf_sc.uc_stack.ss_size = p->p_sigstk.ss_size;
+
+ bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
+
+ frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__bits[0];
frame.sf_sc.uc_mcontext.sc_gs = rgs();
frame.sf_sc.uc_mcontext.sc_fs = regs->tf_fs;
frame.sf_sc.uc_mcontext.sc_es = regs->tf_es;
@@ -287,21 +297,11 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame.sf_sc.uc_mcontext.sc_err = regs->tf_err;
frame.sf_sc.uc_mcontext.sc_trapno = code; /* XXX ???? */
- /*
- * Build the remainder of the ucontext struct to be used by sigreturn.
- */
- frame.sf_sc.uc_flags = 0; /* XXX ??? */
- frame.sf_sc.uc_link = NULL; /* XXX ??? */
- frame.sf_sc.uc_stack.ss_sp = p->p_sigstk.ss_sp;
- frame.sf_sc.uc_stack.ss_flags =
- bsd_to_linux_sigaltstack(p->p_sigstk.ss_flags);
- frame.sf_sc.uc_stack.ss_size = p->p_sigstk.ss_size;
#ifdef DEBUG
printf("Linux-emul(%ld): rt_sendsig flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x\n",
(long)p->p_pid, frame.sf_sc.uc_stack.ss_flags, p->p_sigstk.ss_sp,
p->p_sigstk.ss_size, frame.sf_sc.uc_mcontext.sc_mask);
#endif
- bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
if (copyout(&frame, fp, sizeof(frame)) != 0) {
/*
@@ -345,9 +345,15 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
register struct proc *p = curproc;
register struct trapframe *regs;
struct linux_sigframe *fp, frame;
- struct sigacts *psp = p->p_sigacts;
+ linux_sigset_t lmask;
int oonstack, i;
+ if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
+ /* Signal handler installed with SA_SIGINFO. */
+ linux_rt_sendsig(catcher, sig, mask, code);
+ return;
+ }
+
regs = p->p_md.md_regs;
oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
@@ -356,17 +362,11 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
(long)p->p_pid, catcher, sig, (void*)mask, code);
#endif
- if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
- /* Signal handler installed with SA_SIGINFO. */
- linux_rt_sendsig(catcher, sig, mask, code);
- return;
- }
-
/*
* Allocate space for the signal handler context.
*/
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
- SIGISMEMBER(psp->ps_sigonstack, sig)) {
+ SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) {
fp = (struct linux_sigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct linux_sigframe));
p->p_sigstk.ss_flags |= SS_ONSTACK;
@@ -404,10 +404,12 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame.sf_handler = catcher;
frame.sf_sig = sig;
+ bsd_to_linux_sigset(mask, &lmask);
+
/*
* Build the signal context to be used by sigreturn.
*/
- frame.sf_sc.sc_mask = mask->__bits[0];
+ frame.sf_sc.sc_mask = lmask.__bits[0];
frame.sf_sc.sc_gs = rgs();
frame.sf_sc.sc_fs = regs->tf_fs;
frame.sf_sc.sc_es = regs->tf_es;
@@ -426,10 +428,12 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame.sf_sc.sc_ss = regs->tf_ss;
frame.sf_sc.sc_err = regs->tf_err;
frame.sf_sc.sc_trapno = code; /* XXX ???? */
- bzero(&frame.fpstate, sizeof(struct linux_fpstate));
+
+ bzero(&frame.sf_fpstate, sizeof(struct linux_fpstate));
+
for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
- frame.extramask[i] = mask->__bits[i+1];
-
+ frame.sf_extramask[i] = lmask.__bits[i+1];
+
if (copyout(&frame, fp, sizeof(frame)) != 0) {
/*
* Process has trashed its stack; give it an illegal
@@ -468,10 +472,9 @@ linux_sigreturn(p, args)
struct proc *p;
struct linux_sigreturn_args *args;
{
- struct linux_sigcontext context;
+ struct linux_sigframe frame;
register struct trapframe *regs;
- u_int extramask[LINUX_NSIG_WORDS-1];
- u_int *emp;
+ linux_sigset_t lmask;
int eflags, i;
regs = p->p_md.md_regs;
@@ -481,18 +484,18 @@ linux_sigreturn(p, args)
(long)p->p_pid, (void *)args->scp);
#endif
/*
- * The trampoline code hands us the context.
+ * The trampoline code hands us the sigframe.
* It is unsafe to keep track of it ourselves, in the event that a
* program jumps out of a signal handler.
*/
- if (copyin((caddr_t)args->scp, &context, sizeof(context)) != 0)
+ if (copyin((caddr_t)args->sfp, &frame, sizeof(frame)) != 0)
return (EFAULT);
/*
* Check for security violations.
*/
#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
- eflags = context.sc_eflags;
+ eflags = frame.sf_sc.sc_eflags;
/*
* XXX do allow users to change the privileged flag PSL_RF. The
* cpu sets PSL_RF in tf_eflags for faults. Debuggers should
@@ -513,40 +516,37 @@ linux_sigreturn(p, args)
* other selectors, invalid %eip's and invalid %esp's.
*/
#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
- if (!CS_SECURE(context.sc_cs)) {
+ if (!CS_SECURE(frame.sf_sc.sc_cs)) {
trapsignal(p, SIGBUS, T_PROTFLT);
return(EINVAL);
}
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
- emp = (u_int *)((caddr_t)args->scp + sizeof(context) +
- sizeof(struct linux_fpstate));
- if (copyin((caddr_t)emp, extramask, sizeof(extramask)) == 0)
- for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
- p->p_sigmask.__bits[i+1] = extramask[i];
-
- SIGSETOLD(p->p_sigmask, context.sc_mask);
+ lmask.__bits[0] = frame.sf_sc.sc_mask;
+ for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
+ lmask.__bits[i+1] = frame.sf_extramask[i];
+ linux_to_bsd_sigset(&lmask, &p->p_sigmask);
SIG_CANTMASK(p->p_sigmask);
/*
* Restore signal context.
*/
/* %gs was restored by the trampoline. */
- regs->tf_fs = context.sc_fs;
- regs->tf_es = context.sc_es;
- regs->tf_ds = context.sc_ds;
- regs->tf_edi = context.sc_edi;
- regs->tf_esi = context.sc_esi;
- regs->tf_ebp = context.sc_ebp;
- regs->tf_ebx = context.sc_ebx;
- regs->tf_edx = context.sc_edx;
- regs->tf_ecx = context.sc_ecx;
- regs->tf_eax = context.sc_eax;
- regs->tf_eip = context.sc_eip;
- regs->tf_cs = context.sc_cs;
+ regs->tf_fs = frame.sf_sc.sc_fs;
+ regs->tf_es = frame.sf_sc.sc_es;
+ regs->tf_ds = frame.sf_sc.sc_ds;
+ regs->tf_edi = frame.sf_sc.sc_edi;
+ regs->tf_esi = frame.sf_sc.sc_esi;
+ regs->tf_ebp = frame.sf_sc.sc_ebp;
+ regs->tf_ebx = frame.sf_sc.sc_ebx;
+ regs->tf_edx = frame.sf_sc.sc_edx;
+ regs->tf_ecx = frame.sf_sc.sc_ecx;
+ regs->tf_eax = frame.sf_sc.sc_eax;
+ regs->tf_eip = frame.sf_sc.sc_eip;
+ regs->tf_cs = frame.sf_sc.sc_cs;
regs->tf_eflags = eflags;
- regs->tf_esp = context.sc_esp_at_signal;
- regs->tf_ss = context.sc_ss;
+ regs->tf_esp = frame.sf_sc.sc_esp_at_signal;
+ regs->tf_ss = frame.sf_sc.sc_ss;
return (EJUSTRETURN);
}
@@ -582,7 +582,7 @@ linux_rt_sigreturn(p, args)
(long)p->p_pid, (void *)args->ucp);
#endif
/*
- * The trampoline code hands us the u_context.
+ * The trampoline code hands us the ucontext.
* It is unsafe to keep track of it ourselves, in the event that a
* program jumps out of a signal handler.
*/
@@ -626,7 +626,7 @@ linux_rt_sigreturn(p, args)
SIG_CANTMASK(p->p_sigmask);
/*
- * Restore signal context->
+ * Restore signal context
*/
/* %gs was restored by the trampoline. */
regs->tf_fs = context->sc_fs;
OpenPOWER on IntegriCloud