xref: /freebsd-src/lib/libc/arm/gen/makecontext.c (revision 559a218c9b257775fb249b67945fe4a05b7a6b9f)
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