]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/s390/morestack.S
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / s390 / morestack.S
1 # s390 support for -fsplit-stack.
2 # Copyright (C) 2015-2024 Free Software Foundation, Inc.
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
31 #include <auto-host.h>
32
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
599 #if HAVE_INITFINI_ARRAY_SUPPORT
600 .section .init_array.00000,"aw",@init_array
601 #else
602 .section .ctors.65535,"aw",@progbits
603 #endif
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