Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc64/sparc64 Initial siginfo support for sparc64...
details: https://anonhg.NetBSD.org/src/rev/c7c89f26968f
branches: trunk
changeset: 554225:c7c89f26968f
user: christos <christos%NetBSD.org@localhost>
date: Sun Oct 26 08:05:26 2003 +0000
description:
Initial siginfo support for sparc64 (untested). COMPAT_16 sigcontext signal
delivery tested.
diffstat:
sys/arch/sparc64/sparc64/compat_16_machdep.c | 355 +++++++++++++++++++++++++
sys/arch/sparc64/sparc64/genassym.cf | 3 +-
sys/arch/sparc64/sparc64/locore.s | 11 +-
sys/arch/sparc64/sparc64/machdep.c | 373 ++++++--------------------
sys/arch/sparc64/sparc64/netbsd32_machdep.c | 9 +-
sys/arch/sparc64/sparc64/sunos32_machdep.c | 12 +-
sys/arch/sparc64/sparc64/svr4_32_machdep.c | 13 +-
sys/arch/sparc64/sparc64/svr4_machdep.c | 13 +-
8 files changed, 476 insertions(+), 313 deletions(-)
diffs (truncated from 1043 to 300 lines):
diff -r 87beae3a8d20 -r c7c89f26968f sys/arch/sparc64/sparc64/compat_16_machdep.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/sparc64/sparc64/compat_16_machdep.c Sun Oct 26 08:05:26 2003 +0000
@@ -0,0 +1,355 @@
+/* $NetBSD: compat_16_machdep.c,v 1.1 2003/10/26 08:05:26 christos Exp $ */
+
+/*-
+ * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.1 2003/10/26 08:05:26 christos Exp $");
+
+#include "opt_compat_netbsd.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/signal.h>
+#include <sys/signalvar.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/mount.h>
+#include <sys/sa.h>
+#include <sys/syscallargs.h>
+
+#include <machine/signal.h>
+#include <machine/frame.h>
+
+#if defined(COMPAT_16)
+
+#ifdef DEBUG
+/* See sigdebug.h */
+#include <sparc64/sparc64/sigdebug.h>
+int sigdebug = 0x0;
+int sigpid = 0;
+#endif
+
+#ifdef __arch64__
+#define STACK_OFFSET BIAS
+#define CPOUTREG(l,v) copyout(&(v), (l), sizeof(v))
+#undef CCFSZ
+#define CCFSZ CC64FSZ
+#else
+#define STACK_OFFSET 0
+#define CPOUTREG(l,v) copyout(&(v), (l), sizeof(v))
+#endif
+
+struct sigframe_sigcontext {
+ int sf_signo; /* signal number */
+ int sf_code; /* code */
+#ifndef __arch64__
+ struct sigcontext *sf_scp; /* SunOS user addr of sigcontext */
+ int sf_addr; /* SunOS compat, always 0 for now */
+#endif
+ struct sigcontext sf_sc; /* actual sigcontext */
+};
+
+/*
+ * Send an interrupt to process.
+ */
+void
+sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask)
+{
+ struct lwp *l = curlwp;
+ struct proc *p = l->l_proc;
+ struct sigacts *ps = p->p_sigacts;
+ void *addr;
+ struct rwindow *newsp;
+#ifdef NOT_DEBUG
+ struct rwindow tmpwin;
+#endif
+ int onstack;
+ int sig = ksi->ksi_signo;
+ struct sigframe_sigcontext *fp = getframe(l, sig, &onstack);
+ struct sigframe_sigcontext sf;
+ sig_t catcher = SIGACTION(p, sig).sa_handler;
+ struct trapframe64 *tf = l->l_md.md_tf;
+ /* Allocate an aligned sigframe */
+ fp = (void *)((u_long)(fp - 1) & ~0x0f);
+
+#ifdef DEBUG
+ sigpid = p->p_pid;
+ if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
+ printf("sendsig_sigcontext: %s[%d] sig %d newusp %p scp %p\n",
+ p->p_comm, p->p_pid, sig, fp, &fp->sf_sc);
+#ifdef DDB
+ if (sigdebug & SDB_DDB) Debugger();
+#endif
+ }
+#endif
+
+ /*
+ * Now set up the signal frame. We build it in kernel space
+ * and then copy it out. We probably ought to just build it
+ * directly in user space....
+ */
+ sf.sf_signo = sig;
+ sf.sf_code = ksi->ksi_trap;
+#ifndef __arch64__
+ sf.sf_scp = 0;
+ sf.sf_addr = 0; /* XXX */
+#endif
+
+ /*
+ * Build the signal context to be used by sigreturn.
+ */
+ sf.sf_sc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK;
+ sf.sf_sc.sc_mask = *mask;
+#ifdef COMPAT_13
+ /*
+ * XXX We always have to save an old style signal mask because
+ * XXX we might be delivering a signal to a process which will
+ * XXX escape from the signal in a non-standard way and invoke
+ * XXX sigreturn() directly.
+ */
+ native_sigset_to_sigset13(mask, &sf.sf_sc.__sc_mask13);
+#endif
+ /* Save register context. */
+ sf.sf_sc.sc_sp = (long)tf->tf_out[6];
+ sf.sf_sc.sc_pc = tf->tf_pc;
+ sf.sf_sc.sc_npc = tf->tf_npc;
+#ifdef __arch64__
+ sf.sf_sc.sc_tstate = tf->tf_tstate; /* XXX */
+#else
+ sf.sf_sc.sc_psr = TSTATECCR_TO_PSR(tf->tf_tstate); /* XXX */
+#endif
+ sf.sf_sc.sc_g1 = tf->tf_global[1];
+ sf.sf_sc.sc_o0 = tf->tf_out[0];
+
+ /*
+ * Put the stack in a consistent state before we whack away
+ * at it. Note that write_user_windows may just dump the
+ * registers into the pcb; we need them in the process's memory.
+ * We also need to make sure that when we start the signal handler,
+ * its %i6 (%fp), which is loaded from the newly allocated stack area,
+ * joins seamlessly with the frame it was in when the signal occurred,
+ * so that the debugger and _longjmp code can back up through it.
+ */
+ newsp = (struct rwindow *)((vaddr_t)fp - sizeof(struct rwindow));
+ write_user_windows();
+#ifdef DEBUG
+ if ((sigdebug & SDB_KSTACK))
+ printf("sendsig: saving sf to %p, setting stack pointer %p to %p\n",
+ fp, &(((struct rwindow *)newsp)->rw_in[6]),
+ (void *)(unsigned long)tf->tf_out[6]);
+#endif
+ if (rwindow_save(l) || copyout((caddr_t)&sf, (caddr_t)fp, sizeof sf) ||
+#ifdef NOT_DEBUG
+ copyin(oldsp, &tmpwin, sizeof(tmpwin)) || copyout(&tmpwin, newsp, sizeof(tmpwin)) ||
+#endif
+ CPOUTREG(&(((struct rwindow *)newsp)->rw_in[6]), tf->tf_out[6])) {
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+#ifdef DEBUG
+ if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
+ printf("sendsig: window save or copyout error\n");
+ printf("sendsig: stack was trashed trying to send sig %d, sending SIGILL\n", sig);
+#ifdef DDB
+ if (sigdebug & SDB_DDB) Debugger();
+#endif
+#endif
+ sigexit(l, SIGILL);
+ /* NOTREACHED */
+ }
+
+#ifdef DEBUG
+ if (sigdebug & SDB_FOLLOW) {
+ printf("sendsig: %s[%d] sig %d scp %p\n",
+ p->p_comm, p->p_pid, sig, &fp->sf_sc);
+ }
+#endif
+
+ /*
+ * Arrange to continue execution at the code copied out in exec().
+ * It needs the function to call in %g1, and a new stack pointer.
+ */
+ switch (ps->sa_sigdesc[sig].sd_vers) {
+ case 0: /* legacy on-stack sigtramp */
+ addr = (void *)p->p_sigctx.ps_sigcode;
+ break;
+
+ case 1:
+ addr = (void *)ps->sa_sigdesc[sig].sd_tramp;
+ break;
+
+ default:
+ /* Don't know what trampoline version; kill it. */
+ sigexit(l, SIGILL);
+ }
+
+ buildcontext(l, catcher, addr, newsp);
+
+ /* Remember that we're now on the signal stack. */
+ if (onstack)
+ p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
+
+#ifdef DEBUG
+ if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
+ printf("sendsig: about to return to catcher %p thru %p\n",
+ catcher, (void *)(unsigned long)addr);
+#ifdef DDB
+ if (sigdebug & SDB_DDB) Debugger();
+#endif
+ }
+#endif
+}
+
+/*
+ * System call to cleanup state after a signal
+ * has been taken. Reset signal mask and
+ * stack state from context left by sendsig (above),
+ * and return to the given trap frame (if there is one).
+ * Check carefully to make sure that the user has not
+ * modified the state to gain improper privileges or to cause
+ * a machine fault.
+ */
+int compat_16_sys___sigreturn14(struct lwp *, void *, register_t *);
+
+/* ARGSUSED */
+int
+compat_16_sys___sigreturn14(l, v, retval)
+ register struct lwp *l;
+ void *v;
+ register_t *retval;
+{
+ struct proc *p = l->l_proc;
+ struct compat_16_sys___sigreturn14_args /* {
+ syscallarg(struct sigcontext *) sigcntxp;
+ } */ *uap = v;
+ struct sigcontext sc, *scp;
+ register struct trapframe64 *tf;
+ int error = EINVAL;
+
+ /* First ensure consistent stack state (see sendsig). */
+ write_user_windows();
+ if (rwindow_save(l)) {
+#ifdef DEBUG
+ printf("sigreturn14: rwindow_save(%p) failed, sending SIGILL\n", p);
+#ifdef DDB
+ if (sigdebug & SDB_DDB) Debugger();
+#endif
+#endif
+ sigexit(l, SIGILL);
+ }
+#ifdef DEBUG
+ if (sigdebug & SDB_FOLLOW) {
+ printf("sigreturn14: %s[%d], sigcntxp %p\n",
+ p->p_comm, p->p_pid, SCARG(uap, sigcntxp));
+#ifdef DDB
+ if (sigdebug & SDB_DDB) Debugger();
+#endif
+ }
+#endif
+ scp = SCARG(uap, sigcntxp);
+ if ((vaddr_t)scp & 3 || (error = copyin((caddr_t)scp, &sc, sizeof sc) != 0))
+#ifdef DEBUG
+ {
+ printf("sigreturn14: copyin failed: scp=%p\n", scp);
+#ifdef DDB
+ if (sigdebug & SDB_DDB) Debugger();
+#endif
+ return (error);
+ }
+#else
Home |
Main Index |
Thread Index |
Old Index