1112963Sjake/*- 2112963Sjake * Copyright (c) 2003 Jake Burkholder. 3112963Sjake * All rights reserved. 4112963Sjake * 5112963Sjake * Redistribution and use in source and binary forms, with or without 6112963Sjake * modification, are permitted provided that the following conditions 7112963Sjake * are met: 8112963Sjake * 1. Redistributions of source code must retain the above copyright 9112963Sjake * notice, this list of conditions and the following disclaimer. 10112963Sjake * 2. Redistributions in binary form must reproduce the above copyright 11112963Sjake * notice, this list of conditions and the following disclaimer in the 12112963Sjake * documentation and/or other materials provided with the distribution. 13112963Sjake * 14112963Sjake * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15112963Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16112963Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17112963Sjake * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18112963Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19112963Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20112963Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21112963Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22112963Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23112963Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24112963Sjake * SUCH DAMAGE. 25112963Sjake */ 26112963Sjake 27112963Sjake#include <sys/cdefs.h> 28112963Sjake__FBSDID("$FreeBSD$"); 29112963Sjake 30112963Sjake#include <sys/param.h> 31112963Sjake#include <sys/signal.h> 32112963Sjake#include <sys/ucontext.h> 33112963Sjake 34112963Sjake#include <machine/frame.h> 35112963Sjake#include <machine/tstate.h> 36112963Sjake 37112963Sjake#include <errno.h> 38112963Sjake#include <stdarg.h> 39112963Sjake#include <stdlib.h> 40112963Sjake#include <unistd.h> 41112963Sjake 42112963Sjake__weak_reference(__makecontext, makecontext); 43112963Sjake 44112963Sjakevoid _ctx_done(ucontext_t *ucp); 45112963Sjakevoid _ctx_start(void); 46112963Sjake 47112963Sjakevoid 48112963Sjake__makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...) 49112963Sjake{ 50112963Sjake mcontext_t *mc; 51112963Sjake uint64_t sp; 52112963Sjake va_list ap; 53112963Sjake int i; 54112963Sjake 55112963Sjake mc = &ucp->uc_mcontext; 56112963Sjake if (ucp == NULL || 57254157Smarius (mc->_mc_flags & ((1L << _MC_VERSION_BITS) - 1)) != _MC_VERSION) 58112963Sjake return; 59112963Sjake if ((argc < 0) || (argc > 6) || 60112963Sjake (ucp->uc_stack.ss_sp == NULL) || 61112963Sjake (ucp->uc_stack.ss_size < MINSIGSTKSZ)) { 62254157Smarius mc->_mc_flags = 0; 63112963Sjake return; 64112963Sjake } 65112963Sjake mc = &ucp->uc_mcontext; 66112963Sjake sp = (uint64_t)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size; 67112963Sjake va_start(ap, argc); 68112963Sjake for (i = 0; i < argc; i++) 69112963Sjake mc->mc_out[i] = va_arg(ap, uint64_t); 70112963Sjake va_end(ap); 71112963Sjake mc->mc_global[1] = (uint64_t)start; 72112963Sjake mc->mc_global[2] = (uint64_t)ucp; 73112963Sjake mc->mc_out[6] = sp - SPOFF - sizeof(struct frame); 74254157Smarius mc->_mc_tnpc = (uint64_t)_ctx_start + 4; 75254157Smarius mc->_mc_tpc = (uint64_t)_ctx_start; 76112963Sjake} 77112963Sjake 78112963Sjakevoid 79112963Sjake_ctx_done(ucontext_t *ucp) 80112963Sjake{ 81112963Sjake 82112963Sjake if (ucp->uc_link == NULL) 83112963Sjake exit(0); 84112963Sjake else { 85254157Smarius ucp->uc_mcontext._mc_flags = 0; 86112963Sjake setcontext((const ucontext_t *)ucp->uc_link); 87112963Sjake abort(); 88112963Sjake } 89112963Sjake} 90