diff options
author | krebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-02-15 10:20:18 +0000 |
---|---|---|
committer | krebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-02-15 10:20:18 +0000 |
commit | c6d481f72b62d28bdfc50bcf3b50099bdd72f918 (patch) | |
tree | 633620a331dce10653b1b110b0531b75f5ee2376 /libgcc | |
parent | 4a45fe0fc443008fa175bfbd19a31faa443aa97e (diff) | |
download | gcc-c6d481f72b62d28bdfc50bcf3b50099bdd72f918.tar.gz |
S/390: Add -fsplit-stack support
libgcc/ChangeLog:
* config.host: Use t-stack and t-stack-s390 for s390*-*-linux.
* config/s390/morestack.S: New file.
* config/s390/t-stack-s390: New file.
* generic-morestack.c (__splitstack_find): Add s390-specific code.
gcc/ChangeLog:
* common/config/s390/s390-common.c (s390_supports_split_stack):
New function.
(TARGET_SUPPORTS_SPLIT_STACK): New macro.
* config/s390/s390-protos.h: Add s390_expand_split_stack_prologue.
* config/s390/s390.c (struct machine_function): New field
split_stack_varargs_pointer.
(s390_register_info): Mark r12 as clobbered if it'll be used as temp
in s390_emit_prologue.
(s390_emit_prologue): Use r12 as temp if r1 is taken by split-stack
vararg pointer.
(morestack_ref): New global.
(SPLIT_STACK_AVAILABLE): New macro.
(s390_expand_split_stack_prologue): New function.
(s390_live_on_entry): New function.
(s390_va_start): Use split-stack vararg pointer if appropriate.
(s390_asm_file_end): Emit the split-stack note sections.
(TARGET_EXTRA_LIVE_ON_ENTRY): New macro.
* config/s390/s390.md (UNSPEC_STACK_CHECK): New unspec.
(UNSPECV_SPLIT_STACK_CALL): New unspec.
(UNSPECV_SPLIT_STACK_DATA): New unspec.
(split_stack_prologue): New expand.
(split_stack_space_check): New expand.
(split_stack_data): New insn.
(split_stack_call): New expand.
(split_stack_call_*): New insn.
(split_stack_cond_call): New expand.
(split_stack_cond_call_*): New insn.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233421 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 7 | ||||
-rw-r--r-- | libgcc/config.host | 4 | ||||
-rw-r--r-- | libgcc/config/s390/morestack.S | 611 | ||||
-rw-r--r-- | libgcc/config/s390/t-stack-s390 | 2 | ||||
-rw-r--r-- | libgcc/generic-morestack.c | 4 |
5 files changed, 626 insertions, 2 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 63ad30ec445..80b562caccf 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,10 @@ +2016-02-15 Marcin KoĆcielnicki <koriakin@0x04.net> + + * config.host: Use t-stack and t-stack-s390 for s390*-*-linux. + * config/s390/morestack.S: New file. + * config/s390/t-stack-s390: New file. + * generic-morestack.c (__splitstack_find): Add s390-specific code. + 2016-02-12 Walter Lee <walt@tilera.com> * config.host (tilegx*-*-linux*): remove ti from diff --git a/libgcc/config.host b/libgcc/config.host index 06de0deaeb0..ef7dfd02f5d 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -1114,11 +1114,11 @@ rx-*-elf) tm_file="$tm_file rx/rx-abi.h rx/rx-lib.h" ;; s390-*-linux*) - tmake_file="${tmake_file} s390/t-crtstuff s390/t-linux s390/32/t-floattodi" + tmake_file="${tmake_file} s390/t-crtstuff s390/t-linux s390/32/t-floattodi t-stack s390/t-stack-s390" md_unwind_header=s390/linux-unwind.h ;; s390x-*-linux*) - tmake_file="${tmake_file} s390/t-crtstuff s390/t-linux" + tmake_file="${tmake_file} s390/t-crtstuff s390/t-linux t-stack s390/t-stack-s390" if test "${host_address}" = 32; then tmake_file="${tmake_file} s390/32/t-floattodi" fi diff --git a/libgcc/config/s390/morestack.S b/libgcc/config/s390/morestack.S new file mode 100644 index 00000000000..fa6951badf0 --- /dev/null +++ b/libgcc/config/s390/morestack.S @@ -0,0 +1,611 @@ +# s390 support for -fsplit-stack. +# Copyright (C) 2015 Free Software Foundation, Inc. +# Contributed by Marcin KoĆcielnicki <koriakin@0x04.net>. + +# This file is part of GCC. + +# GCC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3, or (at your option) any later +# version. + +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. + +# Under Section 7 of GPL version 3, you are granted additional +# permissions described in the GCC Runtime Library Exception, version +# 3.1, as published by the Free Software Foundation. + +# You should have received a copy of the GNU General Public License and +# a copy of the GCC Runtime Library Exception along with this program; +# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +# <http://www.gnu.org/licenses/>. + +# Excess space needed to call ld.so resolver for lazy plt +# resolution. Go uses sigaltstack so this doesn't need to +# also cover signal frame size. +#define BACKOFF 0x1000 + +# The __morestack function. + + .global __morestack + .hidden __morestack + + .type __morestack,@function + +__morestack: +.LFB1: + .cfi_startproc + + +#ifndef __s390x__ + + +# The 31-bit __morestack function. + + # We use a cleanup to restore the stack guard if an exception + # is thrown through this code. +#ifndef __PIC__ + .cfi_personality 0,__gcc_personality_v0 + .cfi_lsda 0,.LLSDA1 +#else + .cfi_personality 0x9b,DW.ref.__gcc_personality_v0 + .cfi_lsda 0x1b,.LLSDA1 +#endif + + stm %r2, %r15, 0x8(%r15) # Save %r2-%r15. + .cfi_offset %r6, -0x48 + .cfi_offset %r7, -0x44 + .cfi_offset %r8, -0x40 + .cfi_offset %r9, -0x3c + .cfi_offset %r10, -0x38 + .cfi_offset %r11, -0x34 + .cfi_offset %r12, -0x30 + .cfi_offset %r13, -0x2c + .cfi_offset %r14, -0x28 + .cfi_offset %r15, -0x24 + lr %r11, %r15 # Make frame pointer for vararg. + .cfi_def_cfa_register %r11 + ahi %r15, -0x60 # 0x60 for standard frame. + st %r11, 0(%r15) # Save back chain. + lr %r8, %r0 # Save %r0 (static chain). + lr %r10, %r1 # Save %r1 (address of parameter block). + + l %r7, 0(%r10) # Required frame size to %r7 + ear %r1, %a0 # Extract thread pointer. + l %r1, 0x20(%r1) # Get stack bounduary + ar %r1, %r7 # Stack bounduary + frame size + a %r1, 4(%r10) # + stack param size + clr %r1, %r15 # Compare with current stack pointer + jle .Lnoalloc # guard > sp - frame-size: need alloc + + brasl %r14, __morestack_block_signals + + # We abuse one of caller's fpr save slots (which we don't use for fprs) + # as a local variable. Not needed here, but done to be consistent with + # the below use. + ahi %r7, BACKOFF # Bump requested size a bit. + st %r7, 0x40(%r11) # Stuff frame size on stack. + la %r2, 0x40(%r11) # Pass its address as parameter. + la %r3, 0x60(%r11) # Caller's stack parameters. + l %r4, 4(%r10) # Size of stack parameters. + brasl %r14, __generic_morestack + + lr %r15, %r2 # Switch to the new stack. + ahi %r15, -0x60 # Make a stack frame on it. + st %r11, 0(%r15) # Save back chain. + + s %r2, 0x40(%r11) # The end of stack space. + ahi %r2, BACKOFF # Back off a bit. + ear %r1, %a0 # Extract thread pointer. +.LEHB0: + st %r2, 0x20(%r1) # Save the new stack boundary. + + brasl %r14, __morestack_unblock_signals + + lr %r0, %r8 # Static chain. + lm %r2, %r6, 0x8(%r11) # Paremeter registers. + + # Third parameter is address of function meat - address of parameter + # block. + a %r10, 0x8(%r10) + + # Leave vararg pointer in %r1, in case function uses it + la %r1, 0x60(%r11) + + # State of registers: + # %r0: Static chain from entry. + # %r1: Vararg pointer. + # %r2-%r6: Parameters from entry. + # %r7-%r10: Indeterminate. + # %r11: Frame pointer (%r15 from entry). + # %r12-%r13: Indeterminate. + # %r14: Return address. + # %r15: Stack pointer. + basr %r14, %r10 # Call our caller. + + stm %r2, %r3, 0x8(%r11) # Save return registers. + + brasl %r14, __morestack_block_signals + + # We need a stack slot now, but have no good way to get it - the frame + # on new stack had to be exactly 0x60 bytes, or stack parameters would + # be passed wrong. Abuse fpr save area in caller's frame (we don't + # save actual fprs). + la %r2, 0x40(%r11) + brasl %r14, __generic_releasestack + + s %r2, 0x40(%r11) # Subtract available space. + ahi %r2, BACKOFF # Back off a bit. + ear %r1, %a0 # Extract thread pointer. +.LEHE0: + st %r2, 0x20(%r1) # Save the new stack boundary. + + # We need to restore the old stack pointer before unblocking signals. + # We also need 0x60 bytes for a stack frame. Since we had a stack + # frame at this place before the stack switch, there's no need to + # write the back chain again. + lr %r15, %r11 + ahi %r15, -0x60 + + brasl %r14, __morestack_unblock_signals + + lm %r2, %r15, 0x8(%r11) # Restore all registers. + .cfi_remember_state + .cfi_restore %r15 + .cfi_restore %r14 + .cfi_restore %r13 + .cfi_restore %r12 + .cfi_restore %r11 + .cfi_restore %r10 + .cfi_restore %r9 + .cfi_restore %r8 + .cfi_restore %r7 + .cfi_restore %r6 + .cfi_def_cfa_register %r15 + br %r14 # Return to caller's caller. + +# Executed if no new stack allocation is needed. + +.Lnoalloc: + .cfi_restore_state + # We may need to copy stack parameters. + l %r9, 0x4(%r10) # Load stack parameter size. + ltr %r9, %r9 # And check if it's 0. + je .Lnostackparm # Skip the copy if not needed. + sr %r15, %r9 # Make space on the stack. + la %r8, 0x60(%r15) # Destination. + la %r12, 0x60(%r11) # Source. + lr %r13, %r9 # Source size. +.Lcopy: + mvcle %r8, %r12, 0 # Copy. + jo .Lcopy + +.Lnostackparm: + # Third parameter is address of function meat - address of parameter + # block. + a %r10, 0x8(%r10) + + # Leave vararg pointer in %r1, in case function uses it + la %r1, 0x60(%r11) + + # OK, no stack allocation needed. We still follow the protocol and + # call our caller - it doesn't cost much and makes sure vararg works. + # No need to set any registers here - %r0 and %r2-%r6 weren't modified. + basr %r14, %r10 # Call our caller. + + lm %r6, %r15, 0x18(%r11) # Restore all callee-saved registers. + .cfi_remember_state + .cfi_restore %r15 + .cfi_restore %r14 + .cfi_restore %r13 + .cfi_restore %r12 + .cfi_restore %r11 + .cfi_restore %r10 + .cfi_restore %r9 + .cfi_restore %r8 + .cfi_restore %r7 + .cfi_restore %r6 + .cfi_def_cfa_register %r15 + br %r14 # Return to caller's caller. + +# This is the cleanup code called by the stack unwinder when unwinding +# through the code between .LEHB0 and .LEHE0 above. + +.L1: + .cfi_restore_state + lr %r2, %r11 # Stack pointer after resume. + brasl %r14, __generic_findstack + lr %r3, %r11 # Get the stack pointer. + sr %r3, %r2 # Subtract available space. + ahi %r3, BACKOFF # Back off a bit. + ear %r1, %a0 # Extract thread pointer. + st %r3, 0x20(%r1) # Save the new stack boundary. + + # We need GOT pointer in %r12 for PLT entry. + larl %r12,_GLOBAL_OFFSET_TABLE_ + lr %r2, %r6 # Exception header. +#ifdef __PIC__ + brasl %r14, _Unwind_Resume@PLT +#else + brasl %r14, _Unwind_Resume +#endif + +#else /* defined(__s390x__) */ + + +# The 64-bit __morestack function. + + # We use a cleanup to restore the stack guard if an exception + # is thrown through this code. +#ifndef __PIC__ + .cfi_personality 0x3,__gcc_personality_v0 + .cfi_lsda 0x3,.LLSDA1 +#else + .cfi_personality 0x9b,DW.ref.__gcc_personality_v0 + .cfi_lsda 0x1b,.LLSDA1 +#endif + + stmg %r2, %r15, 0x10(%r15) # Save %r2-%r15. + .cfi_offset %r6, -0x70 + .cfi_offset %r7, -0x68 + .cfi_offset %r8, -0x60 + .cfi_offset %r9, -0x58 + .cfi_offset %r10, -0x50 + .cfi_offset %r11, -0x48 + .cfi_offset %r12, -0x40 + .cfi_offset %r13, -0x38 + .cfi_offset %r14, -0x30 + .cfi_offset %r15, -0x28 + lgr %r11, %r15 # Make frame pointer for vararg. + .cfi_def_cfa_register %r11 + aghi %r15, -0xa0 # 0xa0 for standard frame. + stg %r11, 0(%r15) # Save back chain. + lgr %r8, %r0 # Save %r0 (static chain). + lgr %r10, %r1 # Save %r1 (address of parameter block). + + lg %r7, 0(%r10) # Required frame size to %r7 + ear %r1, %a0 + sllg %r1, %r1, 32 + ear %r1, %a1 # Extract thread pointer. + lg %r1, 0x38(%r1) # Get stack bounduary + agr %r1, %r7 # Stack bounduary + frame size + ag %r1, 8(%r10) # + stack param size + clgr %r1, %r15 # Compare with current stack pointer + jle .Lnoalloc # guard > sp - frame-size: need alloc + + brasl %r14, __morestack_block_signals + + # We abuse one of caller's fpr save slots (which we don't use for fprs) + # as a local variable. Not needed here, but done to be consistent with + # the below use. + aghi %r7, BACKOFF # Bump requested size a bit. + stg %r7, 0x80(%r11) # Stuff frame size on stack. + la %r2, 0x80(%r11) # Pass its address as parameter. + la %r3, 0xa0(%r11) # Caller's stack parameters. + lg %r4, 8(%r10) # Size of stack parameters. + brasl %r14, __generic_morestack + + lgr %r15, %r2 # Switch to the new stack. + aghi %r15, -0xa0 # Make a stack frame on it. + stg %r11, 0(%r15) # Save back chain. + + sg %r2, 0x80(%r11) # The end of stack space. + aghi %r2, BACKOFF # Back off a bit. + ear %r1, %a0 + sllg %r1, %r1, 32 + ear %r1, %a1 # Extract thread pointer. +.LEHB0: + stg %r2, 0x38(%r1) # Save the new stack boundary. + + brasl %r14, __morestack_unblock_signals + + lgr %r0, %r8 # Static chain. + lmg %r2, %r6, 0x10(%r11) # Paremeter registers. + + # Third parameter is address of function meat - address of parameter + # block. + ag %r10, 0x10(%r10) + + # Leave vararg pointer in %r1, in case function uses it + la %r1, 0xa0(%r11) + + # State of registers: + # %r0: Static chain from entry. + # %r1: Vararg pointer. + # %r2-%r6: Parameters from entry. + # %r7-%r10: Indeterminate. + # %r11: Frame pointer (%r15 from entry). + # %r12-%r13: Indeterminate. + # %r14: Return address. + # %r15: Stack pointer. + basr %r14, %r10 # Call our caller. + + stg %r2, 0x10(%r11) # Save return register. + + brasl %r14, __morestack_block_signals + + # We need a stack slot now, but have no good way to get it - the frame + # on new stack had to be exactly 0xa0 bytes, or stack parameters would + # be passed wrong. Abuse fpr save area in caller's frame (we don't + # save actual fprs). + la %r2, 0x80(%r11) + brasl %r14, __generic_releasestack + + sg %r2, 0x80(%r11) # Subtract available space. + aghi %r2, BACKOFF # Back off a bit. + ear %r1, %a0 + sllg %r1, %r1, 32 + ear %r1, %a1 # Extract thread pointer. +.LEHE0: + stg %r2, 0x38(%r1) # Save the new stack boundary. + + # We need to restore the old stack pointer before unblocking signals. + # We also need 0xa0 bytes for a stack frame. Since we had a stack + # frame at this place before the stack switch, there's no need to + # write the back chain again. + lgr %r15, %r11 + aghi %r15, -0xa0 + + brasl %r14, __morestack_unblock_signals + + lmg %r2, %r15, 0x10(%r11) # Restore all registers. + .cfi_remember_state + .cfi_restore %r15 + .cfi_restore %r14 + .cfi_restore %r13 + .cfi_restore %r12 + .cfi_restore %r11 + .cfi_restore %r10 + .cfi_restore %r9 + .cfi_restore %r8 + .cfi_restore %r7 + .cfi_restore %r6 + .cfi_def_cfa_register %r15 + br %r14 # Return to caller's caller. + +# Executed if no new stack allocation is needed. + +.Lnoalloc: + .cfi_restore_state + # We may need to copy stack parameters. + lg %r9, 0x8(%r10) # Load stack parameter size. + ltgr %r9, %r9 # Check if it's 0. + je .Lnostackparm # Skip the copy if not needed. + sgr %r15, %r9 # Make space on the stack. + la %r8, 0xa0(%r15) # Destination. + la %r12, 0xa0(%r11) # Source. + lgr %r13, %r9 # Source size. +.Lcopy: + mvcle %r8, %r12, 0 # Copy. + jo .Lcopy + +.Lnostackparm: + # Third parameter is address of function meat - address of parameter + # block. + ag %r10, 0x10(%r10) + + # Leave vararg pointer in %r1, in case function uses it + la %r1, 0xa0(%r11) + + # OK, no stack allocation needed. We still follow the protocol and + # call our caller - it doesn't cost much and makes sure vararg works. + # No need to set any registers here - %r0 and %r2-%r6 weren't modified. + basr %r14, %r10 # Call our caller. + + lmg %r6, %r15, 0x30(%r11) # Restore all callee-saved registers. + .cfi_remember_state + .cfi_restore %r15 + .cfi_restore %r14 + .cfi_restore %r13 + .cfi_restore %r12 + .cfi_restore %r11 + .cfi_restore %r10 + .cfi_restore %r9 + .cfi_restore %r8 + .cfi_restore %r7 + .cfi_restore %r6 + .cfi_def_cfa_register %r15 + br %r14 # Return to caller's caller. + +# This is the cleanup code called by the stack unwinder when unwinding +# through the code between .LEHB0 and .LEHE0 above. + +.L1: + .cfi_restore_state + lgr %r2, %r11 # Stack pointer after resume. + brasl %r14, __generic_findstack + lgr %r3, %r11 # Get the stack pointer. + sgr %r3, %r2 # Subtract available space. + aghi %r3, BACKOFF # Back off a bit. + ear %r1, %a0 + sllg %r1, %r1, 32 + ear %r1, %a1 # Extract thread pointer. + stg %r3, 0x38(%r1) # Save the new stack boundary. + + lgr %r2, %r6 # Exception header. +#ifdef __PIC__ + brasl %r14, _Unwind_Resume@PLT +#else + brasl %r14, _Unwind_Resume +#endif + +#endif /* defined(__s390x__) */ + + .cfi_endproc + .size __morestack, . - __morestack + + +# The exception table. This tells the personality routine to execute +# the exception handler. + + .section .gcc_except_table,"a",@progbits + .align 4 +.LLSDA1: + .byte 0xff # @LPStart format (omit) + .byte 0xff # @TType format (omit) + .byte 0x1 # call-site format (uleb128) + .uleb128 .LLSDACSE1-.LLSDACSB1 # Call-site table length +.LLSDACSB1: + .uleb128 .LEHB0-.LFB1 # region 0 start + .uleb128 .LEHE0-.LEHB0 # length + .uleb128 .L1-.LFB1 # landing pad + .uleb128 0 # action +.LLSDACSE1: + + + .global __gcc_personality_v0 +#ifdef __PIC__ + # Build a position independent reference to the basic + # personality function. + .hidden DW.ref.__gcc_personality_v0 + .weak DW.ref.__gcc_personality_v0 + .section .data.DW.ref.__gcc_personality_v0,"awG",@progbits,DW.ref.__gcc_personality_v0,comdat + .type DW.ref.__gcc_personality_v0, @object +DW.ref.__gcc_personality_v0: +#ifndef __LP64__ + .align 4 + .size DW.ref.__gcc_personality_v0, 4 + .long __gcc_personality_v0 +#else + .align 8 + .size DW.ref.__gcc_personality_v0, 8 + .quad __gcc_personality_v0 +#endif +#endif + + + +# Initialize the stack test value when the program starts or when a +# new thread starts. We don't know how large the main stack is, so we +# guess conservatively. We might be able to use getrlimit here. + + .text + .global __stack_split_initialize + .hidden __stack_split_initialize + + .type __stack_split_initialize, @function + +__stack_split_initialize: + +#ifndef __s390x__ + + ear %r1, %a0 + lr %r0, %r15 + ahi %r0, -0x4000 # We should have at least 16K. + st %r0, 0x20(%r1) + + lr %r2, %r15 + lhi %r3, 0x4000 +#ifdef __PIC__ + jg __generic_morestack_set_initial_sp@PLT # Tail call +#else + jg __generic_morestack_set_initial_sp # Tail call +#endif + +#else /* defined(__s390x__) */ + + ear %r1, %a0 + sllg %r1, %r1, 32 + ear %r1, %a1 + lgr %r0, %r15 + aghi %r0, -0x4000 # We should have at least 16K. + stg %r0, 0x38(%r1) + + lgr %r2, %r15 + lghi %r3, 0x4000 +#ifdef __PIC__ + jg __generic_morestack_set_initial_sp@PLT # Tail call +#else + jg __generic_morestack_set_initial_sp # Tail call +#endif + +#endif /* defined(__s390x__) */ + + .size __stack_split_initialize, . - __stack_split_initialize + +# Routines to get and set the guard, for __splitstack_getcontext, +# __splitstack_setcontext, and __splitstack_makecontext. + +# void *__morestack_get_guard (void) returns the current stack guard. + .text + .global __morestack_get_guard + .hidden __morestack_get_guard + + .type __morestack_get_guard,@function + +__morestack_get_guard: + +#ifndef __s390x__ + ear %r1, %a0 + l %r2, 0x20(%r1) +#else + ear %r1, %a0 + sllg %r1, %r1, 32 + ear %r1, %a1 + lg %r2, 0x38(%r1) +#endif + br %r14 + + .size __morestack_get_guard, . - __morestack_get_guard + +# void __morestack_set_guard (void *) sets the stack guard. + .global __morestack_set_guard + .hidden __morestack_set_guard + + .type __morestack_set_guard,@function + +__morestack_set_guard: + +#ifndef __s390x__ + ear %r1, %a0 + st %r2, 0x20(%r1) +#else + ear %r1, %a0 + sllg %r1, %r1, 32 + ear %r1, %a1 + stg %r2, 0x38(%r1) +#endif + br %r14 + + .size __morestack_set_guard, . - __morestack_set_guard + +# void *__morestack_make_guard (void *, size_t) returns the stack +# guard value for a stack. + .global __morestack_make_guard + .hidden __morestack_make_guard + + .type __morestack_make_guard,@function + +__morestack_make_guard: + +#ifndef __s390x__ + sr %r2, %r3 + ahi %r2, BACKOFF +#else + sgr %r2, %r3 + aghi %r2, BACKOFF +#endif + br %r14 + + .size __morestack_make_guard, . - __morestack_make_guard + +# Make __stack_split_initialize a high priority constructor. + + .section .ctors.65535,"aw",@progbits + +#ifndef __LP64__ + .align 4 + .long __stack_split_initialize + .long __morestack_load_mmap +#else + .align 8 + .quad __stack_split_initialize + .quad __morestack_load_mmap +#endif + + .section .note.GNU-stack,"",@progbits + .section .note.GNU-split-stack,"",@progbits + .section .note.GNU-no-split-stack,"",@progbits diff --git a/libgcc/config/s390/t-stack-s390 b/libgcc/config/s390/t-stack-s390 new file mode 100644 index 00000000000..4c959b036de --- /dev/null +++ b/libgcc/config/s390/t-stack-s390 @@ -0,0 +1,2 @@ +# Makefile fragment to support -fsplit-stack for s390. +LIB2ADD_ST += $(srcdir)/config/s390/morestack.S diff --git a/libgcc/generic-morestack.c b/libgcc/generic-morestack.c index 89765d45ede..b8eec4e7395 100644 --- a/libgcc/generic-morestack.c +++ b/libgcc/generic-morestack.c @@ -939,6 +939,10 @@ __splitstack_find (void *segment_arg, void *sp, size_t *len, #elif defined (__i386__) nsp -= 6 * sizeof (void *); #elif defined __powerpc64__ +#elif defined __s390x__ + nsp -= 2 * 160; +#elif defined __s390__ + nsp -= 2 * 96; #else #error "unrecognized target" #endif |