$NetBSD$ --- src/arch/netbsd/mcontext/context.c.orig 2017-11-02 06:34:51.953668414 +0000 +++ src/arch/netbsd/mcontext/context.c @@ -0,0 +1,63 @@ +/* This code is taken from libtask library. + * Rip-off done by stsp for dosemu2 project. + * Original copyrights below. */ + +/* Copyright (c) 2005-2006 Russ Cox, MIT; see COPYRIGHT */ + +#include +#include +#include +#include +#include +#include "mcontext.h" + +#if defined(__i386__) +void +makemcontext(m_ucontext_t *ucp, void (*func)(void), int argc, ...) +{ + int *sp; + + sp = (int*)ucp->uc_stack.ss_sp+ucp->uc_stack.ss_size/4; + sp -= argc; + sp = (void*)((uintptr_t)sp - (uintptr_t)sp%16); /* 16-align for OS X */ + memmove(sp, &argc+1, argc*sizeof(int)); + + *--sp = 0; /* return address */ + ucp->uc_mcontext.mc_eip = (long)func; + ucp->uc_mcontext.mc_esp = (int)sp; +} +#endif + +#if defined(__x86_64__) +void +makemcontext(m_ucontext_t *ucp, void (*func)(void), int argc, ...) +{ + long *sp; + va_list va; + + memset(&ucp->uc_mcontext, 0, sizeof ucp->uc_mcontext); + if (argc) { + assert(argc <= 2); // oops + va_start(va, argc); + if (argc >= 1) + ucp->uc_mcontext.mc_rdi = va_arg(va, long); + if (argc >= 2) + ucp->uc_mcontext.mc_rsi = va_arg(va, long); + va_end(va); + } + sp = (long*)ucp->uc_stack.ss_sp+ucp->uc_stack.ss_size/sizeof(long); + sp -= argc; + sp = (void*)((uintptr_t)sp - (uintptr_t)sp%16); /* 16-align for OS X */ + *--sp = 0; /* return address */ + ucp->uc_mcontext.mc_rip = (long)func; + ucp->uc_mcontext.mc_rsp = (long)sp; +} +#endif + +int +swapmcontext(m_ucontext_t *oucp, const m_ucontext_t *ucp) +{ + if(getmcontext(oucp) == 0) + setmcontext(ucp); + return 0; +}