12357939bSOlivier Houchard /* $NetBSD: makecontext.c,v 1.2 2003/01/18 11:06:24 thorpej Exp $ */
22357939bSOlivier Houchard
32357939bSOlivier Houchard /*-
4*b61a5730SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
5d915a14eSPedro F. Giffuni *
62357939bSOlivier Houchard * Copyright (c) 2001 The NetBSD Foundation, Inc.
72357939bSOlivier Houchard * All rights reserved.
82357939bSOlivier Houchard *
92357939bSOlivier Houchard * This code is derived from software contributed to The NetBSD Foundation
102357939bSOlivier Houchard * by Klaus Klein.
112357939bSOlivier Houchard *
122357939bSOlivier Houchard * Redistribution and use in source and binary forms, with or without
132357939bSOlivier Houchard * modification, are permitted provided that the following conditions
142357939bSOlivier Houchard * are met:
152357939bSOlivier Houchard * 1. Redistributions of source code must retain the above copyright
162357939bSOlivier Houchard * notice, this list of conditions and the following disclaimer.
172357939bSOlivier Houchard * 2. Redistributions in binary form must reproduce the above copyright
182357939bSOlivier Houchard * notice, this list of conditions and the following disclaimer in the
192357939bSOlivier Houchard * documentation and/or other materials provided with the distribution.
202357939bSOlivier Houchard *
212357939bSOlivier Houchard * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
222357939bSOlivier Houchard * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
232357939bSOlivier Houchard * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
242357939bSOlivier Houchard * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
252357939bSOlivier Houchard * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
262357939bSOlivier Houchard * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
272357939bSOlivier Houchard * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
282357939bSOlivier Houchard * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
292357939bSOlivier Houchard * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
302357939bSOlivier Houchard * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
312357939bSOlivier Houchard * POSSIBILITY OF SUCH DAMAGE.
322357939bSOlivier Houchard */
332357939bSOlivier Houchard
342357939bSOlivier Houchard #include <stdlib.h>
352357939bSOlivier Houchard #include <stddef.h>
362357939bSOlivier Houchard #include <inttypes.h>
372357939bSOlivier Houchard #include <ucontext.h>
382357939bSOlivier Houchard
392357939bSOlivier Houchard #include <stdarg.h>
402357939bSOlivier Houchard
4160497154SOlivier Houchard extern void _ctx_start(void);
422357939bSOlivier Houchard
432357939bSOlivier Houchard void
ctx_done(ucontext_t * ucp)442357939bSOlivier Houchard ctx_done(ucontext_t *ucp)
452357939bSOlivier Houchard {
462357939bSOlivier Houchard
472357939bSOlivier Houchard if (ucp->uc_link == NULL)
482357939bSOlivier Houchard exit(0);
492357939bSOlivier Houchard else {
502357939bSOlivier Houchard setcontext((const ucontext_t *)ucp->uc_link);
512357939bSOlivier Houchard abort();
522357939bSOlivier Houchard }
532357939bSOlivier Houchard }
542357939bSOlivier Houchard
552357939bSOlivier Houchard __weak_reference(__makecontext, makecontext);
562357939bSOlivier Houchard
572357939bSOlivier Houchard void
__makecontext(ucontext_t * ucp,void (* func)(void),int argc,...)582357939bSOlivier Houchard __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
592357939bSOlivier Houchard {
602357939bSOlivier Houchard __greg_t *gr = ucp->uc_mcontext.__gregs;
612357939bSOlivier Houchard int i;
622357939bSOlivier Houchard unsigned int *sp;
632357939bSOlivier Houchard va_list ap;
642357939bSOlivier Houchard
652357939bSOlivier Houchard /* Compute and align stack pointer. */
662357939bSOlivier Houchard sp = (unsigned int *)
6760497154SOlivier Houchard (((uintptr_t)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size -
6860497154SOlivier Houchard sizeof(double)) & ~7);
692357939bSOlivier Houchard /* Allocate necessary stack space for arguments exceeding r0-3. */
702357939bSOlivier Houchard if (argc > 4)
712357939bSOlivier Houchard sp -= argc - 4;
722357939bSOlivier Houchard gr[_REG_SP] = (__greg_t)sp;
732357939bSOlivier Houchard /* Wipe out frame pointer. */
742357939bSOlivier Houchard gr[_REG_FP] = 0;
752357939bSOlivier Houchard /* Arrange for return via the trampoline code. */
7660497154SOlivier Houchard gr[_REG_PC] = (__greg_t)_ctx_start;
7760497154SOlivier Houchard gr[_REG_R4] = (__greg_t)func;
7860497154SOlivier Houchard gr[_REG_R5] = (__greg_t)ucp;
792357939bSOlivier Houchard
802357939bSOlivier Houchard va_start(ap, argc);
812357939bSOlivier Houchard /* Pass up to four arguments in r0-3. */
822357939bSOlivier Houchard for (i = 0; i < argc && i < 4; i++)
832357939bSOlivier Houchard gr[_REG_R0 + i] = va_arg(ap, int);
842357939bSOlivier Houchard /* Pass any additional arguments on the stack. */
852357939bSOlivier Houchard for (argc -= i; argc > 0; argc--)
862357939bSOlivier Houchard *sp++ = va_arg(ap, int);
872357939bSOlivier Houchard va_end(ap);
882357939bSOlivier Houchard }
89