1/* Modify saved context. 2 Copyright (C) 2009-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library. If not, see 17 <https://www.gnu.org/licenses/>. */ 18 19#include <sysdep.h> 20#include <sys/asm.h> 21#include <sys/fpregdef.h> 22#include <sys/regdef.h> 23 24#include "ucontext_i.h" 25 26/* int makecontext (ucontext_t *ucp, (void *func) (), int argc, ...) */ 27 28 .text 29 .set nomips16 30LOCALSZ = 0 31ARGSZ = 0 32MASK = 0x00000000 33#ifdef __PIC__ 34LOCALSZ = 1 /* save gp */ 35#endif 36#if _MIPS_SIM != _ABIO32 37ARGSZ = 5 /* save a3-a7 */ 38# ifdef __PIC__ 39MASK = 0x10000000 40# endif 41#endif 42FRAMESZ = (((ARGSZ + LOCALSZ) * SZREG) + ALSZ) & ALMASK 43GPOFF = FRAMESZ - ((ARGSZ + 1) * SZREG) 44#if _MIPS_SIM != _ABIO32 45A3OFF = FRAMESZ - (5 * SZREG) /* callee-allocated */ 46A4OFF = FRAMESZ - (4 * SZREG) 47A5OFF = FRAMESZ - (3 * SZREG) 48A6OFF = FRAMESZ - (2 * SZREG) 49A7OFF = FRAMESZ - (1 * SZREG) 50NARGREGS = 8 51#else 52A3OFF = FRAMESZ + (3 * SZREG) /* caller-allocated */ 53NARGREGS = 4 54#endif 55MCONTEXT_GREGSZ = 8 56#if _MIPS_SIM == _ABIO32 && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 57MCONTEXT_GREGOFF = 4 58#else 59MCONTEXT_GREGOFF = 0 60#endif 61 62NESTED (__makecontext, FRAMESZ, ra) 63 .mask MASK, -(ARGSZ * SZREG) 64 .fmask 0x00000000, 0 65 6698: 67#ifdef __PIC__ 68 SETUP_GP 69#endif 70 71 PTR_ADDIU sp, -FRAMESZ 72 cfi_adjust_cfa_offset (FRAMESZ) 73 74#ifdef __PIC__ 75 SETUP_GP64_STACK (GPOFF, __makecontext) 76 SAVE_GP (GPOFF) 77#endif 78 79#ifdef PROF 80 .set noat 81 move AT, ra 82 jal _mcount 83 .set at 84#endif 85 86 /* Store args to be passed. */ 87 REG_S a3, A3OFF(sp) 88#if _MIPS_SIM != _ABIO32 89 REG_S a4, A4OFF(sp) 90 REG_S a5, A5OFF(sp) 91 REG_S a6, A6OFF(sp) 92 REG_S a7, A7OFF(sp) 93#endif 94 95 /* Set up the stack. */ 96 PTR_L t0, STACK_SP(a0) 97 PTR_L t2, STACK_SIZE(a0) 98 PTR_ADDIU t1, sp, A3OFF 99 PTR_ADDU t0, t2 100 and t0, ALMASK 101 blez a2, 2f /* no arguments */ 102 103 /* Store register arguments. */ 104 PTR_ADDIU t2, a0, MCONTEXT_GREGS + 4 * MCONTEXT_GREGSZ + MCONTEXT_GREGOFF 105 move t3, zero 1060: 107 addiu t3, 1 108 REG_L v1, (t1) 109 PTR_ADDIU t1, SZREG 110 REG_S v1, (t2) 111 PTR_ADDIU t2, MCONTEXT_GREGSZ 112 bgeu t3, a2, 2f /* all done */ 113 bltu t3, NARGREGS, 0b /* next */ 114 115 /* Make room for stack arguments. */ 116 PTR_SUBU t2, a2, t3 117 PTR_SLL t2, 3 118 PTR_SUBU t0, t2 119 and t0, ALMASK 120 121 /* Store stack arguments. */ 122 move t2, t0 1231: 124 addiu t3, 1 125 REG_L v1, (t1) 126 PTR_ADDIU t1, SZREG 127 REG_S v1, (t2) 128 PTR_ADDIU t2, SZREG 129 bltu t3, a2, 1b /* next */ 130 1312: 132#if _MIPS_SIM == _ABIO32 133 /* Make room for a0-a3 storage. */ 134 PTR_ADDIU t0, -(NARGSAVE * SZREG) 135#endif 136 PTR_L v1, UCONTEXT_LINK(a0) 137#ifdef __PIC__ 138 PTR_ADDIU t9, 99f - 98b 139#else 140 PTR_LA t9, 99f 141#endif 142 /* sp */ 143 REG_S t0, (MCONTEXT_GREGOFF + 29 * MCONTEXT_GREGSZ + MCONTEXT_GREGS)(a0) 144 /* s0 */ 145 REG_S v1, (MCONTEXT_GREGOFF + 16 * MCONTEXT_GREGSZ + MCONTEXT_GREGS)(a0) 146#ifdef __PIC__ 147 /* s1 */ 148 REG_S gp, (MCONTEXT_GREGOFF + 17 * MCONTEXT_GREGSZ + MCONTEXT_GREGS)(a0) 149#endif 150 /* ra */ 151 REG_S t9, (MCONTEXT_GREGOFF + 31 * MCONTEXT_GREGSZ + MCONTEXT_GREGS)(a0) 152 REG_S a1, (MCONTEXT_GREGOFF + MCONTEXT_PC)(a0) 153 154#ifdef __PIC__ 155 RESTORE_GP64_STACK 156 PTR_ADDIU sp, FRAMESZ 157 cfi_adjust_cfa_offset (-FRAMESZ) 158#endif 159 jr ra 160 161 /* We need to terminate the FDE to stop unwinding if backtrace was 162 called within a context created by makecontext. */ 163 cfi_endproc 164 nop 165 16699: 167#ifdef __PIC__ 168 move gp, s1 169#endif 170 move a0, zero 171 beqz s0, 0f 172 173 /* setcontext (ucp) */ 174 move a0, s0 175#ifdef __PIC__ 176 PTR_LA t9, JUMPTARGET (__setcontext) 177 jalr t9 178# if _MIPS_SIM == _ABIO32 179 move gp, s1 180# endif 181#else 182 jal JUMPTARGET (__setcontext) 183#endif 184 move a0, v0 185 1860: 187 /* exit (a0) */ 188#ifdef __PIC__ 189 PTR_LA t9, HIDDEN_JUMPTARGET (exit) 190 jalr t9 191#else 192 jal HIDDEN_JUMPTARGET (exit) 193#endif 194 195 /* You don't exist, you won't feel anything. */ 1961: 197 lb zero, (zero) 198 b 1b 199 200 cfi_startproc 201PSEUDO_END (__makecontext) 202 203weak_alias (__makecontext, makecontext) 204