]>
Commit | Line | Data |
---|---|---|
76e95c88 | 1 | /* Create new context. |
688903eb | 2 | Copyright (C) 2005-2018 Free Software Foundation, Inc. |
76e95c88 UD |
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 | |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
76e95c88 UD |
18 | |
19 | #include <sysdep.h> | |
967705fe | 20 | #include <abort-instr.h> |
76e95c88 UD |
21 | |
22 | #include "ucontext_i.h" | |
23 | ||
25128773 | 24 | /* void __makecontext (ucontext_t *ucp, void (*func)(), int argc, ...); |
76e95c88 UD |
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 | |
76e95c88 UD |
35 | ENTRY(__makecontext) |
36 | mov #4, r3 | |
af1bce34 TS |
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 */ | |
2a649725 | 40 | cmp/gt r3, r6 /* argc > 4? */ |
76e95c88 | 41 | bf/s 1f |
af1bce34 | 42 | shlr2 r2 /* r2 <- stack_top / 4 */ |
76e95c88 UD |
43 | sub r6, r2 |
44 | add r3, r2 | |
45 | 1: | |
af1bce34 | 46 | shll2 r2 /* r2 <- stack_top - ((argc > 4) ? 4 * (argc - 4) : 0 */ |
76e95c88 UD |
47 | mov #oR15, r0 |
48 | mov.l @(oLINK,r4), r1 | |
af1bce34 TS |
49 | mov.l r2, @(r0,r4) /* ucp->r15 <- r2 */ |
50 | mov.l r1, @(oR8,r4) /* ucp->r8 <- ucp->uc_link */ | |
76e95c88 | 51 | mov #oPC, r0 |
af1bce34 | 52 | mov.l r5, @(r0,r4) /* ucp->PC <- func */ |
76e95c88 | 53 | |
af1bce34 | 54 | cmp/pl r6 /* argc > 0? */ |
76e95c88 UD |
55 | bf/s .L1 |
56 | dt r6 | |
af1bce34 TS |
57 | mov.l r7, @(oR4,r4) /* ucp->r4 <- argv[0] */ |
58 | cmp/pl r6 /* argc > 1? */ | |
76e95c88 UD |
59 | bf/s .L1 |
60 | dt r6 | |
61 | mov.l @(0,r15), r1 | |
af1bce34 TS |
62 | mov.l r1, @(oR5,r4) /* ucp->r5 <- argv[1] */ |
63 | cmp/pl r6 /* argc > 2? */ | |
76e95c88 UD |
64 | bf/s .L1 |
65 | dt r6 | |
66 | mov.l @(4,r15), r1 | |
af1bce34 TS |
67 | mov.l r1, @(oR6,r4) /* ucp->r6 <- argv[2] */ |
68 | cmp/pl r6 /* argc > 3? */ | |
76e95c88 UD |
69 | bf/s .L1 |
70 | dt r6 | |
71 | mov.l @(8,r15), r1 | |
af1bce34 | 72 | mov.l r1, @(oR7,r4) /* ucp->r7 <- argv[3] */ |
76e95c88 | 73 | mov #12,r0 |
af1bce34 | 74 | .L0: /* Save remaining argv[] on the stack. */ |
76e95c88 UD |
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 | |
af1bce34 | 91 | mov.l r0, @r4 /* ucp->pr <- exitcode */ |
76e95c88 UD |
92 | #ifndef PIC |
93 | .align 2 | |
94 | .L2: | |
95 | .long .Lexitcode | |
96 | #endif | |
97 | cfi_endproc | |
98 | ||
99 | .align 5 | |
58f902b8 | 100 | cfi_startproc |
76e95c88 | 101 | .Lexitcode: |
76e95c88 | 102 | #ifdef PIC |
58f902b8 TS |
103 | mov.l r12, @-r15 |
104 | cfi_adjust_cfa_offset (4) | |
105 | cfi_rel_offset (r12, 0) | |
76e95c88 UD |
106 | mova .Lgot, r0 |
107 | mov.l .Lgot, r12 | |
108 | add r0, r12 | |
a9def8c4 TS |
109 | #endif |
110 | tst r8, r8 /* ucb->uc_link == NULL? */ | |
111 | bt/s 2f | |
112 | mov r8, r4 /* r4 <- ucb->uc_link */ | |
af1bce34 | 113 | mov.l .Lsetcontext, r1 |
58f902b8 TS |
114 | sts.l pr, @-r15 |
115 | cfi_adjust_cfa_offset (4) | |
116 | cfi_rel_offset (pr, 0) | |
a9def8c4 | 117 | #ifdef PIC |
76e95c88 UD |
118 | bsrf r1 |
119 | .LPCS0: | |
120 | nop | |
121 | #else | |
76e95c88 UD |
122 | jsr @r1 |
123 | nop | |
124 | #endif | |
58f902b8 TS |
125 | /* Restore to keep CFI/CFA balanced. */ |
126 | lds.l @r15+, pr | |
127 | cfi_adjust_cfa_offset (-4) | |
128 | cfi_restore (pr) | |
a9def8c4 TS |
129 | /* If this returns (which can happen if the syscall fails) we'll exit |
130 | the program with the return error value (-1). */ | |
07cbfc23 | 131 | mov r0, r4 |
a9def8c4 | 132 | |
76e95c88 | 133 | 2: |
af1bce34 | 134 | mov.l .Lexit, r1 |
76e95c88 UD |
135 | #ifdef PIC |
136 | add r12, r1 | |
137 | #endif | |
138 | jsr @r1 | |
07cbfc23 | 139 | nop |
967705fe TS |
140 | /* The 'exit' call should never return. In case it does cause the |
141 | process to terminate. */ | |
142 | ABORT_INSTRUCTION_ASM | |
76e95c88 UD |
143 | |
144 | .align 2 | |
145 | #ifdef PIC | |
146 | .Lgot: | |
147 | .long _GLOBAL_OFFSET_TABLE_ | |
af1bce34 | 148 | .Lsetcontext: |
76e95c88 | 149 | .long __setcontext@PLT-(.LPCS0+2-(.)) |
af1bce34 | 150 | .Lexit: |
76e95c88 UD |
151 | .long HIDDEN_JUMPTARGET(exit)@GOTOFF |
152 | #else | |
af1bce34 | 153 | .Lsetcontext: |
76e95c88 | 154 | .long __setcontext |
af1bce34 | 155 | .Lexit: |
76e95c88 UD |
156 | .long HIDDEN_JUMPTARGET(exit) |
157 | #endif | |
158 | PSEUDO_END(__makecontext) | |
159 | ||
160 | weak_alias (__makecontext, makecontext) |