1/* Create new context. 2 Copyright (C) 2005-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 <abort-instr.h> 21 22#include "ucontext_i.h" 23 24/* void __makecontext (ucontext_t *ucp, void (*func)(), int argc, ...); 25 __makecontext sets up a stack and registers for context to run a given 26 function. The registers are set up like this: 27 r4-r7: parameters 1 to 4 28 r8 : uc_link from ucontext structure 29 pc : (*func) pointer 30 pr : address of exitcode 31 r15 : stack pointer for func. */ 32 33 .text 34 .align 5 35ENTRY(__makecontext) 36 mov #4, r3 37 mov.l @(oSS_SP,r4), r1 /* r1 <- ucb->stack_base */ 38 mov.l @(oSS_SIZE,r4), r2 /* r2 <- ucb->stack_size */ 39 add r1, r2 /* r2 <- stack_top */ 40 cmp/gt r3, r6 /* argc > 4? */ 41 bf/s 1f 42 shlr2 r2 /* r2 <- stack_top / 4 */ 43 sub r6, r2 44 add r3, r2 451: 46 shll2 r2 /* r2 <- stack_top - ((argc > 4) ? 4 * (argc - 4) : 0 */ 47 mov #oR15, r0 48 mov.l @(oLINK,r4), r1 49 mov.l r2, @(r0,r4) /* ucp->r15 <- r2 */ 50 mov.l r1, @(oR8,r4) /* ucp->r8 <- ucp->uc_link */ 51 mov #oPC, r0 52 mov.l r5, @(r0,r4) /* ucp->PC <- func */ 53 54 cmp/pl r6 /* argc > 0? */ 55 bf/s .L1 56 dt r6 57 mov.l r7, @(oR4,r4) /* ucp->r4 <- argv[0] */ 58 cmp/pl r6 /* argc > 1? */ 59 bf/s .L1 60 dt r6 61 mov.l @(0,r15), r1 62 mov.l r1, @(oR5,r4) /* ucp->r5 <- argv[1] */ 63 cmp/pl r6 /* argc > 2? */ 64 bf/s .L1 65 dt r6 66 mov.l @(4,r15), r1 67 mov.l r1, @(oR6,r4) /* ucp->r6 <- argv[2] */ 68 cmp/pl r6 /* argc > 3? */ 69 bf/s .L1 70 dt r6 71 mov.l @(8,r15), r1 72 mov.l r1, @(oR7,r4) /* ucp->r7 <- argv[3] */ 73 mov #12,r0 74.L0: /* Save remaining argv[] on the stack. */ 75 cmp/pl r6 76 bf/s .L1 77 dt r6 78 mov.l @(r0,r15), r1 79 mov.l r1, @r2 80 add #4, r0 81 bra .L0 82 add #4, r2 83.L1: 84#ifdef PIC 85 mova .Lexitcode, r0 86#else 87 mov.l .L2, r0 88#endif 89 add #oPR, r4 90 rts 91 mov.l r0, @r4 /* ucp->pr <- exitcode */ 92#ifndef PIC 93 .align 2 94.L2: 95 .long .Lexitcode 96#endif 97 cfi_endproc 98 99 .align 5 100 cfi_startproc 101.Lexitcode: 102#ifdef PIC 103 mov.l r12, @-r15 104 cfi_adjust_cfa_offset (4) 105 cfi_rel_offset (r12, 0) 106 mova .Lgot, r0 107 mov.l .Lgot, r12 108 add r0, r12 109#endif 110 tst r8, r8 /* ucb->uc_link == NULL? */ 111 bt/s 2f 112 mov r8, r4 /* r4 <- ucb->uc_link */ 113 mov.l .Lsetcontext, r1 114 sts.l pr, @-r15 115 cfi_adjust_cfa_offset (4) 116 cfi_rel_offset (pr, 0) 117#ifdef PIC 118 bsrf r1 119.LPCS0: 120 nop 121#else 122 jsr @r1 123 nop 124#endif 125 /* Restore to keep CFI/CFA balanced. */ 126 lds.l @r15+, pr 127 cfi_adjust_cfa_offset (-4) 128 cfi_restore (pr) 129 /* If this returns (which can happen if the syscall fails) we'll exit 130 the program with the return error value (-1). */ 131 mov r0, r4 132 1332: 134 mov.l .Lexit, r1 135#ifdef PIC 136 add r12, r1 137#endif 138 jsr @r1 139 nop 140 /* The 'exit' call should never return. In case it does cause the 141 process to terminate. */ 142 ABORT_INSTRUCTION_ASM 143 144 .align 2 145#ifdef PIC 146.Lgot: 147 .long _GLOBAL_OFFSET_TABLE_ 148.Lsetcontext: 149 .long __setcontext@PLT-(.LPCS0+2-(.)) 150.Lexit: 151 .long HIDDEN_JUMPTARGET(exit)@GOTOFF 152#else 153.Lsetcontext: 154 .long __setcontext 155.Lexit: 156 .long HIDDEN_JUMPTARGET(exit) 157#endif 158PSEUDO_END(__makecontext) 159 160weak_alias (__makecontext, makecontext) 161