#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep_13.c,v 1.5 2023/12/14 20:17:18 andvar Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
#include "opt_modular.h"
#include "opt_execfmt.h"
#include "firm_events.h"
#endif
#include <sys/param.h>
#include <sys/exec.h>
#include <sys/exec_aout.h>
#include <sys/filedesc.h>
#include <sys/file.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/systm.h>
#include <sys/core.h>
#include <sys/mount.h>
#include <sys/buf.h>
#include <sys/vnode.h>
#include <sys/select.h>
#include <sys/socketvar.h>
#include <sys/ucontext.h>
#include <sys/ioctl.h>
#include <sys/kmem.h>
#include <dev/sun/event_var.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/igmp.h>
#include <netinet/igmp_var.h>
#include <netinet/ip_mroute.h>
#include <compat/netbsd32/netbsd32.h>
#include <compat/netbsd32/netbsd32_ioctl.h>
#include <compat/netbsd32/netbsd32_syscallargs.h>
#include <compat/netbsd32/netbsd32_exec.h>
#include <compat/sys/signal.h>
#include <compat/sys/signalvar.h>
#include <compat/sys/siginfo.h>
#include <compat/sys/ucontext.h>
#include <machine/frame.h>
#include <machine/pcb.h>
#include <machine/reg.h>
#include <machine/vmparam.h>
#include <machine/vuid_event.h>
#include <machine/netbsd32_machdep.h>
#include <machine/userret.h>
#ifdef DEBUG
#include <sparc64/sparc64/sigdebug.h>
#endif
int
compat_13_netbsd32_sigreturn(struct lwp *l, const struct compat_13_netbsd32_sigreturn_args *uap, register_t *retval)
{
struct netbsd32_sigcontext13 *scp;
struct netbsd32_sigcontext13 sc;
struct trapframe64 *tf;
struct proc *p = l->l_proc;
sigset_t mask;
write_user_windows();
if (rwindow_save(l)) {
#ifdef DEBUG
printf("%s: rwindow_save(%p) failed, sending SIGILL\n",
__func__, p);
console_debugger();
#endif
mutex_enter(p->p_lock);
sigexit(l, SIGILL);
}
#ifdef DEBUG
if (sigdebug & SDB_FOLLOW) {
printf("%s: %s[%d], sigcntxp %u\n", __func__,
p->p_comm, p->p_pid, SCARG(uap, sigcntxp));
if (sigdebug & SDB_DDB) console_debugger();
}
#endif
scp = (struct netbsd32_sigcontext13 *)(u_long)SCARG(uap, sigcntxp);
if ((vaddr_t)scp & 3 || (copyin((void *)scp, &sc, sizeof sc) != 0))
{
#ifdef DEBUG
printf("%s: copyin failed\n", __func__);
console_debugger();
#endif
return (EINVAL);
}
scp = ≻
tf = l->l_md.md_tf;
if (((sc.sc_pc | sc.sc_npc) & 3) != 0)
#ifdef DEBUG
{
printf("%s: pc %d or npc %d invalid\n",
__func__, sc.sc_pc, sc.sc_npc);
console_debugger();
return (EINVAL);
}
#else
return (EINVAL);
#endif
tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(sc.sc_psr);
tf->tf_pc = (int64_t)sc.sc_pc;
tf->tf_npc = (int64_t)sc.sc_npc;
tf->tf_global[1] = (int64_t)sc.sc_g1;
tf->tf_out[0] = (int64_t)sc.sc_o0;
tf->tf_out[6] = (int64_t)sc.sc_sp;
#ifdef DEBUG
if (sigdebug & SDB_FOLLOW) {
printf("%s: return trapframe pc=%d sp=%d tstate=%x\n", __func__,
(int)tf->tf_pc, (int)tf->tf_out[6], (int)tf->tf_tstate);
if (sigdebug & SDB_DDB) console_debugger();
}
#endif
mutex_enter(p->p_lock);
if (scp->sc_onstack & SS_ONSTACK)
l->l_sigstk.ss_flags |= SS_ONSTACK;
else
l->l_sigstk.ss_flags &= ~SS_ONSTACK;
native_sigset13_to_sigset((sigset13_t *)&scp->sc_mask, &mask);
(void) sigprocmask1(l, SIG_SETMASK, &mask, 0);
mutex_exit(p->p_lock);
return (EJUSTRETURN);
}
void
netbsd32_machdep_md_13_init(void)
{
}
void
netbsd32_machdep_md_13_fini(void)
{
}