11d6e1c66SJonathan Mini /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3d915a14eSPedro F. Giffuni *
41d6e1c66SJonathan Mini * Copyright (c) 2002 Jonathan Mini <mini@freebsd.org>
51d6e1c66SJonathan Mini * All rights reserved.
61d6e1c66SJonathan Mini *
71d6e1c66SJonathan Mini * Redistribution and use in source and binary forms, with or without
81d6e1c66SJonathan Mini * modification, are permitted provided that the following conditions
91d6e1c66SJonathan Mini * are met:
101d6e1c66SJonathan Mini * 1. Redistributions of source code must retain the above copyright
111d6e1c66SJonathan Mini * notice, this list of conditions and the following disclaimer.
121d6e1c66SJonathan Mini * 2. Redistributions in binary form must reproduce the above copyright
131d6e1c66SJonathan Mini * notice, this list of conditions and the following disclaimer in the
141d6e1c66SJonathan Mini * documentation and/or other materials provided with the distribution.
151d6e1c66SJonathan Mini *
161d6e1c66SJonathan Mini * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
171d6e1c66SJonathan Mini * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
181d6e1c66SJonathan Mini * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
191d6e1c66SJonathan Mini * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
201d6e1c66SJonathan Mini * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
211d6e1c66SJonathan Mini * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
221d6e1c66SJonathan Mini * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
231d6e1c66SJonathan Mini * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
241d6e1c66SJonathan Mini * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
251d6e1c66SJonathan Mini * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
261d6e1c66SJonathan Mini * SUCH DAMAGE.
271d6e1c66SJonathan Mini */
281d6e1c66SJonathan Mini
291d6e1c66SJonathan Mini #include <sys/param.h>
301d6e1c66SJonathan Mini #include <sys/ucontext.h>
311d6e1c66SJonathan Mini #include <machine/psl.h>
321d6e1c66SJonathan Mini #include <machine/sigframe.h>
33dcf0aad8SJonathan Mini #include <signal.h>
34e0554a53SJacques Vidrine #include <strings.h>
351d6e1c66SJonathan Mini
367630ea31SJonathan Mini __weak_reference(__signalcontext, signalcontext);
377630ea31SJonathan Mini
381d6e1c66SJonathan Mini extern void _ctx_start(ucontext_t *, int argc, ...);
391d6e1c66SJonathan Mini
401d6e1c66SJonathan Mini int
__signalcontext(ucontext_t * ucp,int sig,__sighandler_t * func)417630ea31SJonathan Mini __signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func)
421d6e1c66SJonathan Mini {
43dcf0aad8SJonathan Mini register_t *p;
441d6e1c66SJonathan Mini struct sigframe *sfp;
451d6e1c66SJonathan Mini
46dcf0aad8SJonathan Mini /*-
471d6e1c66SJonathan Mini * Set up stack.
481d6e1c66SJonathan Mini * (n = sizeof(int))
491d6e1c66SJonathan Mini * 2n+sizeof(struct sigframe) ucp
501d6e1c66SJonathan Mini * 2n struct sigframe
511d6e1c66SJonathan Mini * 1n &func
521d6e1c66SJonathan Mini * 0n &_ctx_start
531d6e1c66SJonathan Mini */
54dcf0aad8SJonathan Mini p = (register_t *)(void *)(intptr_t)ucp->uc_mcontext.mc_esp;
55dcf0aad8SJonathan Mini *--p = (register_t)(intptr_t)ucp;
5667aba1c6SDaniel Eischen p = (register_t *)((u_register_t)p & ~0xF); /* Align to 16 bytes. */
5767aba1c6SDaniel Eischen p = (register_t *)((u_register_t)p - sizeof(struct sigframe));
581d6e1c66SJonathan Mini sfp = (struct sigframe *)p;
591d6e1c66SJonathan Mini bzero(sfp, sizeof(struct sigframe));
601d6e1c66SJonathan Mini sfp->sf_signum = sig;
61dcf0aad8SJonathan Mini sfp->sf_siginfo = (register_t)(intptr_t)&sfp->sf_si;
62dcf0aad8SJonathan Mini sfp->sf_ucontext = (register_t)(intptr_t)&sfp->sf_uc;
631d6e1c66SJonathan Mini sfp->sf_ahu.sf_action = (__siginfohandler_t *)func;
641d6e1c66SJonathan Mini bcopy(ucp, &sfp->sf_uc, sizeof(ucontext_t));
651d6e1c66SJonathan Mini sfp->sf_si.si_signo = sig;
66dcf0aad8SJonathan Mini *--p = (register_t)(intptr_t)func;
671d6e1c66SJonathan Mini
681d6e1c66SJonathan Mini /*
691d6e1c66SJonathan Mini * Set up ucontext_t.
701d6e1c66SJonathan Mini */
7139ba326dSDavid Xu ucp->uc_mcontext.mc_esi = ucp->uc_mcontext.mc_esp - sizeof(int);
72dcf0aad8SJonathan Mini ucp->uc_mcontext.mc_esp = (register_t)(intptr_t)p;
73dcf0aad8SJonathan Mini ucp->uc_mcontext.mc_eip = (register_t)(intptr_t)_ctx_start;
741d6e1c66SJonathan Mini ucp->uc_mcontext.mc_eflags &= ~PSL_T;
751d6e1c66SJonathan Mini ucp->uc_link = &sfp->sf_uc;
76dcf0aad8SJonathan Mini sigdelset(&ucp->uc_sigmask, sig);
771d6e1c66SJonathan Mini return (0);
781d6e1c66SJonathan Mini }
79