From nobody Sat Oct 16 13:02:54 2021 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 0EA53180C677; Sat, 16 Oct 2021 13:02:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4HWjwt4Ycjz3DpJ; Sat, 16 Oct 2021 13:02:54 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 28B9D1A788; Sat, 16 Oct 2021 13:02:54 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 19GD2sAm037185; Sat, 16 Oct 2021 13:02:54 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 19GD2sVW037184; Sat, 16 Oct 2021 13:02:54 GMT (envelope-from git) Date: Sat, 16 Oct 2021 13:02:54 GMT Message-Id: <202110161302.19GD2sVW037184@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: 6a54fd55de06 - stable/13 - arm: move signal delivery code to exec_machdep.c List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 6a54fd55de060fbde2cff17188c2a926f542d745 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=6a54fd55de060fbde2cff17188c2a926f542d745 commit 6a54fd55de060fbde2cff17188c2a926f542d745 Author: Konstantin Belousov AuthorDate: 2021-10-04 11:39:11 +0000 Commit: Konstantin Belousov CommitDate: 2021-10-16 13:01:48 +0000 arm: move signal delivery code to exec_machdep.c (cherry picked from commit dfaf65023ef0d9f68da856f3795448596751a69d) --- sys/arm/arm/exec_machdep.c | 379 +++++++++++++++++++++++++++++++++++++++++++++ sys/arm/arm/machdep.c | 322 -------------------------------------- sys/conf/files.arm | 1 + 3 files changed, 380 insertions(+), 322 deletions(-) diff --git a/sys/arm/arm/exec_machdep.c b/sys/arm/arm/exec_machdep.c new file mode 100644 index 000000000000..3b952463b1ad --- /dev/null +++ b/sys/arm/arm/exec_machdep.c @@ -0,0 +1,379 @@ +/* $NetBSD: arm32_machdep.c,v 1.44 2004/03/24 15:34:47 atatat Exp $ */ + +/*- + * SPDX-License-Identifier: BSD-4-Clause + * + * Copyright (c) 2004 Olivier Houchard + * Copyright (c) 1994-1998 Mark Brinicombe. + * Copyright (c) 1994 Brini. + * All rights reserved. + * + * This code is derived from software written for Brini by Mark Brinicombe + * + * 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 Mark Brinicombe + * for the NetBSD Project. + * 4. The name of the company nor the name of the author may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * Clear registers on exec + */ +void +exec_setregs(struct thread *td, struct image_params *imgp, uintptr_t stack) +{ + struct trapframe *tf = td->td_frame; + + memset(tf, 0, sizeof(*tf)); + tf->tf_usr_sp = stack; + tf->tf_usr_lr = imgp->entry_addr; + tf->tf_svc_lr = 0x77777777; + tf->tf_pc = imgp->entry_addr; + tf->tf_spsr = PSR_USR32_MODE; + if ((register_t)imgp->entry_addr & 1) + tf->tf_spsr |= PSR_T; +} + +#ifdef VFP +/* + * Get machine VFP context. + */ +void +get_vfpcontext(struct thread *td, mcontext_vfp_t *vfp) +{ + struct pcb *pcb; + + pcb = td->td_pcb; + if (td == curthread) { + critical_enter(); + vfp_store(&pcb->pcb_vfpstate, false); + critical_exit(); + } else + MPASS(TD_IS_SUSPENDED(td)); + memcpy(vfp->mcv_reg, pcb->pcb_vfpstate.reg, + sizeof(vfp->mcv_reg)); + vfp->mcv_fpscr = pcb->pcb_vfpstate.fpscr; +} + +/* + * Set machine VFP context. + */ +void +set_vfpcontext(struct thread *td, mcontext_vfp_t *vfp) +{ + struct pcb *pcb; + + pcb = td->td_pcb; + if (td == curthread) { + critical_enter(); + vfp_discard(td); + critical_exit(); + } else + MPASS(TD_IS_SUSPENDED(td)); + memcpy(pcb->pcb_vfpstate.reg, vfp->mcv_reg, + sizeof(pcb->pcb_vfpstate.reg)); + pcb->pcb_vfpstate.fpscr = vfp->mcv_fpscr; +} +#endif + +int +arm_get_vfpstate(struct thread *td, void *args) +{ + int rv; + struct arm_get_vfpstate_args ua; + mcontext_vfp_t mcontext_vfp; + + rv = copyin(args, &ua, sizeof(ua)); + if (rv != 0) + return (rv); + if (ua.mc_vfp_size != sizeof(mcontext_vfp_t)) + return (EINVAL); +#ifdef VFP + get_vfpcontext(td, &mcontext_vfp); +#else + bzero(&mcontext_vfp, sizeof(mcontext_vfp)); +#endif + + rv = copyout(&mcontext_vfp, ua.mc_vfp, sizeof(mcontext_vfp)); + if (rv != 0) + return (rv); + return (0); +} + +/* + * Get machine context. + */ +int +get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) +{ + struct trapframe *tf = td->td_frame; + __greg_t *gr = mcp->__gregs; + + if (clear_ret & GET_MC_CLEAR_RET) { + gr[_REG_R0] = 0; + gr[_REG_CPSR] = tf->tf_spsr & ~PSR_C; + } else { + gr[_REG_R0] = tf->tf_r0; + gr[_REG_CPSR] = tf->tf_spsr; + } + gr[_REG_R1] = tf->tf_r1; + gr[_REG_R2] = tf->tf_r2; + gr[_REG_R3] = tf->tf_r3; + gr[_REG_R4] = tf->tf_r4; + gr[_REG_R5] = tf->tf_r5; + gr[_REG_R6] = tf->tf_r6; + gr[_REG_R7] = tf->tf_r7; + gr[_REG_R8] = tf->tf_r8; + gr[_REG_R9] = tf->tf_r9; + gr[_REG_R10] = tf->tf_r10; + gr[_REG_R11] = tf->tf_r11; + gr[_REG_R12] = tf->tf_r12; + gr[_REG_SP] = tf->tf_usr_sp; + gr[_REG_LR] = tf->tf_usr_lr; + gr[_REG_PC] = tf->tf_pc; + + mcp->mc_vfp_size = 0; + mcp->mc_vfp_ptr = NULL; + memset(&mcp->mc_spare, 0, sizeof(mcp->mc_spare)); + + return (0); +} + +/* + * Set machine context. + * + * However, we don't set any but the user modifiable flags, and we won't + * touch the cs selector. + */ +int +set_mcontext(struct thread *td, mcontext_t *mcp) +{ + mcontext_vfp_t mc_vfp, *vfp; + struct trapframe *tf = td->td_frame; + const __greg_t *gr = mcp->__gregs; + int spsr; + + /* + * Make sure the processor mode has not been tampered with and + * interrupts have not been disabled. + */ + spsr = gr[_REG_CPSR]; + if ((spsr & PSR_MODE) != PSR_USR32_MODE || + (spsr & (PSR_I | PSR_F)) != 0) + return (EINVAL); + +#ifdef WITNESS + if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_size != sizeof(mc_vfp)) { + printf("%s: %s: Malformed mc_vfp_size: %d (0x%08X)\n", + td->td_proc->p_comm, __func__, + mcp->mc_vfp_size, mcp->mc_vfp_size); + } else if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_ptr == NULL) { + printf("%s: %s: c_vfp_size != 0 but mc_vfp_ptr == NULL\n", + td->td_proc->p_comm, __func__); + } +#endif + + if (mcp->mc_vfp_size == sizeof(mc_vfp) && mcp->mc_vfp_ptr != NULL) { + if (copyin(mcp->mc_vfp_ptr, &mc_vfp, sizeof(mc_vfp)) != 0) + return (EFAULT); + vfp = &mc_vfp; + } else { + vfp = NULL; + } + + tf->tf_r0 = gr[_REG_R0]; + tf->tf_r1 = gr[_REG_R1]; + tf->tf_r2 = gr[_REG_R2]; + tf->tf_r3 = gr[_REG_R3]; + tf->tf_r4 = gr[_REG_R4]; + tf->tf_r5 = gr[_REG_R5]; + tf->tf_r6 = gr[_REG_R6]; + tf->tf_r7 = gr[_REG_R7]; + tf->tf_r8 = gr[_REG_R8]; + tf->tf_r9 = gr[_REG_R9]; + tf->tf_r10 = gr[_REG_R10]; + tf->tf_r11 = gr[_REG_R11]; + tf->tf_r12 = gr[_REG_R12]; + tf->tf_usr_sp = gr[_REG_SP]; + tf->tf_usr_lr = gr[_REG_LR]; + tf->tf_pc = gr[_REG_PC]; + tf->tf_spsr = gr[_REG_CPSR]; +#ifdef VFP + if (vfp != NULL) + set_vfpcontext(td, vfp); +#endif + return (0); +} + +void +sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +{ + struct thread *td; + struct proc *p; + struct trapframe *tf; + struct sigframe *fp, frame; + struct sigacts *psp; + struct sysentvec *sysent; + int onstack; + int sig; + int code; + + 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; + onstack = sigonstack(tf->tf_usr_sp); + + 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 && !(onstack) && + SIGISMEMBER(psp->ps_sigonstack, sig)) { + fp = (struct sigframe *)((uintptr_t)td->td_sigstk.ss_sp + + td->td_sigstk.ss_size); +#if defined(COMPAT_43) + td->td_sigstk.ss_flags |= SS_ONSTACK; +#endif + } else + fp = (struct sigframe *)td->td_frame->tf_usr_sp; + + /* make room on the stack */ + fp--; + + /* make the stack aligned */ + fp = (struct sigframe *)STACKALIGN(fp); + /* Populate the siginfo frame. */ + bzero(&frame, sizeof(frame)); + get_mcontext(td, &frame.sf_uc.uc_mcontext, 0); +#ifdef VFP + get_vfpcontext(td, &frame.sf_vfp); + frame.sf_uc.uc_mcontext.mc_vfp_size = sizeof(fp->sf_vfp); + frame.sf_uc.uc_mcontext.mc_vfp_ptr = &fp->sf_vfp; +#else + frame.sf_uc.uc_mcontext.mc_vfp_size = 0; + frame.sf_uc.uc_mcontext.mc_vfp_ptr = NULL; +#endif + frame.sf_si = ksi->ksi_info; + frame.sf_uc.uc_sigmask = *mask; + frame.sf_uc.uc_stack = td->td_sigstk; + frame.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) != 0 ? + (onstack ? SS_ONSTACK : 0) : SS_DISABLE; + mtx_unlock(&psp->ps_mtx); + PROC_UNLOCK(td->td_proc); + + /* Copy the sigframe out to the user's stack. */ + if (copyout(&frame, fp, sizeof(*fp)) != 0) { + /* Process has trashed its stack. Kill it. */ + CTR2(KTR_SIG, "sendsig: sigexit td=%p fp=%p", td, fp); + PROC_LOCK(p); + sigexit(td, SIGILL); + } + + /* + * Build context to run handler in. We invoke the handler + * directly, only returning via the trampoline. Note the + * trampoline version numbers are coordinated with machine- + * dependent code in libc. + */ + + tf->tf_r0 = sig; + tf->tf_r1 = (register_t)&fp->sf_si; + tf->tf_r2 = (register_t)&fp->sf_uc; + + /* the trampoline uses r5 as the uc address */ + tf->tf_r5 = (register_t)&fp->sf_uc; + tf->tf_pc = (register_t)catcher; + tf->tf_usr_sp = (register_t)fp; + sysent = p->p_sysent; + if (sysent->sv_sigcode_base != 0) + tf->tf_usr_lr = (register_t)sysent->sv_sigcode_base; + else + tf->tf_usr_lr = (register_t)(sysent->sv_psstrings - + *(sysent->sv_szsigcode)); + /* Set the mode to enter in the signal handler */ +#if __ARM_ARCH >= 7 + if ((register_t)catcher & 1) + tf->tf_spsr |= PSR_T; + else + tf->tf_spsr &= ~PSR_T; +#endif + + CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_usr_lr, + tf->tf_usr_sp); + + PROC_LOCK(p); + mtx_lock(&psp->ps_mtx); +} + +int +sys_sigreturn(struct thread *td, struct sigreturn_args *uap) +{ + ucontext_t uc; + int error; + + if (uap == NULL) + return (EFAULT); + if (copyin(uap->sigcntxp, &uc, sizeof(uc))) + return (EFAULT); + /* Restore register context. */ + error = set_mcontext(td, &uc.uc_mcontext); + if (error != 0) + return (error); + + /* Restore signal mask. */ + kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); + + return (EJUSTRETURN); +} diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index ea5b5a0de251..c2e5a29bd244 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -337,328 +337,6 @@ spinlock_exit(void) } } -/* - * Clear registers on exec - */ -void -exec_setregs(struct thread *td, struct image_params *imgp, uintptr_t stack) -{ - struct trapframe *tf = td->td_frame; - - memset(tf, 0, sizeof(*tf)); - tf->tf_usr_sp = stack; - tf->tf_usr_lr = imgp->entry_addr; - tf->tf_svc_lr = 0x77777777; - tf->tf_pc = imgp->entry_addr; - tf->tf_spsr = PSR_USR32_MODE; - if ((register_t)imgp->entry_addr & 1) - tf->tf_spsr |= PSR_T; -} - -#ifdef VFP -/* - * Get machine VFP context. - */ -void -get_vfpcontext(struct thread *td, mcontext_vfp_t *vfp) -{ - struct pcb *pcb; - - pcb = td->td_pcb; - if (td == curthread) { - critical_enter(); - vfp_store(&pcb->pcb_vfpstate, false); - critical_exit(); - } else - MPASS(TD_IS_SUSPENDED(td)); - memcpy(vfp->mcv_reg, pcb->pcb_vfpstate.reg, - sizeof(vfp->mcv_reg)); - vfp->mcv_fpscr = pcb->pcb_vfpstate.fpscr; -} - -/* - * Set machine VFP context. - */ -void -set_vfpcontext(struct thread *td, mcontext_vfp_t *vfp) -{ - struct pcb *pcb; - - pcb = td->td_pcb; - if (td == curthread) { - critical_enter(); - vfp_discard(td); - critical_exit(); - } else - MPASS(TD_IS_SUSPENDED(td)); - memcpy(pcb->pcb_vfpstate.reg, vfp->mcv_reg, - sizeof(pcb->pcb_vfpstate.reg)); - pcb->pcb_vfpstate.fpscr = vfp->mcv_fpscr; -} -#endif - -int -arm_get_vfpstate(struct thread *td, void *args) -{ - int rv; - struct arm_get_vfpstate_args ua; - mcontext_vfp_t mcontext_vfp; - - rv = copyin(args, &ua, sizeof(ua)); - if (rv != 0) - return (rv); - if (ua.mc_vfp_size != sizeof(mcontext_vfp_t)) - return (EINVAL); -#ifdef VFP - get_vfpcontext(td, &mcontext_vfp); -#else - bzero(&mcontext_vfp, sizeof(mcontext_vfp)); -#endif - - rv = copyout(&mcontext_vfp, ua.mc_vfp, sizeof(mcontext_vfp)); - if (rv != 0) - return (rv); - return (0); -} - -/* - * Get machine context. - */ -int -get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) -{ - struct trapframe *tf = td->td_frame; - __greg_t *gr = mcp->__gregs; - - if (clear_ret & GET_MC_CLEAR_RET) { - gr[_REG_R0] = 0; - gr[_REG_CPSR] = tf->tf_spsr & ~PSR_C; - } else { - gr[_REG_R0] = tf->tf_r0; - gr[_REG_CPSR] = tf->tf_spsr; - } - gr[_REG_R1] = tf->tf_r1; - gr[_REG_R2] = tf->tf_r2; - gr[_REG_R3] = tf->tf_r3; - gr[_REG_R4] = tf->tf_r4; - gr[_REG_R5] = tf->tf_r5; - gr[_REG_R6] = tf->tf_r6; - gr[_REG_R7] = tf->tf_r7; - gr[_REG_R8] = tf->tf_r8; - gr[_REG_R9] = tf->tf_r9; - gr[_REG_R10] = tf->tf_r10; - gr[_REG_R11] = tf->tf_r11; - gr[_REG_R12] = tf->tf_r12; - gr[_REG_SP] = tf->tf_usr_sp; - gr[_REG_LR] = tf->tf_usr_lr; - gr[_REG_PC] = tf->tf_pc; - - mcp->mc_vfp_size = 0; - mcp->mc_vfp_ptr = NULL; - memset(&mcp->mc_spare, 0, sizeof(mcp->mc_spare)); - - return (0); -} - -/* - * Set machine context. - * - * However, we don't set any but the user modifiable flags, and we won't - * touch the cs selector. - */ -int -set_mcontext(struct thread *td, mcontext_t *mcp) -{ - mcontext_vfp_t mc_vfp, *vfp; - struct trapframe *tf = td->td_frame; - const __greg_t *gr = mcp->__gregs; - int spsr; - - /* - * Make sure the processor mode has not been tampered with and - * interrupts have not been disabled. - */ - spsr = gr[_REG_CPSR]; - if ((spsr & PSR_MODE) != PSR_USR32_MODE || - (spsr & (PSR_I | PSR_F)) != 0) - return (EINVAL); - -#ifdef WITNESS - if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_size != sizeof(mc_vfp)) { - printf("%s: %s: Malformed mc_vfp_size: %d (0x%08X)\n", - td->td_proc->p_comm, __func__, - mcp->mc_vfp_size, mcp->mc_vfp_size); - } else if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_ptr == NULL) { - printf("%s: %s: c_vfp_size != 0 but mc_vfp_ptr == NULL\n", - td->td_proc->p_comm, __func__); - } -#endif - - if (mcp->mc_vfp_size == sizeof(mc_vfp) && mcp->mc_vfp_ptr != NULL) { - if (copyin(mcp->mc_vfp_ptr, &mc_vfp, sizeof(mc_vfp)) != 0) - return (EFAULT); - vfp = &mc_vfp; - } else { - vfp = NULL; - } - - tf->tf_r0 = gr[_REG_R0]; - tf->tf_r1 = gr[_REG_R1]; - tf->tf_r2 = gr[_REG_R2]; - tf->tf_r3 = gr[_REG_R3]; - tf->tf_r4 = gr[_REG_R4]; - tf->tf_r5 = gr[_REG_R5]; - tf->tf_r6 = gr[_REG_R6]; - tf->tf_r7 = gr[_REG_R7]; - tf->tf_r8 = gr[_REG_R8]; - tf->tf_r9 = gr[_REG_R9]; - tf->tf_r10 = gr[_REG_R10]; - tf->tf_r11 = gr[_REG_R11]; - tf->tf_r12 = gr[_REG_R12]; - tf->tf_usr_sp = gr[_REG_SP]; - tf->tf_usr_lr = gr[_REG_LR]; - tf->tf_pc = gr[_REG_PC]; - tf->tf_spsr = gr[_REG_CPSR]; -#ifdef VFP - if (vfp != NULL) - set_vfpcontext(td, vfp); -#endif - return (0); -} - -void -sendsig(catcher, ksi, mask) - sig_t catcher; - ksiginfo_t *ksi; - sigset_t *mask; -{ - struct thread *td; - struct proc *p; - struct trapframe *tf; - struct sigframe *fp, frame; - struct sigacts *psp; - struct sysentvec *sysent; - int onstack; - int sig; - int code; - - 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; - onstack = sigonstack(tf->tf_usr_sp); - - 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 && !(onstack) && - SIGISMEMBER(psp->ps_sigonstack, sig)) { - fp = (struct sigframe *)((uintptr_t)td->td_sigstk.ss_sp + - td->td_sigstk.ss_size); -#if defined(COMPAT_43) - td->td_sigstk.ss_flags |= SS_ONSTACK; -#endif - } else - fp = (struct sigframe *)td->td_frame->tf_usr_sp; - - /* make room on the stack */ - fp--; - - /* make the stack aligned */ - fp = (struct sigframe *)STACKALIGN(fp); - /* Populate the siginfo frame. */ - bzero(&frame, sizeof(frame)); - get_mcontext(td, &frame.sf_uc.uc_mcontext, 0); -#ifdef VFP - get_vfpcontext(td, &frame.sf_vfp); - frame.sf_uc.uc_mcontext.mc_vfp_size = sizeof(fp->sf_vfp); - frame.sf_uc.uc_mcontext.mc_vfp_ptr = &fp->sf_vfp; -#else - frame.sf_uc.uc_mcontext.mc_vfp_size = 0; - frame.sf_uc.uc_mcontext.mc_vfp_ptr = NULL; -#endif - frame.sf_si = ksi->ksi_info; - frame.sf_uc.uc_sigmask = *mask; - frame.sf_uc.uc_stack = td->td_sigstk; - frame.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) != 0 ? - (onstack ? SS_ONSTACK : 0) : SS_DISABLE; - mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(td->td_proc); - - /* Copy the sigframe out to the user's stack. */ - if (copyout(&frame, fp, sizeof(*fp)) != 0) { - /* Process has trashed its stack. Kill it. */ - CTR2(KTR_SIG, "sendsig: sigexit td=%p fp=%p", td, fp); - PROC_LOCK(p); - sigexit(td, SIGILL); - } - - /* - * Build context to run handler in. We invoke the handler - * directly, only returning via the trampoline. Note the - * trampoline version numbers are coordinated with machine- - * dependent code in libc. - */ - - tf->tf_r0 = sig; - tf->tf_r1 = (register_t)&fp->sf_si; - tf->tf_r2 = (register_t)&fp->sf_uc; - - /* the trampoline uses r5 as the uc address */ - tf->tf_r5 = (register_t)&fp->sf_uc; - tf->tf_pc = (register_t)catcher; - tf->tf_usr_sp = (register_t)fp; - sysent = p->p_sysent; - if (sysent->sv_sigcode_base != 0) - tf->tf_usr_lr = (register_t)sysent->sv_sigcode_base; - else - tf->tf_usr_lr = (register_t)(sysent->sv_psstrings - - *(sysent->sv_szsigcode)); - /* Set the mode to enter in the signal handler */ -#if __ARM_ARCH >= 7 - if ((register_t)catcher & 1) - tf->tf_spsr |= PSR_T; - else - tf->tf_spsr &= ~PSR_T; -#endif - - CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_usr_lr, - tf->tf_usr_sp); - - PROC_LOCK(p); - mtx_lock(&psp->ps_mtx); -} - -int -sys_sigreturn(td, uap) - struct thread *td; - struct sigreturn_args /* { - const struct __ucontext *sigcntxp; - } */ *uap; -{ - ucontext_t uc; - int error; - - if (uap == NULL) - return (EFAULT); - if (copyin(uap->sigcntxp, &uc, sizeof(uc))) - return (EFAULT); - /* Restore register context. */ - error = set_mcontext(td, &uc.uc_mcontext); - if (error != 0) - return (error); - - /* Restore signal mask. */ - kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); - - return (EJUSTRETURN); -} - /* * Construct a PCB from a trapframe. This is called from kdb_trap() where * we want to start a backtrace from the function that caused us to enter diff --git a/sys/conf/files.arm b/sys/conf/files.arm index 44402b5aa433..69437d21e880 100644 --- a/sys/conf/files.arm +++ b/sys/conf/files.arm @@ -25,6 +25,7 @@ arm/arm/dump_machdep.c standard arm/arm/elf_machdep.c standard arm/arm/elf_note.S standard arm/arm/exception.S standard +arm/arm/exec_machdep.c standard arm/arm/fiq.c standard arm/arm/fiq_subr.S standard arm/arm/fusu.S standard