From ff376b0763a0300d7667137fd7cf1e29312c12fc Mon Sep 17 00:00:00 2001 From: fvdl Date: Mon, 13 Oct 2003 18:55:30 +0000 Subject: [PATCH] Implement 32bit get/setcontext entry points. --- sys/compat/netbsd32/netbsd32.h | 8 +- sys/compat/netbsd32/netbsd32_signal.c | 181 +++++++++++++++++++++++++- sys/compat/netbsd32/netbsd32_sysent.c | 30 +++-- 3 files changed, 207 insertions(+), 12 deletions(-) diff --git a/sys/compat/netbsd32/netbsd32.h b/sys/compat/netbsd32/netbsd32.h index 34be0c3dd975..07b57a4ecbb5 100644 --- a/sys/compat/netbsd32/netbsd32.h +++ b/sys/compat/netbsd32/netbsd32.h @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32.h,v 1.24 2003/01/18 08:28:25 thorpej Exp $ */ +/* $NetBSD: netbsd32.h,v 1.25 2003/10/13 18:55:30 fvdl Exp $ */ /* * Copyright (c) 1998, 2001 Matthew R. Green @@ -45,6 +45,7 @@ #include #include #include +#include /* * first, define the basic types we need. @@ -104,6 +105,8 @@ typedef netbsd32_pointer_t netbsd32_caddrp; typedef netbsd32_pointer_t netbsd32_caddr; typedef netbsd32_pointer_t netbsd32_gid_tp; typedef netbsd32_pointer_t netbsd32_fsid_tp_t; +typedef netbsd32_pointer_t netbsd32_lwpidp; +typedef netbsd32_pointer_t netbsd32_ucontextp; /* * now, the compatibility structures and their fake pointer types. @@ -523,6 +526,9 @@ typedef struct firm_event32 { struct netbsd32_timeval time; } Firm_event32; +void netbsd32_si_to_si32(siginfo32_t *, siginfo_t *); +void netbsd32_si32_to_si(siginfo_t *, siginfo32_t *); + /* * here are some macros to convert between netbsd32 and sparc64 types. * note that they do *NOT* act like good macros and put ()'s around all diff --git a/sys/compat/netbsd32/netbsd32_signal.c b/sys/compat/netbsd32/netbsd32_signal.c index bf6a7681669a..45f45e6a9ddb 100644 --- a/sys/compat/netbsd32/netbsd32_signal.c +++ b/sys/compat/netbsd32/netbsd32_signal.c @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_signal.c,v 1.6 2003/01/18 08:28:26 thorpej Exp $ */ +/* $NetBSD: netbsd32_signal.c,v 1.7 2003/10/13 18:55:30 fvdl Exp $ */ /* * Copyright (c) 1998, 2001 Matthew R. Green @@ -29,7 +29,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: netbsd32_signal.c,v 1.6 2003/01/18 08:28:26 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_signal.c,v 1.7 2003/10/13 18:55:30 fvdl Exp $"); #include #include @@ -39,6 +39,9 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_signal.c,v 1.6 2003/01/18 08:28:26 thorpej #include #include #include +#include + +#include #include #include @@ -213,3 +216,177 @@ netbsd32___sigaction_sigtramp(l, v, retval) } return (0); } + +void +netbsd32_si32_to_si(siginfo_t *si, siginfo32_t *si32) +{ + memset(si, 0, sizeof (*si)); + si->si_signo = si32->si_signo; + si->si_code = si32->si_code; + si->si_errno = si32->si_errno; + + switch (si32->si_signo) { + case SIGILL: + case SIGBUS: + case SIGSEGV: + case SIGFPE: + case SIGTRAP: + si->si_addr = (void *)NETBSD32PTR64(si32->si_addr); + si->si_trap = si32->si_trap; + break; + case SIGALRM: + case SIGVTALRM: + case SIGPROF: + si->si_pid = si32->si_pid; + si->si_uid = si32->si_uid; + /* + * XXX sival_ptr is currently unused. + */ + si->si_sigval.sival_int = si32->si_sigval.sival_int; + break; + case SIGCHLD: + si->si_pid = si32->si_pid; + si->si_uid = si32->si_uid; + si->si_utime = si32->si_utime; + si->si_stime = si32->si_stime; + break; + case SIGURG: + case SIGIO: + si->si_band = si32->si_band; + si->si_fd = si32->si_fd; + break; + } +} + +void +netbsd32_si_to_si32(siginfo32_t *si32, siginfo_t *si) +{ + memset(si32, 0, sizeof (*si32)); + si32->si_signo = si->si_signo; + si32->si_code = si->si_code; + si32->si_errno = si->si_errno; + + switch (si32->si_signo) { + case SIGILL: + case SIGBUS: + case SIGSEGV: + case SIGFPE: + case SIGTRAP: + si32->si_addr = (uint32_t)(uintptr_t)si->si_addr; + si32->si_trap = si->si_trap; + break; + case SIGALRM: + case SIGVTALRM: + case SIGPROF: + si32->si_pid = si->si_pid; + si32->si_uid = si->si_uid; + /* + * XXX sival_ptr is currently unused. + */ + si32->si_sigval.sival_int = si->si_sigval.sival_int; + break; + case SIGCHLD: + si32->si_pid = si->si_pid; + si32->si_uid = si->si_uid; + si32->si_status = si->si_status; + si32->si_utime = si->si_utime; + si32->si_stime = si->si_stime; + break; + case SIGURG: + case SIGIO: + si32->si_band = si->si_band; + si32->si_fd = si->si_fd; + break; + } +} + +void +getucontext32(struct lwp *l, ucontext32_t *ucp) +{ + struct proc *p; + + p = l->l_proc; + + ucp->uc_flags = 0; + ucp->uc_link = (uint32_t)(intptr_t)l->l_ctxlink; + + (void)sigprocmask1(p, 0, NULL, &ucp->uc_sigmask); + ucp->uc_flags |= _UC_SIGMASK; + + /* + * The (unsupplied) definition of the `current execution stack' + * in the System V Interface Definition appears to allow returning + * the main context stack. + */ + if ((p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK) == 0) { + ucp->uc_stack.ss_sp = USRSTACK32; + ucp->uc_stack.ss_size = ctob(p->p_vmspace->vm_ssize); + ucp->uc_stack.ss_flags = 0; /* XXX, def. is Very Fishy */ + } else { + /* Simply copy alternate signal execution stack. */ + ucp->uc_stack.ss_sp = + (uint32_t)(intptr_t)p->p_sigctx.ps_sigstk.ss_sp; + ucp->uc_stack.ss_size = p->p_sigctx.ps_sigstk.ss_size; + ucp->uc_stack.ss_flags = p->p_sigctx.ps_sigstk.ss_flags; + } + ucp->uc_flags |= _UC_STACK; + + cpu_getmcontext32(l, &ucp->uc_mcontext, &ucp->uc_flags); +} + +/* ARGSUSED */ +int +netbsd32_getcontext(struct lwp *l, void *v, register_t *retval) +{ + struct netbsd32_getcontext_args /* { + syscallarg(netbsd32_ucontextp) ucp; + } */ *uap = v; + ucontext32_t uc; + + getucontext32(l, &uc); + + return copyout(&uc, NETBSD32PTR64(SCARG(uap, ucp)), + sizeof (ucontext32_t)); +} + +int +setucontext32(struct lwp *l, const ucontext32_t *ucp) +{ + struct proc *p; + int error; + + p = l->l_proc; + if ((error = cpu_setmcontext32(l, &ucp->uc_mcontext, + ucp->uc_flags)) != 0) + return (error); + l->l_ctxlink = (void *)(intptr_t)ucp->uc_link; + /* + * We might want to take care of the stack portion here but currently + * don't; see the comment in getucontext(). + */ + if ((ucp->uc_flags & _UC_SIGMASK) != 0) + sigprocmask1(p, SIG_SETMASK, &ucp->uc_sigmask, NULL); + + return 0; +} + +/* ARGSUSED */ +int +netbsd32_setcontext(struct lwp *l, void *v, register_t *retval) +{ + struct netbsd32_setcontext_args /* { + syscallarg(netbsd32_ucontextp) ucp; + } */ *uap = v; + ucontext32_t uc; + int error; + void *p; + + p = NETBSD32PTR64(SCARG(uap, ucp)); + if (p == NULL) + exit1(l, W_EXITCODE(0, 0)); + else if ((error = copyin(p, &uc, sizeof (uc))) != 0 || + (error = setucontext32(l, &uc)) != 0) + return (error); + + return (EJUSTRETURN); +} diff --git a/sys/compat/netbsd32/netbsd32_sysent.c b/sys/compat/netbsd32/netbsd32_sysent.c index 84cedde6a0df..7ff32e1eefd5 100644 --- a/sys/compat/netbsd32/netbsd32_sysent.c +++ b/sys/compat/netbsd32/netbsd32_sysent.c @@ -1,14 +1,14 @@ -/* $NetBSD: netbsd32_sysent.c,v 1.29 2003/01/18 23:40:00 thorpej Exp $ */ +/* $NetBSD: netbsd32_sysent.c,v 1.30 2003/10/13 18:55:30 fvdl Exp $ */ /* * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * created from NetBSD: syscalls.master,v 1.23 2003/01/18 08:28:26 thorpej Exp + * created from NetBSD: syscalls.master,v 1.24 2003/10/13 18:53:35 fvdl Exp */ #include -__KERNEL_RCSID(0, "$NetBSD: netbsd32_sysent.c,v 1.29 2003/01/18 23:40:00 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_sysent.c,v 1.30 2003/10/13 18:55:30 fvdl Exp $"); #if defined(_KERNEL_OPT) #include "opt_ktrace.h" @@ -71,6 +71,18 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_sysent.c,v 1.29 2003/01/18 23:40:00 thorpej #define compat_14(func) sys_nosys #endif +#ifdef COMPAT_15 +#define compat_15(func) __CONCAT(compat_15_,func) +#else +#define compat_15(func) sys_nosys +#endif + +#ifdef COMPAT_16 +#define compat_16(func) __CONCAT(compat_16_,func) +#else +#define compat_16(func) sys_nosys +#endif + #define s(type) sizeof(type) struct sysent netbsd32_sysent[] = { @@ -783,8 +795,8 @@ struct sysent netbsd32_sysent[] = { netbsd32___sigprocmask14 }, /* 293 = netbsd32___sigprocmask14 */ { 1, s(struct netbsd32___sigsuspend14_args), 0, netbsd32___sigsuspend14 }, /* 294 = netbsd32___sigsuspend14 */ - { 1, s(struct netbsd32___sigreturn14_args), 0, - netbsd32___sigreturn14 }, /* 295 = netbsd32___sigreturn14 */ + { 1, s(struct compat_16_netbsd32___sigreturn14_args), 0, + compat_16(netbsd32___sigreturn14) },/* 295 = compat_16 netbsd32___sigreturn14 */ { 2, s(struct netbsd32___getcwd_args), 0, netbsd32___getcwd }, /* 296 = netbsd32___getcwd */ { 1, s(struct netbsd32_fchroot_args), 0, @@ -822,10 +834,10 @@ struct sysent netbsd32_sysent[] = { sys_issetugid }, /* 305 = issetugid */ { 3, s(struct netbsd32_utrace_args), 0, netbsd32_utrace }, /* 306 = netbsd32_utrace */ - { 0, 0, 0, - sys_nosys }, /* 307 = unimplemented */ - { 0, 0, 0, - sys_nosys }, /* 308 = unimplemented */ + { 1, s(struct netbsd32_getcontext_args), 0, + netbsd32_getcontext }, /* 307 = netbsd32_getcontext */ + { 3, s(struct netbsd32_setcontext_args), 0, + netbsd32_setcontext }, /* 308 = netbsd32_setcontext */ { 0, 0, 0, sys_nosys }, /* 309 = unimplemented */ { 0, 0, 0,