1209878Snwhitehorn/* 2209878Snwhitehorn * Copyright (c) 2004 Marcel Moolenaar, Peter Grehan 3209878Snwhitehorn * All rights reserved. 4209878Snwhitehorn * 5209878Snwhitehorn * Redistribution and use in source and binary forms, with or without 6209878Snwhitehorn * modification, are permitted provided that the following conditions 7209878Snwhitehorn * are met: 8209878Snwhitehorn * 9209878Snwhitehorn * 1. Redistributions of source code must retain the above copyright 10209878Snwhitehorn * notice, this list of conditions and the following disclaimer. 11209878Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 12209878Snwhitehorn * notice, this list of conditions and the following disclaimer in the 13209878Snwhitehorn * documentation and/or other materials provided with the distribution. 14209878Snwhitehorn * 15209878Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16209878Snwhitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17209878Snwhitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18209878Snwhitehorn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19209878Snwhitehorn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20209878Snwhitehorn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21209878Snwhitehorn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22209878Snwhitehorn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23209878Snwhitehorn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24209878Snwhitehorn * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25209878Snwhitehorn */ 26209878Snwhitehorn 27209878Snwhitehorn#include <sys/cdefs.h> 28209878Snwhitehorn__FBSDID("$FreeBSD$"); 29209878Snwhitehorn 30209878Snwhitehorn#include <sys/param.h> 31209878Snwhitehorn#include <sys/ucontext.h> 32209878Snwhitehorn#include <signal.h> 33209878Snwhitehorn#include <stdlib.h> 34209878Snwhitehorn#include <strings.h> 35209878Snwhitehorn 36209878Snwhitehorntypedef void (*handler_t)(uint32_t, uint32_t, uint32_t); 37209878Snwhitehorn 38209878Snwhitehorn/* Prototypes */ 39209878Snwhitehornstatic void ctx_wrapper(ucontext_t *ucp, handler_t func, uint32_t sig, 40209878Snwhitehorn uint32_t sig_si, uint32_t sig_uc); 41209878Snwhitehorn 42209878Snwhitehorn__weak_reference(__signalcontext, signalcontext); 43209878Snwhitehorn 44209878Snwhitehornint 45209878Snwhitehorn__signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func) 46209878Snwhitehorn{ 47209878Snwhitehorn siginfo_t *sig_si; 48209878Snwhitehorn ucontext_t *sig_uc; 49209878Snwhitehorn uintptr_t sp; 50209878Snwhitehorn 51209878Snwhitehorn /* Bail out if we don't have a valid ucontext pointer. */ 52209878Snwhitehorn if (ucp == NULL) 53209878Snwhitehorn abort(); 54209878Snwhitehorn 55209878Snwhitehorn /* 56209878Snwhitehorn * Build a 16-byte-aligned signal frame 57209878Snwhitehorn */ 58209878Snwhitehorn sp = (ucp->uc_mcontext.mc_gpr[1] - sizeof(ucontext_t)) & ~15UL; 59209878Snwhitehorn sig_uc = (ucontext_t *)sp; 60209878Snwhitehorn bcopy(ucp, sig_uc, sizeof(*sig_uc)); 61209878Snwhitehorn sp = (sp - sizeof(siginfo_t)) & ~15UL; 62209878Snwhitehorn sig_si = (siginfo_t *)sp; 63209878Snwhitehorn bzero(sig_si, sizeof(*sig_si)); 64209878Snwhitehorn sig_si->si_signo = sig; 65209878Snwhitehorn 66209878Snwhitehorn /* 67209878Snwhitehorn * Subtract 48 bytes from stack to allow for frameptr 68209878Snwhitehorn */ 69209878Snwhitehorn sp -= 6*sizeof(uint64_t); 70209878Snwhitehorn sp &= ~15UL; 71209878Snwhitehorn 72209878Snwhitehorn /* 73209878Snwhitehorn * Setup the ucontext of the signal handler. 74209878Snwhitehorn */ 75209878Snwhitehorn bzero(&ucp->uc_mcontext, sizeof(ucp->uc_mcontext)); 76209878Snwhitehorn ucp->uc_link = sig_uc; 77209878Snwhitehorn sigdelset(&ucp->uc_sigmask, sig); 78209878Snwhitehorn 79209878Snwhitehorn ucp->uc_mcontext.mc_vers = _MC_VERSION; 80209878Snwhitehorn ucp->uc_mcontext.mc_len = sizeof(struct __mcontext); 81209878Snwhitehorn ucp->uc_mcontext.mc_srr0 = (uint64_t) ctx_wrapper; 82209878Snwhitehorn ucp->uc_mcontext.mc_gpr[1] = (uint64_t) sp; 83209878Snwhitehorn ucp->uc_mcontext.mc_gpr[3] = (uint64_t) func; 84209878Snwhitehorn ucp->uc_mcontext.mc_gpr[4] = (uint64_t) sig; 85209878Snwhitehorn ucp->uc_mcontext.mc_gpr[5] = (uint64_t) sig_si; 86209878Snwhitehorn ucp->uc_mcontext.mc_gpr[6] = (uint64_t) sig_uc; 87209878Snwhitehorn 88209878Snwhitehorn return (0); 89209878Snwhitehorn} 90209878Snwhitehorn 91209878Snwhitehornstatic void 92209878Snwhitehornctx_wrapper(ucontext_t *ucp, handler_t func, uint32_t sig, uint32_t sig_si, 93209878Snwhitehorn uint32_t sig_uc) 94209878Snwhitehorn{ 95209878Snwhitehorn 96209878Snwhitehorn (*func)(sig, sig_si, sig_uc); 97209878Snwhitehorn if (ucp->uc_link == NULL) 98209878Snwhitehorn exit(0); 99209878Snwhitehorn setcontext((const ucontext_t *)ucp->uc_link); 100209878Snwhitehorn /* should never get here */ 101209878Snwhitehorn abort(); 102209878Snwhitehorn /* NOTREACHED */ 103209878Snwhitehorn} 104