]>
Commit | Line | Data |
---|---|---|
4cb4721f | 1 | # s390 support for -fsplit-stack. |
83ffe9cd | 2 | # Copyright (C) 2015-2023 Free Software Foundation, Inc. |
4cb4721f MK |
3 | # Contributed by Marcin Kościelnicki <koriakin@0x04.net>. |
4 | ||
5 | # This file is part of GCC. | |
6 | ||
7 | # GCC is free software; you can redistribute it and/or modify it under | |
8 | # the terms of the GNU General Public License as published by the Free | |
9 | # Software Foundation; either version 3, or (at your option) any later | |
10 | # version. | |
11 | ||
12 | # GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | # for more details. | |
16 | ||
17 | # Under Section 7 of GPL version 3, you are granted additional | |
18 | # permissions described in the GCC Runtime Library Exception, version | |
19 | # 3.1, as published by the Free Software Foundation. | |
20 | ||
21 | # You should have received a copy of the GNU General Public License and | |
22 | # a copy of the GCC Runtime Library Exception along with this program; | |
23 | # see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
24 | # <http://www.gnu.org/licenses/>. | |
25 | ||
26 | # Excess space needed to call ld.so resolver for lazy plt | |
27 | # resolution. Go uses sigaltstack so this doesn't need to | |
28 | # also cover signal frame size. | |
29 | #define BACKOFF 0x1000 | |
30 | ||
f49e3d28 ILT |
31 | #include <auto-host.h> |
32 | ||
4cb4721f MK |
33 | # The __morestack function. |
34 | ||
35 | .global __morestack | |
36 | .hidden __morestack | |
37 | ||
38 | .type __morestack,@function | |
39 | ||
40 | __morestack: | |
41 | .LFB1: | |
42 | .cfi_startproc | |
43 | ||
44 | ||
45 | #ifndef __s390x__ | |
46 | ||
47 | ||
48 | # The 31-bit __morestack function. | |
49 | ||
50 | # We use a cleanup to restore the stack guard if an exception | |
51 | # is thrown through this code. | |
52 | #ifndef __PIC__ | |
53 | .cfi_personality 0,__gcc_personality_v0 | |
54 | .cfi_lsda 0,.LLSDA1 | |
55 | #else | |
56 | .cfi_personality 0x9b,DW.ref.__gcc_personality_v0 | |
57 | .cfi_lsda 0x1b,.LLSDA1 | |
58 | #endif | |
59 | ||
60 | stm %r2, %r15, 0x8(%r15) # Save %r2-%r15. | |
61 | .cfi_offset %r6, -0x48 | |
62 | .cfi_offset %r7, -0x44 | |
63 | .cfi_offset %r8, -0x40 | |
64 | .cfi_offset %r9, -0x3c | |
65 | .cfi_offset %r10, -0x38 | |
66 | .cfi_offset %r11, -0x34 | |
67 | .cfi_offset %r12, -0x30 | |
68 | .cfi_offset %r13, -0x2c | |
69 | .cfi_offset %r14, -0x28 | |
70 | .cfi_offset %r15, -0x24 | |
71 | lr %r11, %r15 # Make frame pointer for vararg. | |
72 | .cfi_def_cfa_register %r11 | |
73 | ahi %r15, -0x60 # 0x60 for standard frame. | |
74 | st %r11, 0(%r15) # Save back chain. | |
75 | lr %r8, %r0 # Save %r0 (static chain). | |
76 | lr %r10, %r1 # Save %r1 (address of parameter block). | |
77 | ||
78 | l %r7, 0(%r10) # Required frame size to %r7 | |
79 | ear %r1, %a0 # Extract thread pointer. | |
80 | l %r1, 0x20(%r1) # Get stack bounduary | |
81 | ar %r1, %r7 # Stack bounduary + frame size | |
82 | a %r1, 4(%r10) # + stack param size | |
83 | clr %r1, %r15 # Compare with current stack pointer | |
84 | jle .Lnoalloc # guard > sp - frame-size: need alloc | |
85 | ||
86 | brasl %r14, __morestack_block_signals | |
87 | ||
88 | # We abuse one of caller's fpr save slots (which we don't use for fprs) | |
89 | # as a local variable. Not needed here, but done to be consistent with | |
90 | # the below use. | |
91 | ahi %r7, BACKOFF # Bump requested size a bit. | |
92 | st %r7, 0x40(%r11) # Stuff frame size on stack. | |
93 | la %r2, 0x40(%r11) # Pass its address as parameter. | |
94 | la %r3, 0x60(%r11) # Caller's stack parameters. | |
95 | l %r4, 4(%r10) # Size of stack parameters. | |
96 | brasl %r14, __generic_morestack | |
97 | ||
98 | lr %r15, %r2 # Switch to the new stack. | |
99 | ahi %r15, -0x60 # Make a stack frame on it. | |
100 | st %r11, 0(%r15) # Save back chain. | |
101 | ||
102 | s %r2, 0x40(%r11) # The end of stack space. | |
103 | ahi %r2, BACKOFF # Back off a bit. | |
104 | ear %r1, %a0 # Extract thread pointer. | |
105 | .LEHB0: | |
106 | st %r2, 0x20(%r1) # Save the new stack boundary. | |
107 | ||
108 | brasl %r14, __morestack_unblock_signals | |
109 | ||
110 | lr %r0, %r8 # Static chain. | |
111 | lm %r2, %r6, 0x8(%r11) # Paremeter registers. | |
112 | ||
113 | # Third parameter is address of function meat - address of parameter | |
114 | # block. | |
115 | a %r10, 0x8(%r10) | |
116 | ||
117 | # Leave vararg pointer in %r1, in case function uses it | |
118 | la %r1, 0x60(%r11) | |
119 | ||
120 | # State of registers: | |
121 | # %r0: Static chain from entry. | |
122 | # %r1: Vararg pointer. | |
123 | # %r2-%r6: Parameters from entry. | |
124 | # %r7-%r10: Indeterminate. | |
125 | # %r11: Frame pointer (%r15 from entry). | |
126 | # %r12-%r13: Indeterminate. | |
127 | # %r14: Return address. | |
128 | # %r15: Stack pointer. | |
129 | basr %r14, %r10 # Call our caller. | |
130 | ||
131 | stm %r2, %r3, 0x8(%r11) # Save return registers. | |
132 | ||
133 | brasl %r14, __morestack_block_signals | |
134 | ||
135 | # We need a stack slot now, but have no good way to get it - the frame | |
136 | # on new stack had to be exactly 0x60 bytes, or stack parameters would | |
137 | # be passed wrong. Abuse fpr save area in caller's frame (we don't | |
138 | # save actual fprs). | |
139 | la %r2, 0x40(%r11) | |
140 | brasl %r14, __generic_releasestack | |
141 | ||
142 | s %r2, 0x40(%r11) # Subtract available space. | |
143 | ahi %r2, BACKOFF # Back off a bit. | |
144 | ear %r1, %a0 # Extract thread pointer. | |
145 | .LEHE0: | |
146 | st %r2, 0x20(%r1) # Save the new stack boundary. | |
147 | ||
148 | # We need to restore the old stack pointer before unblocking signals. | |
149 | # We also need 0x60 bytes for a stack frame. Since we had a stack | |
150 | # frame at this place before the stack switch, there's no need to | |
151 | # write the back chain again. | |
152 | lr %r15, %r11 | |
153 | ahi %r15, -0x60 | |
154 | ||
155 | brasl %r14, __morestack_unblock_signals | |
156 | ||
157 | lm %r2, %r15, 0x8(%r11) # Restore all registers. | |
158 | .cfi_remember_state | |
159 | .cfi_restore %r15 | |
160 | .cfi_restore %r14 | |
161 | .cfi_restore %r13 | |
162 | .cfi_restore %r12 | |
163 | .cfi_restore %r11 | |
164 | .cfi_restore %r10 | |
165 | .cfi_restore %r9 | |
166 | .cfi_restore %r8 | |
167 | .cfi_restore %r7 | |
168 | .cfi_restore %r6 | |
169 | .cfi_def_cfa_register %r15 | |
170 | br %r14 # Return to caller's caller. | |
171 | ||
172 | # Executed if no new stack allocation is needed. | |
173 | ||
174 | .Lnoalloc: | |
175 | .cfi_restore_state | |
176 | # We may need to copy stack parameters. | |
177 | l %r9, 0x4(%r10) # Load stack parameter size. | |
178 | ltr %r9, %r9 # And check if it's 0. | |
179 | je .Lnostackparm # Skip the copy if not needed. | |
180 | sr %r15, %r9 # Make space on the stack. | |
181 | la %r8, 0x60(%r15) # Destination. | |
182 | la %r12, 0x60(%r11) # Source. | |
183 | lr %r13, %r9 # Source size. | |
184 | .Lcopy: | |
185 | mvcle %r8, %r12, 0 # Copy. | |
186 | jo .Lcopy | |
187 | ||
188 | .Lnostackparm: | |
189 | # Third parameter is address of function meat - address of parameter | |
190 | # block. | |
191 | a %r10, 0x8(%r10) | |
192 | ||
193 | # Leave vararg pointer in %r1, in case function uses it | |
194 | la %r1, 0x60(%r11) | |
195 | ||
196 | # OK, no stack allocation needed. We still follow the protocol and | |
197 | # call our caller - it doesn't cost much and makes sure vararg works. | |
198 | # No need to set any registers here - %r0 and %r2-%r6 weren't modified. | |
199 | basr %r14, %r10 # Call our caller. | |
200 | ||
201 | lm %r6, %r15, 0x18(%r11) # Restore all callee-saved registers. | |
202 | .cfi_remember_state | |
203 | .cfi_restore %r15 | |
204 | .cfi_restore %r14 | |
205 | .cfi_restore %r13 | |
206 | .cfi_restore %r12 | |
207 | .cfi_restore %r11 | |
208 | .cfi_restore %r10 | |
209 | .cfi_restore %r9 | |
210 | .cfi_restore %r8 | |
211 | .cfi_restore %r7 | |
212 | .cfi_restore %r6 | |
213 | .cfi_def_cfa_register %r15 | |
214 | br %r14 # Return to caller's caller. | |
215 | ||
216 | # This is the cleanup code called by the stack unwinder when unwinding | |
217 | # through the code between .LEHB0 and .LEHE0 above. | |
218 | ||
219 | .L1: | |
220 | .cfi_restore_state | |
221 | lr %r2, %r11 # Stack pointer after resume. | |
222 | brasl %r14, __generic_findstack | |
223 | lr %r3, %r11 # Get the stack pointer. | |
224 | sr %r3, %r2 # Subtract available space. | |
225 | ahi %r3, BACKOFF # Back off a bit. | |
226 | ear %r1, %a0 # Extract thread pointer. | |
227 | st %r3, 0x20(%r1) # Save the new stack boundary. | |
228 | ||
229 | # We need GOT pointer in %r12 for PLT entry. | |
230 | larl %r12,_GLOBAL_OFFSET_TABLE_ | |
231 | lr %r2, %r6 # Exception header. | |
232 | #ifdef __PIC__ | |
233 | brasl %r14, _Unwind_Resume@PLT | |
234 | #else | |
235 | brasl %r14, _Unwind_Resume | |
236 | #endif | |
237 | ||
238 | #else /* defined(__s390x__) */ | |
239 | ||
240 | ||
241 | # The 64-bit __morestack function. | |
242 | ||
243 | # We use a cleanup to restore the stack guard if an exception | |
244 | # is thrown through this code. | |
245 | #ifndef __PIC__ | |
246 | .cfi_personality 0x3,__gcc_personality_v0 | |
247 | .cfi_lsda 0x3,.LLSDA1 | |
248 | #else | |
249 | .cfi_personality 0x9b,DW.ref.__gcc_personality_v0 | |
250 | .cfi_lsda 0x1b,.LLSDA1 | |
251 | #endif | |
252 | ||
253 | stmg %r2, %r15, 0x10(%r15) # Save %r2-%r15. | |
254 | .cfi_offset %r6, -0x70 | |
255 | .cfi_offset %r7, -0x68 | |
256 | .cfi_offset %r8, -0x60 | |
257 | .cfi_offset %r9, -0x58 | |
258 | .cfi_offset %r10, -0x50 | |
259 | .cfi_offset %r11, -0x48 | |
260 | .cfi_offset %r12, -0x40 | |
261 | .cfi_offset %r13, -0x38 | |
262 | .cfi_offset %r14, -0x30 | |
263 | .cfi_offset %r15, -0x28 | |
264 | lgr %r11, %r15 # Make frame pointer for vararg. | |
265 | .cfi_def_cfa_register %r11 | |
266 | aghi %r15, -0xa0 # 0xa0 for standard frame. | |
267 | stg %r11, 0(%r15) # Save back chain. | |
268 | lgr %r8, %r0 # Save %r0 (static chain). | |
269 | lgr %r10, %r1 # Save %r1 (address of parameter block). | |
270 | ||
271 | lg %r7, 0(%r10) # Required frame size to %r7 | |
272 | ear %r1, %a0 | |
273 | sllg %r1, %r1, 32 | |
274 | ear %r1, %a1 # Extract thread pointer. | |
275 | lg %r1, 0x38(%r1) # Get stack bounduary | |
276 | agr %r1, %r7 # Stack bounduary + frame size | |
277 | ag %r1, 8(%r10) # + stack param size | |
278 | clgr %r1, %r15 # Compare with current stack pointer | |
279 | jle .Lnoalloc # guard > sp - frame-size: need alloc | |
280 | ||
281 | brasl %r14, __morestack_block_signals | |
282 | ||
283 | # We abuse one of caller's fpr save slots (which we don't use for fprs) | |
284 | # as a local variable. Not needed here, but done to be consistent with | |
285 | # the below use. | |
286 | aghi %r7, BACKOFF # Bump requested size a bit. | |
287 | stg %r7, 0x80(%r11) # Stuff frame size on stack. | |
288 | la %r2, 0x80(%r11) # Pass its address as parameter. | |
289 | la %r3, 0xa0(%r11) # Caller's stack parameters. | |
290 | lg %r4, 8(%r10) # Size of stack parameters. | |
291 | brasl %r14, __generic_morestack | |
292 | ||
293 | lgr %r15, %r2 # Switch to the new stack. | |
294 | aghi %r15, -0xa0 # Make a stack frame on it. | |
295 | stg %r11, 0(%r15) # Save back chain. | |
296 | ||
297 | sg %r2, 0x80(%r11) # The end of stack space. | |
298 | aghi %r2, BACKOFF # Back off a bit. | |
299 | ear %r1, %a0 | |
300 | sllg %r1, %r1, 32 | |
301 | ear %r1, %a1 # Extract thread pointer. | |
302 | .LEHB0: | |
303 | stg %r2, 0x38(%r1) # Save the new stack boundary. | |
304 | ||
305 | brasl %r14, __morestack_unblock_signals | |
306 | ||
307 | lgr %r0, %r8 # Static chain. | |
308 | lmg %r2, %r6, 0x10(%r11) # Paremeter registers. | |
309 | ||
310 | # Third parameter is address of function meat - address of parameter | |
311 | # block. | |
312 | ag %r10, 0x10(%r10) | |
313 | ||
314 | # Leave vararg pointer in %r1, in case function uses it | |
315 | la %r1, 0xa0(%r11) | |
316 | ||
317 | # State of registers: | |
318 | # %r0: Static chain from entry. | |
319 | # %r1: Vararg pointer. | |
320 | # %r2-%r6: Parameters from entry. | |
321 | # %r7-%r10: Indeterminate. | |
322 | # %r11: Frame pointer (%r15 from entry). | |
323 | # %r12-%r13: Indeterminate. | |
324 | # %r14: Return address. | |
325 | # %r15: Stack pointer. | |
326 | basr %r14, %r10 # Call our caller. | |
327 | ||
328 | stg %r2, 0x10(%r11) # Save return register. | |
329 | ||
330 | brasl %r14, __morestack_block_signals | |
331 | ||
332 | # We need a stack slot now, but have no good way to get it - the frame | |
333 | # on new stack had to be exactly 0xa0 bytes, or stack parameters would | |
334 | # be passed wrong. Abuse fpr save area in caller's frame (we don't | |
335 | # save actual fprs). | |
336 | la %r2, 0x80(%r11) | |
337 | brasl %r14, __generic_releasestack | |
338 | ||
339 | sg %r2, 0x80(%r11) # Subtract available space. | |
340 | aghi %r2, BACKOFF # Back off a bit. | |
341 | ear %r1, %a0 | |
342 | sllg %r1, %r1, 32 | |
343 | ear %r1, %a1 # Extract thread pointer. | |
344 | .LEHE0: | |
345 | stg %r2, 0x38(%r1) # Save the new stack boundary. | |
346 | ||
347 | # We need to restore the old stack pointer before unblocking signals. | |
348 | # We also need 0xa0 bytes for a stack frame. Since we had a stack | |
349 | # frame at this place before the stack switch, there's no need to | |
350 | # write the back chain again. | |
351 | lgr %r15, %r11 | |
352 | aghi %r15, -0xa0 | |
353 | ||
354 | brasl %r14, __morestack_unblock_signals | |
355 | ||
356 | lmg %r2, %r15, 0x10(%r11) # Restore all registers. | |
357 | .cfi_remember_state | |
358 | .cfi_restore %r15 | |
359 | .cfi_restore %r14 | |
360 | .cfi_restore %r13 | |
361 | .cfi_restore %r12 | |
362 | .cfi_restore %r11 | |
363 | .cfi_restore %r10 | |
364 | .cfi_restore %r9 | |
365 | .cfi_restore %r8 | |
366 | .cfi_restore %r7 | |
367 | .cfi_restore %r6 | |
368 | .cfi_def_cfa_register %r15 | |
369 | br %r14 # Return to caller's caller. | |
370 | ||
371 | # Executed if no new stack allocation is needed. | |
372 | ||
373 | .Lnoalloc: | |
374 | .cfi_restore_state | |
375 | # We may need to copy stack parameters. | |
376 | lg %r9, 0x8(%r10) # Load stack parameter size. | |
377 | ltgr %r9, %r9 # Check if it's 0. | |
378 | je .Lnostackparm # Skip the copy if not needed. | |
379 | sgr %r15, %r9 # Make space on the stack. | |
380 | la %r8, 0xa0(%r15) # Destination. | |
381 | la %r12, 0xa0(%r11) # Source. | |
382 | lgr %r13, %r9 # Source size. | |
383 | .Lcopy: | |
384 | mvcle %r8, %r12, 0 # Copy. | |
385 | jo .Lcopy | |
386 | ||
387 | .Lnostackparm: | |
388 | # Third parameter is address of function meat - address of parameter | |
389 | # block. | |
390 | ag %r10, 0x10(%r10) | |
391 | ||
392 | # Leave vararg pointer in %r1, in case function uses it | |
393 | la %r1, 0xa0(%r11) | |
394 | ||
395 | # OK, no stack allocation needed. We still follow the protocol and | |
396 | # call our caller - it doesn't cost much and makes sure vararg works. | |
397 | # No need to set any registers here - %r0 and %r2-%r6 weren't modified. | |
398 | basr %r14, %r10 # Call our caller. | |
399 | ||
400 | lmg %r6, %r15, 0x30(%r11) # Restore all callee-saved registers. | |
401 | .cfi_remember_state | |
402 | .cfi_restore %r15 | |
403 | .cfi_restore %r14 | |
404 | .cfi_restore %r13 | |
405 | .cfi_restore %r12 | |
406 | .cfi_restore %r11 | |
407 | .cfi_restore %r10 | |
408 | .cfi_restore %r9 | |
409 | .cfi_restore %r8 | |
410 | .cfi_restore %r7 | |
411 | .cfi_restore %r6 | |
412 | .cfi_def_cfa_register %r15 | |
413 | br %r14 # Return to caller's caller. | |
414 | ||
415 | # This is the cleanup code called by the stack unwinder when unwinding | |
416 | # through the code between .LEHB0 and .LEHE0 above. | |
417 | ||
418 | .L1: | |
419 | .cfi_restore_state | |
420 | lgr %r2, %r11 # Stack pointer after resume. | |
421 | brasl %r14, __generic_findstack | |
422 | lgr %r3, %r11 # Get the stack pointer. | |
423 | sgr %r3, %r2 # Subtract available space. | |
424 | aghi %r3, BACKOFF # Back off a bit. | |
425 | ear %r1, %a0 | |
426 | sllg %r1, %r1, 32 | |
427 | ear %r1, %a1 # Extract thread pointer. | |
428 | stg %r3, 0x38(%r1) # Save the new stack boundary. | |
429 | ||
430 | lgr %r2, %r6 # Exception header. | |
431 | #ifdef __PIC__ | |
432 | brasl %r14, _Unwind_Resume@PLT | |
433 | #else | |
434 | brasl %r14, _Unwind_Resume | |
435 | #endif | |
436 | ||
437 | #endif /* defined(__s390x__) */ | |
438 | ||
439 | .cfi_endproc | |
440 | .size __morestack, . - __morestack | |
441 | ||
442 | ||
443 | # The exception table. This tells the personality routine to execute | |
444 | # the exception handler. | |
445 | ||
446 | .section .gcc_except_table,"a",@progbits | |
447 | .align 4 | |
448 | .LLSDA1: | |
449 | .byte 0xff # @LPStart format (omit) | |
450 | .byte 0xff # @TType format (omit) | |
451 | .byte 0x1 # call-site format (uleb128) | |
452 | .uleb128 .LLSDACSE1-.LLSDACSB1 # Call-site table length | |
453 | .LLSDACSB1: | |
454 | .uleb128 .LEHB0-.LFB1 # region 0 start | |
455 | .uleb128 .LEHE0-.LEHB0 # length | |
456 | .uleb128 .L1-.LFB1 # landing pad | |
457 | .uleb128 0 # action | |
458 | .LLSDACSE1: | |
459 | ||
460 | ||
461 | .global __gcc_personality_v0 | |
462 | #ifdef __PIC__ | |
463 | # Build a position independent reference to the basic | |
464 | # personality function. | |
465 | .hidden DW.ref.__gcc_personality_v0 | |
466 | .weak DW.ref.__gcc_personality_v0 | |
467 | .section .data.DW.ref.__gcc_personality_v0,"awG",@progbits,DW.ref.__gcc_personality_v0,comdat | |
468 | .type DW.ref.__gcc_personality_v0, @object | |
469 | DW.ref.__gcc_personality_v0: | |
470 | #ifndef __LP64__ | |
471 | .align 4 | |
472 | .size DW.ref.__gcc_personality_v0, 4 | |
473 | .long __gcc_personality_v0 | |
474 | #else | |
475 | .align 8 | |
476 | .size DW.ref.__gcc_personality_v0, 8 | |
477 | .quad __gcc_personality_v0 | |
478 | #endif | |
479 | #endif | |
480 | ||
481 | ||
482 | ||
483 | # Initialize the stack test value when the program starts or when a | |
484 | # new thread starts. We don't know how large the main stack is, so we | |
485 | # guess conservatively. We might be able to use getrlimit here. | |
486 | ||
487 | .text | |
488 | .global __stack_split_initialize | |
489 | .hidden __stack_split_initialize | |
490 | ||
491 | .type __stack_split_initialize, @function | |
492 | ||
493 | __stack_split_initialize: | |
494 | ||
495 | #ifndef __s390x__ | |
496 | ||
497 | ear %r1, %a0 | |
498 | lr %r0, %r15 | |
499 | ahi %r0, -0x4000 # We should have at least 16K. | |
500 | st %r0, 0x20(%r1) | |
501 | ||
502 | lr %r2, %r15 | |
503 | lhi %r3, 0x4000 | |
504 | #ifdef __PIC__ | |
505 | jg __generic_morestack_set_initial_sp@PLT # Tail call | |
506 | #else | |
507 | jg __generic_morestack_set_initial_sp # Tail call | |
508 | #endif | |
509 | ||
510 | #else /* defined(__s390x__) */ | |
511 | ||
512 | ear %r1, %a0 | |
513 | sllg %r1, %r1, 32 | |
514 | ear %r1, %a1 | |
515 | lgr %r0, %r15 | |
516 | aghi %r0, -0x4000 # We should have at least 16K. | |
517 | stg %r0, 0x38(%r1) | |
518 | ||
519 | lgr %r2, %r15 | |
520 | lghi %r3, 0x4000 | |
521 | #ifdef __PIC__ | |
522 | jg __generic_morestack_set_initial_sp@PLT # Tail call | |
523 | #else | |
524 | jg __generic_morestack_set_initial_sp # Tail call | |
525 | #endif | |
526 | ||
527 | #endif /* defined(__s390x__) */ | |
528 | ||
529 | .size __stack_split_initialize, . - __stack_split_initialize | |
530 | ||
531 | # Routines to get and set the guard, for __splitstack_getcontext, | |
532 | # __splitstack_setcontext, and __splitstack_makecontext. | |
533 | ||
534 | # void *__morestack_get_guard (void) returns the current stack guard. | |
535 | .text | |
536 | .global __morestack_get_guard | |
537 | .hidden __morestack_get_guard | |
538 | ||
539 | .type __morestack_get_guard,@function | |
540 | ||
541 | __morestack_get_guard: | |
542 | ||
543 | #ifndef __s390x__ | |
544 | ear %r1, %a0 | |
545 | l %r2, 0x20(%r1) | |
546 | #else | |
547 | ear %r1, %a0 | |
548 | sllg %r1, %r1, 32 | |
549 | ear %r1, %a1 | |
550 | lg %r2, 0x38(%r1) | |
551 | #endif | |
552 | br %r14 | |
553 | ||
554 | .size __morestack_get_guard, . - __morestack_get_guard | |
555 | ||
556 | # void __morestack_set_guard (void *) sets the stack guard. | |
557 | .global __morestack_set_guard | |
558 | .hidden __morestack_set_guard | |
559 | ||
560 | .type __morestack_set_guard,@function | |
561 | ||
562 | __morestack_set_guard: | |
563 | ||
564 | #ifndef __s390x__ | |
565 | ear %r1, %a0 | |
566 | st %r2, 0x20(%r1) | |
567 | #else | |
568 | ear %r1, %a0 | |
569 | sllg %r1, %r1, 32 | |
570 | ear %r1, %a1 | |
571 | stg %r2, 0x38(%r1) | |
572 | #endif | |
573 | br %r14 | |
574 | ||
575 | .size __morestack_set_guard, . - __morestack_set_guard | |
576 | ||
577 | # void *__morestack_make_guard (void *, size_t) returns the stack | |
578 | # guard value for a stack. | |
579 | .global __morestack_make_guard | |
580 | .hidden __morestack_make_guard | |
581 | ||
582 | .type __morestack_make_guard,@function | |
583 | ||
584 | __morestack_make_guard: | |
585 | ||
586 | #ifndef __s390x__ | |
587 | sr %r2, %r3 | |
588 | ahi %r2, BACKOFF | |
589 | #else | |
590 | sgr %r2, %r3 | |
591 | aghi %r2, BACKOFF | |
592 | #endif | |
593 | br %r14 | |
594 | ||
595 | .size __morestack_make_guard, . - __morestack_make_guard | |
596 | ||
597 | # Make __stack_split_initialize a high priority constructor. | |
598 | ||
f49e3d28 ILT |
599 | #if HAVE_INITFINI_ARRAY_SUPPORT |
600 | .section .init_array.00000,"aw",@progbits | |
601 | #else | |
4cb4721f | 602 | .section .ctors.65535,"aw",@progbits |
f49e3d28 | 603 | #endif |
4cb4721f MK |
604 | |
605 | #ifndef __LP64__ | |
606 | .align 4 | |
607 | .long __stack_split_initialize | |
608 | .long __morestack_load_mmap | |
609 | #else | |
610 | .align 8 | |
611 | .quad __stack_split_initialize | |
612 | .quad __morestack_load_mmap | |
613 | #endif | |
614 | ||
615 | .section .note.GNU-stack,"",@progbits | |
616 | .section .note.GNU-split-stack,"",@progbits | |
617 | .section .note.GNU-no-split-stack,"",@progbits |