1 # s390 support for -fsplit-stack.
2 # Copyright (C) 2015-2018 Free Software Foundation, Inc.
3 # Contributed by Marcin KoĆcielnicki <koriakin@0x04.net>.
5 # This file is part of GCC.
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
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
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.
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/>.
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
31 # The __morestack function.
36 .type __morestack,@function
46 # The 31-bit __morestack function.
48 # We use a cleanup to restore the stack guard if an exception
49 # is thrown through this code.
51 .cfi_personality 0,__gcc_personality_v0
54 .cfi_personality 0x9b,DW.ref.__gcc_personality_v0
55 .cfi_lsda 0x1b,.LLSDA1
58 stm %r2, %r15, 0x8(%r15) # Save %r2-%r15.
59 .cfi_offset %r6, -0x48
60 .cfi_offset %r7, -0x44
61 .cfi_offset %r8, -0x40
62 .cfi_offset %r9, -0x3c
63 .cfi_offset %r10, -0x38
64 .cfi_offset %r11, -0x34
65 .cfi_offset %r12, -0x30
66 .cfi_offset %r13, -0x2c
67 .cfi_offset %r14, -0x28
68 .cfi_offset %r15, -0x24
69 lr %r11, %r15 # Make frame pointer for vararg.
70 .cfi_def_cfa_register %r11
71 ahi %r15, -0x60 # 0x60 for standard frame.
72 st %r11, 0(%r15) # Save back chain.
73 lr %r8, %r0 # Save %r0 (static chain).
74 lr %r10, %r1 # Save %r1 (address of parameter block).
76 l %r7, 0(%r10) # Required frame size to %r7
77 ear %r1, %a0 # Extract thread pointer.
78 l %r1, 0x20(%r1) # Get stack bounduary
79 ar %r1, %r7 # Stack bounduary + frame size
80 a %r1, 4(%r10) # + stack param size
81 clr %r1, %r15 # Compare with current stack pointer
82 jle .Lnoalloc # guard > sp - frame-size: need alloc
84 brasl %r14, __morestack_block_signals
86 # We abuse one of caller's fpr save slots (which we don't use for fprs)
87 # as a local variable. Not needed here, but done to be consistent with
89 ahi %r7, BACKOFF # Bump requested size a bit.
90 st %r7, 0x40(%r11) # Stuff frame size on stack.
91 la %r2, 0x40(%r11) # Pass its address as parameter.
92 la %r3, 0x60(%r11) # Caller's stack parameters.
93 l %r4, 4(%r10) # Size of stack parameters.
94 brasl %r14, __generic_morestack
96 lr %r15, %r2 # Switch to the new stack.
97 ahi %r15, -0x60 # Make a stack frame on it.
98 st %r11, 0(%r15) # Save back chain.
100 s %r2, 0x40(%r11) # The end of stack space.
101 ahi %r2, BACKOFF # Back off a bit.
102 ear %r1, %a0 # Extract thread pointer.
104 st %r2, 0x20(%r1) # Save the new stack boundary.
106 brasl %r14, __morestack_unblock_signals
108 lr %r0, %r8 # Static chain.
109 lm %r2, %r6, 0x8(%r11) # Paremeter registers.
111 # Third parameter is address of function meat - address of parameter
115 # Leave vararg pointer in %r1, in case function uses it
118 # State of registers:
119 # %r0: Static chain from entry.
120 # %r1: Vararg pointer.
121 # %r2-%r6: Parameters from entry.
122 # %r7-%r10: Indeterminate.
123 # %r11: Frame pointer (%r15 from entry).
124 # %r12-%r13: Indeterminate.
125 # %r14: Return address.
126 # %r15: Stack pointer.
127 basr %r14, %r10 # Call our caller.
129 stm %r2, %r3, 0x8(%r11) # Save return registers.
131 brasl %r14, __morestack_block_signals
133 # We need a stack slot now, but have no good way to get it - the frame
134 # on new stack had to be exactly 0x60 bytes, or stack parameters would
135 # be passed wrong. Abuse fpr save area in caller's frame (we don't
138 brasl %r14, __generic_releasestack
140 s %r2, 0x40(%r11) # Subtract available space.
141 ahi %r2, BACKOFF # Back off a bit.
142 ear %r1, %a0 # Extract thread pointer.
144 st %r2, 0x20(%r1) # Save the new stack boundary.
146 # We need to restore the old stack pointer before unblocking signals.
147 # We also need 0x60 bytes for a stack frame. Since we had a stack
148 # frame at this place before the stack switch, there's no need to
149 # write the back chain again.
153 brasl %r14, __morestack_unblock_signals
155 lm %r2, %r15, 0x8(%r11) # Restore all registers.
167 .cfi_def_cfa_register %r15
168 br %r14 # Return to caller's caller.
170 # Executed if no new stack allocation is needed.
174 # We may need to copy stack parameters.
175 l %r9, 0x4(%r10) # Load stack parameter size.
176 ltr %r9, %r9 # And check if it's 0.
177 je .Lnostackparm # Skip the copy if not needed.
178 sr %r15, %r9 # Make space on the stack.
179 la %r8, 0x60(%r15) # Destination.
180 la %r12, 0x60(%r11) # Source.
181 lr %r13, %r9 # Source size.
183 mvcle %r8, %r12, 0 # Copy.
187 # Third parameter is address of function meat - address of parameter
191 # Leave vararg pointer in %r1, in case function uses it
194 # OK, no stack allocation needed. We still follow the protocol and
195 # call our caller - it doesn't cost much and makes sure vararg works.
196 # No need to set any registers here - %r0 and %r2-%r6 weren't modified.
197 basr %r14, %r10 # Call our caller.
199 lm %r6, %r15, 0x18(%r11) # Restore all callee-saved registers.
211 .cfi_def_cfa_register %r15
212 br %r14 # Return to caller's caller.
214 # This is the cleanup code called by the stack unwinder when unwinding
215 # through the code between .LEHB0 and .LEHE0 above.
219 lr %r2, %r11 # Stack pointer after resume.
220 brasl %r14, __generic_findstack
221 lr %r3, %r11 # Get the stack pointer.
222 sr %r3, %r2 # Subtract available space.
223 ahi %r3, BACKOFF # Back off a bit.
224 ear %r1, %a0 # Extract thread pointer.
225 st %r3, 0x20(%r1) # Save the new stack boundary.
227 # We need GOT pointer in %r12 for PLT entry.
228 larl %r12,_GLOBAL_OFFSET_TABLE_
229 lr %r2, %r6 # Exception header.
231 brasl %r14, _Unwind_Resume@PLT
233 brasl %r14, _Unwind_Resume
236 #else /* defined(__s390x__) */
239 # The 64-bit __morestack function.
241 # We use a cleanup to restore the stack guard if an exception
242 # is thrown through this code.
244 .cfi_personality 0x3,__gcc_personality_v0
245 .cfi_lsda 0x3,.LLSDA1
247 .cfi_personality 0x9b,DW.ref.__gcc_personality_v0
248 .cfi_lsda 0x1b,.LLSDA1
251 stmg %r2, %r15, 0x10(%r15) # Save %r2-%r15.
252 .cfi_offset %r6, -0x70
253 .cfi_offset %r7, -0x68
254 .cfi_offset %r8, -0x60
255 .cfi_offset %r9, -0x58
256 .cfi_offset %r10, -0x50
257 .cfi_offset %r11, -0x48
258 .cfi_offset %r12, -0x40
259 .cfi_offset %r13, -0x38
260 .cfi_offset %r14, -0x30
261 .cfi_offset %r15, -0x28
262 lgr %r11, %r15 # Make frame pointer for vararg.
263 .cfi_def_cfa_register %r11
264 aghi %r15, -0xa0 # 0xa0 for standard frame.
265 stg %r11, 0(%r15) # Save back chain.
266 lgr %r8, %r0 # Save %r0 (static chain).
267 lgr %r10, %r1 # Save %r1 (address of parameter block).
269 lg %r7, 0(%r10) # Required frame size to %r7
272 ear %r1, %a1 # Extract thread pointer.
273 lg %r1, 0x38(%r1) # Get stack bounduary
274 agr %r1, %r7 # Stack bounduary + frame size
275 ag %r1, 8(%r10) # + stack param size
276 clgr %r1, %r15 # Compare with current stack pointer
277 jle .Lnoalloc # guard > sp - frame-size: need alloc
279 brasl %r14, __morestack_block_signals
281 # We abuse one of caller's fpr save slots (which we don't use for fprs)
282 # as a local variable. Not needed here, but done to be consistent with
284 aghi %r7, BACKOFF # Bump requested size a bit.
285 stg %r7, 0x80(%r11) # Stuff frame size on stack.
286 la %r2, 0x80(%r11) # Pass its address as parameter.
287 la %r3, 0xa0(%r11) # Caller's stack parameters.
288 lg %r4, 8(%r10) # Size of stack parameters.
289 brasl %r14, __generic_morestack
291 lgr %r15, %r2 # Switch to the new stack.
292 aghi %r15, -0xa0 # Make a stack frame on it.
293 stg %r11, 0(%r15) # Save back chain.
295 sg %r2, 0x80(%r11) # The end of stack space.
296 aghi %r2, BACKOFF # Back off a bit.
299 ear %r1, %a1 # Extract thread pointer.
301 stg %r2, 0x38(%r1) # Save the new stack boundary.
303 brasl %r14, __morestack_unblock_signals
305 lgr %r0, %r8 # Static chain.
306 lmg %r2, %r6, 0x10(%r11) # Paremeter registers.
308 # Third parameter is address of function meat - address of parameter
312 # Leave vararg pointer in %r1, in case function uses it
315 # State of registers:
316 # %r0: Static chain from entry.
317 # %r1: Vararg pointer.
318 # %r2-%r6: Parameters from entry.
319 # %r7-%r10: Indeterminate.
320 # %r11: Frame pointer (%r15 from entry).
321 # %r12-%r13: Indeterminate.
322 # %r14: Return address.
323 # %r15: Stack pointer.
324 basr %r14, %r10 # Call our caller.
326 stg %r2, 0x10(%r11) # Save return register.
328 brasl %r14, __morestack_block_signals
330 # We need a stack slot now, but have no good way to get it - the frame
331 # on new stack had to be exactly 0xa0 bytes, or stack parameters would
332 # be passed wrong. Abuse fpr save area in caller's frame (we don't
335 brasl %r14, __generic_releasestack
337 sg %r2, 0x80(%r11) # Subtract available space.
338 aghi %r2, BACKOFF # Back off a bit.
341 ear %r1, %a1 # Extract thread pointer.
343 stg %r2, 0x38(%r1) # Save the new stack boundary.
345 # We need to restore the old stack pointer before unblocking signals.
346 # We also need 0xa0 bytes for a stack frame. Since we had a stack
347 # frame at this place before the stack switch, there's no need to
348 # write the back chain again.
352 brasl %r14, __morestack_unblock_signals
354 lmg %r2, %r15, 0x10(%r11) # Restore all registers.
366 .cfi_def_cfa_register %r15
367 br %r14 # Return to caller's caller.
369 # Executed if no new stack allocation is needed.
373 # We may need to copy stack parameters.
374 lg %r9, 0x8(%r10) # Load stack parameter size.
375 ltgr %r9, %r9 # Check if it's 0.
376 je .Lnostackparm # Skip the copy if not needed.
377 sgr %r15, %r9 # Make space on the stack.
378 la %r8, 0xa0(%r15) # Destination.
379 la %r12, 0xa0(%r11) # Source.
380 lgr %r13, %r9 # Source size.
382 mvcle %r8, %r12, 0 # Copy.
386 # Third parameter is address of function meat - address of parameter
390 # Leave vararg pointer in %r1, in case function uses it
393 # OK, no stack allocation needed. We still follow the protocol and
394 # call our caller - it doesn't cost much and makes sure vararg works.
395 # No need to set any registers here - %r0 and %r2-%r6 weren't modified.
396 basr %r14, %r10 # Call our caller.
398 lmg %r6, %r15, 0x30(%r11) # Restore all callee-saved registers.
410 .cfi_def_cfa_register %r15
411 br %r14 # Return to caller's caller.
413 # This is the cleanup code called by the stack unwinder when unwinding
414 # through the code between .LEHB0 and .LEHE0 above.
418 lgr %r2, %r11 # Stack pointer after resume.
419 brasl %r14, __generic_findstack
420 lgr %r3, %r11 # Get the stack pointer.
421 sgr %r3, %r2 # Subtract available space.
422 aghi %r3, BACKOFF # Back off a bit.
425 ear %r1, %a1 # Extract thread pointer.
426 stg %r3, 0x38(%r1) # Save the new stack boundary.
428 lgr %r2, %r6 # Exception header.
430 brasl %r14, _Unwind_Resume@PLT
432 brasl %r14, _Unwind_Resume
435 #endif /* defined(__s390x__) */
438 .size __morestack, . - __morestack
441 # The exception table. This tells the personality routine to execute
442 # the exception handler.
444 .section .gcc_except_table,"a",@progbits
447 .byte 0xff # @LPStart format (omit)
448 .byte 0xff # @TType format (omit)
449 .byte 0x1 # call-site format (uleb128)
450 .uleb128 .LLSDACSE1-.LLSDACSB1 # Call-site table length
452 .uleb128 .LEHB0-.LFB1 # region 0 start
453 .uleb128 .LEHE0-.LEHB0 # length
454 .uleb128 .L1-.LFB1 # landing pad
459 .global __gcc_personality_v0
461 # Build a position independent reference to the basic
462 # personality function.
463 .hidden DW.ref.__gcc_personality_v0
464 .weak DW.ref.__gcc_personality_v0
465 .section .data.DW.ref.__gcc_personality_v0,"awG",@progbits,DW.ref.__gcc_personality_v0,comdat
466 .type DW.ref.__gcc_personality_v0, @object
467 DW.ref.__gcc_personality_v0:
470 .size DW.ref.__gcc_personality_v0, 4
471 .long __gcc_personality_v0
474 .size DW.ref.__gcc_personality_v0, 8
475 .quad __gcc_personality_v0
481 # Initialize the stack test value when the program starts or when a
482 # new thread starts. We don't know how large the main stack is, so we
483 # guess conservatively. We might be able to use getrlimit here.
486 .global __stack_split_initialize
487 .hidden __stack_split_initialize
489 .type __stack_split_initialize, @function
491 __stack_split_initialize:
497 ahi %r0, -0x4000 # We should have at least 16K.
503 jg __generic_morestack_set_initial_sp@PLT # Tail call
505 jg __generic_morestack_set_initial_sp # Tail call
508 #else /* defined(__s390x__) */
514 aghi %r0, -0x4000 # We should have at least 16K.
520 jg __generic_morestack_set_initial_sp@PLT # Tail call
522 jg __generic_morestack_set_initial_sp # Tail call
525 #endif /* defined(__s390x__) */
527 .size __stack_split_initialize, . - __stack_split_initialize
529 # Routines to get and set the guard, for __splitstack_getcontext,
530 # __splitstack_setcontext, and __splitstack_makecontext.
532 # void *__morestack_get_guard (void) returns the current stack guard.
534 .global __morestack_get_guard
535 .hidden __morestack_get_guard
537 .type __morestack_get_guard,@function
539 __morestack_get_guard:
552 .size __morestack_get_guard, . - __morestack_get_guard
554 # void __morestack_set_guard (void *) sets the stack guard.
555 .global __morestack_set_guard
556 .hidden __morestack_set_guard
558 .type __morestack_set_guard,@function
560 __morestack_set_guard:
573 .size __morestack_set_guard, . - __morestack_set_guard
575 # void *__morestack_make_guard (void *, size_t) returns the stack
576 # guard value for a stack.
577 .global __morestack_make_guard
578 .hidden __morestack_make_guard
580 .type __morestack_make_guard,@function
582 __morestack_make_guard:
593 .size __morestack_make_guard, . - __morestack_make_guard
595 # Make __stack_split_initialize a high priority constructor.
597 .section .ctors.65535,"aw",@progbits
601 .long __stack_split_initialize
602 .long __morestack_load_mmap
605 .quad __stack_split_initialize
606 .quad __morestack_load_mmap
609 .section .note.GNU-stack,"",@progbits
610 .section .note.GNU-split-stack,"",@progbits
611 .section .note.GNU-no-split-stack,"",@progbits