svn commit: r199402 - projects/ppc64/sys/powerpc/powerpc
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Tue Nov 17 16:17:44 UTC 2009
Author: nwhitehorn
Date: Tue Nov 17 16:17:44 2009
New Revision: 199402
URL: http://svn.freebsd.org/changeset/base/199402
Log:
Get signal delivery mostly working for 32-bit processes. Next there are
all the fun 'XXX big-endian' bits in compat/freebsd32.
Modified:
projects/ppc64/sys/powerpc/powerpc/exec_machdep.c
Modified: projects/ppc64/sys/powerpc/powerpc/exec_machdep.c
==============================================================================
--- projects/ppc64/sys/powerpc/powerpc/exec_machdep.c Tue Nov 17 16:17:39 2009 (r199401)
+++ projects/ppc64/sys/powerpc/powerpc/exec_machdep.c Tue Nov 17 16:17:44 2009 (r199402)
@@ -94,6 +94,22 @@ __FBSDID("$FreeBSD: projects/ppc64/sys/p
#include <compat/freebsd32/freebsd32_signal.h>
#include <compat/freebsd32/freebsd32_util.h>
#include <compat/freebsd32/freebsd32_proto.h>
+
+typedef struct __ucontext32 {
+ sigset_t uc_sigmask;
+ mcontext32_t uc_mcontext;
+ uint32_t uc_link;
+ struct sigaltstack32 uc_stack;
+ uint32_t uc_flags;
+ uint32_t __spare__[4];
+} ucontext32_t;
+
+struct sigframe32 {
+ ucontext32_t sf_uc;
+ struct siginfo32 sf_si;
+};
+
+static int grab_mcontext32(struct thread *td, mcontext32_t *, int flags);
#endif
static int grab_mcontext(struct thread *, mcontext_t *, int);
@@ -102,11 +118,16 @@ void
sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct trapframe *tf;
- struct sigframe *sfp;
struct sigacts *psp;
struct sigframe sf;
struct thread *td;
struct proc *p;
+ #ifdef COMPAT_FREEBSD32
+ struct siginfo32 siginfo32;
+ struct sigframe32 sf32;
+ #endif
+ size_t sfpsize;
+ caddr_t sfp, usfp;
int oonstack, rndfsize;
int sig;
int code;
@@ -114,8 +135,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi,
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
- sig = ksi->ksi_signo;
- code = ksi->ksi_code;
+
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
tf = td->td_frame;
@@ -123,30 +143,76 @@ sendsig(sig_t catcher, ksiginfo_t *ksi,
rndfsize = ((sizeof(sf) + 15) / 16) * 16;
- CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
- catcher, sig);
-
/*
- * Save user context
+ * Fill siginfo structure.
*/
- memset(&sf, 0, sizeof(sf));
- grab_mcontext(td, &sf.sf_uc.uc_mcontext, 0);
- sf.sf_uc.uc_sigmask = *mask;
- sf.sf_uc.uc_stack = td->td_sigstk;
- sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
- ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
+ ksi->ksi_info.si_signo = ksi->ksi_signo;
+ #ifdef AIM
+ ksi->ksi_info.si_addr = (void *)((tf->exc == EXC_DSI) ?
+ tf->cpu.aim.dar : tf->srr0);
+ #else
+ ksi->ksi_info.si_addr = (void *)((tf->exc == EXC_DSI) ?
+ tf->cpu.booke.dear : tf->srr0);
+ #endif
- sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
+ #ifdef COMPAT_FREEBSD32
+ if (p->p_sysent->sv_flags & SV_ILP32) {
+ siginfo_to_siginfo32(&ksi->ksi_info, &siginfo32);
+ sig = siginfo32.si_signo;
+ code = siginfo32.si_code;
+ sfp = (caddr_t)&sf32;
+ sfpsize = sizeof(sf32);
+
+ /*
+ * Save user context
+ */
+
+ memset(&sf32, 0, sizeof(sf32));
+ grab_mcontext32(td, &sf32.sf_uc.uc_mcontext, 0);
+
+ sf32.sf_uc.uc_sigmask = *mask;
+ sf32.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp;
+ sf32.sf_uc.uc_stack.ss_size = (uint32_t)td->td_sigstk.ss_size;
+ sf32.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
+ ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
+
+ sf32.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
+ } else {
+ #endif
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_code;
+ sfp = (caddr_t)&sf;
+ sfpsize = sizeof(sf);
+
+ /*
+ * Save user context
+ */
+
+ memset(&sf, 0, sizeof(sf));
+ grab_mcontext(td, &sf.sf_uc.uc_mcontext, 0);
+
+ sf.sf_uc.uc_sigmask = *mask;
+ sf.sf_uc.uc_stack = td->td_sigstk;
+ sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
+ ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
+
+ sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
+ #ifdef COMPAT_FREEBSD32
+ }
+ #endif
+
+ CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
+ catcher, sig);
/*
* Allocate and validate space for the signal handler context.
*/
if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
- sfp = (struct sigframe *)(td->td_sigstk.ss_sp +
+ usfp = (void *)(td->td_sigstk.ss_sp +
td->td_sigstk.ss_size - rndfsize);
} else {
- sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize);
+ usfp = (void *)(tf->fixreg[1] - rndfsize);
}
/*
@@ -171,26 +237,34 @@ sendsig(sig_t catcher, ksiginfo_t *ksi,
* srr0 - trampoline function addr
*/
tf->lr = (register_t)catcher;
- tf->fixreg[1] = (register_t)sfp;
+ tf->fixreg[1] = (register_t)usfp;
tf->fixreg[FIRSTARG] = sig;
- tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc;
+ #ifdef COMPAT_FREEBSD32
+ tf->fixreg[FIRSTARG+2] = (register_t)usfp +
+ (p->p_sysent->sv_flags & SV_ILP32) ?
+ offsetof(struct sigframe32, sf_uc) :
+ offsetof(struct sigframe, sf_uc);
+ #else
+ tf->fixreg[FIRSTARG+2] = (register_t)usfp +
+ offsetof(struct sigframe, sf_uc);
+ #endif
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
/*
* Signal handler installed with SA_SIGINFO.
*/
- tf->fixreg[FIRSTARG+1] = (register_t)&sfp->sf_si;
-
- /*
- * Fill siginfo structure.
- */
- sf.sf_si = ksi->ksi_info;
- sf.sf_si.si_signo = sig;
- #ifdef AIM
- sf.sf_si.si_addr = (void *)((tf->exc == EXC_DSI) ?
- tf->cpu.aim.dar : tf->srr0);
- #else
- sf.sf_si.si_addr = (void *)((tf->exc == EXC_DSI) ?
- tf->cpu.booke.dear : tf->srr0);
+ #ifdef COMPAT_FREEBSD32
+ if (p->p_sysent->sv_flags & SV_ILP32) {
+ sf32.sf_si = siginfo32;
+ tf->fixreg[FIRSTARG+1] = (register_t)usfp +
+ offsetof(struct sigframe32, sf_si);
+ sf32.sf_si = siginfo32;
+ } else {
+ #endif
+ tf->fixreg[FIRSTARG+1] = (register_t)usfp +
+ offsetof(struct sigframe, sf_si);
+ sf.sf_si = ksi->ksi_info;
+ #ifdef COMPAT_FREEBSD32
+ }
#endif
} else {
/* Old FreeBSD-style arguments. */
@@ -206,12 +280,20 @@ sendsig(sig_t catcher, ksiginfo_t *ksi,
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p);
- tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
+ #ifdef COMPAT_FREEBSD32
+ if (p->p_sysent->sv_flags & SV_ILP32)
+ tf->srr0 = (register_t)(FREEBSD32_PS_STRINGS -
+ *(p->p_sysent->sv_szsigcode));
+ else
+ #else
+ tf->srr0 = (register_t)(PS_STRINGS -
+ *(p->p_sysent->sv_szsigcode));
+ #endif
/*
* copy the frame out to userland.
*/
- if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
+ if (copyout(sfp, usfp, sfpsize) != 0) {
/*
* Process has trashed its stack. Kill it.
*/
@@ -601,12 +683,12 @@ fill_regs32(struct thread *td, struct re
}
static int
-get_mcontext32(struct thread *td, mcontext32_t *mcp, int flags)
+grab_mcontext32(struct thread *td, mcontext32_t *mcp, int flags)
{
mcontext_t mcp64;
int i, error;
- error = get_mcontext(td, &mcp64, flags);
+ error = grab_mcontext(td, &mcp64, flags);
if (error != 0)
return (error);
@@ -624,6 +706,21 @@ get_mcontext32(struct thread *td, mconte
}
static int
+get_mcontext32(struct thread *td, mcontext32_t *mcp, int flags)
+{
+ int error;
+
+ error = grab_mcontext32(td, mcp, flags);
+ if (error == 0) {
+ PROC_LOCK(curthread->td_proc);
+ mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]);
+ PROC_UNLOCK(curthread->td_proc);
+ }
+
+ return (error);
+}
+
+static int
set_mcontext32(struct thread *td, const mcontext32_t *mcp)
{
mcontext_t mcp64;
@@ -646,15 +743,6 @@ set_mcontext32(struct thread *td, const
#endif
#ifdef COMPAT_FREEBSD32
-typedef struct __ucontext32 {
- sigset_t uc_sigmask;
- mcontext32_t uc_mcontext;
- uint32_t uc_link;
- struct sigaltstack32 uc_stack;
- uint32_t uc_flags;
- uint32_t __spare__[4];
-} ucontext32_t;
-
int
freebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap)
{
More information about the svn-src-projects
mailing list