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