makecontext.c revision 1.8
11.8Sriastrad/* $NetBSD: makecontext.c,v 1.8 2025/04/25 01:18:51 riastradh Exp $ */ 21.1Schs 31.1Schs/*- 41.1Schs * Copyright (c) 2001 The NetBSD Foundation, Inc. 51.1Schs * All rights reserved. 61.1Schs * 71.1Schs * This code is derived from software contributed to The NetBSD Foundation 81.1Schs * by Klaus Klein. 91.1Schs * 101.1Schs * Redistribution and use in source and binary forms, with or without 111.1Schs * modification, are permitted provided that the following conditions 121.1Schs * are met: 131.1Schs * 1. Redistributions of source code must retain the above copyright 141.1Schs * notice, this list of conditions and the following disclaimer. 151.1Schs * 2. Redistributions in binary form must reproduce the above copyright 161.1Schs * notice, this list of conditions and the following disclaimer in the 171.1Schs * documentation and/or other materials provided with the distribution. 181.1Schs * 191.1Schs * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 201.1Schs * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 211.1Schs * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 221.1Schs * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 231.1Schs * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 241.1Schs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 251.1Schs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 261.1Schs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 271.1Schs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 281.1Schs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 291.1Schs * POSSIBILITY OF SUCH DAMAGE. 301.1Schs */ 311.1Schs 321.1Schs#include <sys/cdefs.h> 331.1Schs#if defined(LIBC_SCCS) && !defined(lint) 341.8Sriastrad__RCSID("$NetBSD: makecontext.c,v 1.8 2025/04/25 01:18:51 riastradh Exp $"); 351.1Schs#endif 361.1Schs 371.8Sriastrad#include <sys/param.h> 381.7Sriastrad#include <sys/types.h> 391.7Sriastrad 401.7Sriastrad#include <machine/frame.h> 411.7Sriastrad 421.1Schs#include <inttypes.h> 431.7Sriastrad#include <stdarg.h> 441.1Schs#include <stddef.h> 451.1Schs#include <ucontext.h> 461.7Sriastrad 471.1Schs#include "extern.h" 481.1Schs 491.5Sjoergvoid __resumecontext(void) __dead; 501.5Sjoerg 511.1Schsvoid 521.1Schsmakecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) 531.1Schs{ 541.1Schs __greg_t *gr = ucp->uc_mcontext.__gregs; 551.1Schs __greg_t *gp, rp, fp; 561.2Sperry register __greg_t dp __asm("r27"); 571.1Schs uintptr_t *sp; 581.1Schs int i; 591.1Schs va_list ap; 601.1Schs 611.1Schs /* LINTED uintptr_t is safe */ 621.1Schs sp = (uintptr_t *)ucp->uc_stack.ss_sp; 631.1Schs /* LINTED uintptr_t is safe */ 641.1Schs sp += 16; /* standard frame */ 651.1Schs sp += (argc >= 4 ? argc : 4); /* Make room for >=4 arguments. */ 661.8Sriastrad sp = (uintptr_t *) /* Align on 64-byte boundary. */ 671.8Sriastrad (((uintptr_t)sp + STACK_ALIGNBYTES) & ~STACK_ALIGNBYTES); 681.1Schs 691.1Schs /* Save away the registers that we'll need. */ 701.1Schs gr[_REG_SP] = (__greg_t)sp; 711.1Schs rp = (__greg_t)__resumecontext; 721.1Schs if (rp & 2) { 731.1Schs gp = (__greg_t *)(rp & ~3); 741.1Schs rp = gp[0]; 751.1Schs sp[-8] = gp[1]; 761.1Schs } 771.1Schs gr[_REG_RP] = rp; 781.1Schs fp = (__greg_t)func; 791.1Schs if (fp & 2) { 801.1Schs gp = (__greg_t *)(fp & ~3); 811.1Schs fp = gp[0]; 821.1Schs gr[_REG_R19] = gp[1]; 831.1Schs } 841.1Schs gr[_REG_PCOQH] = fp | HPPA_PC_PRIV_USER; 851.1Schs gr[_REG_PCOQT] = (fp + 4) | HPPA_PC_PRIV_USER; 861.6Sskrll /* LINTED dp is reg27, ref. above, so initialized */ 871.1Schs gr[_REG_DP] = dp; 881.1Schs 891.1Schs /* Construct argument list. */ 901.1Schs va_start(ap, argc); 911.1Schs /* Up to the first four arguments are passed in %arg0-3. */ 921.1Schs for (i = 0; i < argc && i < 4; i++) { 931.1Schs /* LINTED uintptr_t is safe */ 941.1Schs gr[_REG_ARG0 - i] = va_arg(ap, uintptr_t); 951.1Schs } 961.1Schs /* Pass remaining arguments on the stack below the %arg0-3 gap. */ 971.1Schs for (; i < argc; i++) { 981.1Schs /* LINTED uintptr_t is safe */ 991.1Schs sp[-9 - i] = va_arg(ap, uintptr_t); 1001.1Schs } 1011.1Schs va_end(ap); 1021.1Schs} 103