xref: /netbsd-src/lib/libc/arch/vax/gen/makecontext.c (revision 1bb11e66cbf2b7a6c465d935b525af73082a0c66)
1*1bb11e66Schristos /*	$NetBSD: makecontext.c,v 1.4 2012/03/22 17:32:22 christos Exp $	*/
28c295614Smatt 
38c295614Smatt /*-
48c295614Smatt  * Copyright (c) 2003 The NetBSD Foundation, Inc.
58c295614Smatt  * All rights reserved.
68c295614Smatt  *
78c295614Smatt  * This code is derived from software contributed to The NetBSD Foundation
88c295614Smatt  * by Matt Thomas.
98c295614Smatt  *
108c295614Smatt  * Redistribution and use in source and binary forms, with or without
118c295614Smatt  * modification, are permitted provided that the following conditions
128c295614Smatt  * are met:
138c295614Smatt  * 1. Redistributions of source code must retain the above copyright
148c295614Smatt  *    notice, this list of conditions and the following disclaimer.
158c295614Smatt  * 2. Redistributions in binary form must reproduce the above copyright
168c295614Smatt  *    notice, this list of conditions and the following disclaimer in the
178c295614Smatt  *    documentation and/or other materials provided with the distribution.
188c295614Smatt  *
198c295614Smatt  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
208c295614Smatt  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
218c295614Smatt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
228c295614Smatt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
238c295614Smatt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
248c295614Smatt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
258c295614Smatt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
268c295614Smatt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
278c295614Smatt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
288c295614Smatt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
298c295614Smatt  * POSSIBILITY OF SUCH DAMAGE.
308c295614Smatt  */
318c295614Smatt 
328c295614Smatt #include <sys/cdefs.h>
338c295614Smatt #if defined(LIBC_SCCS) && !defined(lint)
34*1bb11e66Schristos __RCSID("$NetBSD: makecontext.c,v 1.4 2012/03/22 17:32:22 christos Exp $");
358c295614Smatt #endif
368c295614Smatt 
378c295614Smatt #include <stddef.h>
388c295614Smatt #include <inttypes.h>
398c295614Smatt #include <ucontext.h>
408c295614Smatt #include "extern.h"
418c295614Smatt 
428c295614Smatt #include <stdarg.h>
438c295614Smatt 
448c295614Smatt void
makecontext(ucontext_t * ucp,void (* func)(void),int argc,...)458c295614Smatt makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
468c295614Smatt {
478c295614Smatt 	__greg_t *gr = ucp->uc_mcontext.__gregs;
488c295614Smatt 	va_list ap;
498c295614Smatt 	int *sp;
508c295614Smatt 	int i;
518c295614Smatt 
528c295614Smatt 	/* Compute and align stack pointer. */
538c295614Smatt 	sp = (int *)
548c295614Smatt 	    (((uintptr_t)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & ~0x3);
558c295614Smatt 
568c295614Smatt 	/*
578c295614Smatt 	 * Allocate necessary stack space for arguments including arg count
588c295614Smatt 	 * and call frame
598c295614Smatt 	 */
608c295614Smatt 	sp -= argc + 1 + 5;
618c295614Smatt 
628c295614Smatt 	va_start(ap, argc);
638c295614Smatt 	sp[5] = argc;
6417a5fd34Smatt 	for (i = 1; argc > 0; argc--, i++)
658c295614Smatt 		sp[5 + i] = va_arg(ap, int);
668c295614Smatt 	va_end(ap);
678c295614Smatt 
688c295614Smatt 	sp[0] = 0;			/* condition handler is null */
698c295614Smatt 	sp[1] = 0x20000000;		/* make this a CALLS frame */
708c295614Smatt 	sp[2] = 0;			/* saved argument pointer */
718c295614Smatt 	sp[3] = 0;			/* saved frame pointer */
72*1bb11e66Schristos 	sp[4] = (int)(uintptr_t)_resumecontext+2;/* return via trampoline code */
738c295614Smatt 
74*1bb11e66Schristos 	gr[_REG_AP] = (__greg_t)(uintptr_t)(sp + 5);
75*1bb11e66Schristos 	gr[_REG_SP] = (__greg_t)(uintptr_t)sp;
76*1bb11e66Schristos 	gr[_REG_FP] = (__greg_t)(uintptr_t)sp;
77*1bb11e66Schristos 	gr[_REG_PC] = (__greg_t)(uintptr_t)func+2;
788c295614Smatt 
798c295614Smatt }
80