makecontext.c revision 1.7
11.7Sriastrad/* $NetBSD: makecontext.c,v 1.7 2025/04/25 01:17:11 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.7Sriastrad__RCSID("$NetBSD: makecontext.c,v 1.7 2025/04/25 01:17:11 riastradh Exp $"); 351.1Schs#endif 361.1Schs 371.7Sriastrad#include <sys/types.h> 381.7Sriastrad 391.7Sriastrad#include <machine/frame.h> 401.7Sriastrad 411.1Schs#include <inttypes.h> 421.7Sriastrad#include <stdarg.h> 431.1Schs#include <stddef.h> 441.1Schs#include <ucontext.h> 451.7Sriastrad 461.1Schs#include "extern.h" 471.1Schs 481.5Sjoergvoid __resumecontext(void) __dead; 491.5Sjoerg 501.1Schsvoid 511.1Schsmakecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) 521.1Schs{ 531.1Schs __greg_t *gr = ucp->uc_mcontext.__gregs; 541.1Schs __greg_t *gp, rp, fp; 551.2Sperry register __greg_t dp __asm("r27"); 561.1Schs uintptr_t *sp; 571.1Schs int i; 581.1Schs va_list ap; 591.1Schs 601.1Schs /* LINTED uintptr_t is safe */ 611.1Schs sp = (uintptr_t *)ucp->uc_stack.ss_sp; 621.1Schs /* LINTED uintptr_t is safe */ 631.1Schs sp += 16; /* standard frame */ 641.1Schs sp += (argc >= 4 ? argc : 4); /* Make room for >=4 arguments. */ 651.1Schs sp = (uintptr_t *) 661.1Schs ((uintptr_t)(sp + 16) & ~0x3f); /* Align on 64-byte boundary. */ 671.1Schs 681.1Schs /* Save away the registers that we'll need. */ 691.1Schs gr[_REG_SP] = (__greg_t)sp; 701.1Schs rp = (__greg_t)__resumecontext; 711.1Schs if (rp & 2) { 721.1Schs gp = (__greg_t *)(rp & ~3); 731.1Schs rp = gp[0]; 741.1Schs sp[-8] = gp[1]; 751.1Schs } 761.1Schs gr[_REG_RP] = rp; 771.1Schs fp = (__greg_t)func; 781.1Schs if (fp & 2) { 791.1Schs gp = (__greg_t *)(fp & ~3); 801.1Schs fp = gp[0]; 811.1Schs gr[_REG_R19] = gp[1]; 821.1Schs } 831.1Schs gr[_REG_PCOQH] = fp | HPPA_PC_PRIV_USER; 841.1Schs gr[_REG_PCOQT] = (fp + 4) | HPPA_PC_PRIV_USER; 851.6Sskrll /* LINTED dp is reg27, ref. above, so initialized */ 861.1Schs gr[_REG_DP] = dp; 871.1Schs 881.1Schs /* Construct argument list. */ 891.1Schs va_start(ap, argc); 901.1Schs /* Up to the first four arguments are passed in %arg0-3. */ 911.1Schs for (i = 0; i < argc && i < 4; i++) { 921.1Schs /* LINTED uintptr_t is safe */ 931.1Schs gr[_REG_ARG0 - i] = va_arg(ap, uintptr_t); 941.1Schs } 951.1Schs /* Pass remaining arguments on the stack below the %arg0-3 gap. */ 961.1Schs for (; i < argc; i++) { 971.1Schs /* LINTED uintptr_t is safe */ 981.1Schs sp[-9 - i] = va_arg(ap, uintptr_t); 991.1Schs } 1001.1Schs va_end(ap); 1011.1Schs} 102