mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 10:54:07 +08:00
[POWER10] __morestack calls from pcrel code
Compiling gcc/testsuite/gcc.dg/split-*.c and others with -mcpu=power10 and linking with a non-pcrel libgcc results in crashes due to the power10 pcrel code not having r2 set for the generic-morestack.c functions called from __morestack. There is also a problem when non-pcrel code calls a pcrel libgcc. See the patch comments. A similar situation theoretically occurs with ELFv1 multi-toc executables, when __morestack might be located in a different toc group to its caller. This patch makes no attempt to fix that, since the gold linker does not support multi-toc (gold is needed for proper support of -fsplit-stack code) nor does gcc emit __morestack calls that support multi-toc. * config/rs6000/morestack.S (R2_SAVE): Define. (__morestack): Save and restore r2. Set up r2 for called functions.
This commit is contained in:
parent
4f3b383cf8
commit
cd6ca96f5d
@ -31,6 +31,7 @@
|
||||
#define PARAMS 48
|
||||
#endif
|
||||
#define MORESTACK_FRAMESIZE (PARAMS+96)
|
||||
#define R2_SAVE -MORESTACK_FRAMESIZE+PARAMS-8
|
||||
#define PARAMREG_SAVE -MORESTACK_FRAMESIZE+PARAMS+0
|
||||
#define STATIC_CHAIN_SAVE -MORESTACK_FRAMESIZE+PARAMS+64
|
||||
#define R29_SAVE -MORESTACK_FRAMESIZE+PARAMS+72
|
||||
@ -143,6 +144,17 @@ ENTRY0(__morestack_non_split)
|
||||
# cr7 must also be preserved.
|
||||
|
||||
ENTRY0(__morestack)
|
||||
|
||||
#if _CALL_ELF == 2
|
||||
# Functions with localentry bits of zero cannot make calls if those
|
||||
# calls might change r2. This is true generally, and also true for
|
||||
# __morestack with its special calling convention. When __morestack's
|
||||
# caller is non-pcrel but libgcc is pcrel, the functions called here
|
||||
# might modify r2. r2 must be preserved on exit, and also restored
|
||||
# for the call back to our caller.
|
||||
std %r2,R2_SAVE(%r1)
|
||||
#endif
|
||||
|
||||
# Save parameter passing registers, our arguments, lr, r29
|
||||
# and use r29 as a frame pointer.
|
||||
std %r3,PARAMREG_SAVE+0(%r1)
|
||||
@ -161,10 +173,24 @@ ENTRY0(__morestack)
|
||||
std %r12,LINKREG_SAVE(%r1)
|
||||
std %r3,NEWSTACKSIZE_SAVE(%r1) # new stack size
|
||||
mr %r29,%r1
|
||||
#if _CALL_ELF == 2
|
||||
.cfi_offset %r2,R2_SAVE
|
||||
#endif
|
||||
.cfi_offset %r29,R29_SAVE
|
||||
.cfi_def_cfa_register %r29
|
||||
stdu %r1,-MORESTACK_FRAMESIZE(%r1)
|
||||
|
||||
#if _CALL_ELF == 2 && !defined __PCREL__
|
||||
# If this isn't a pcrel libgcc then the functions we call here will
|
||||
# require r2 to be valid. If __morestack is called from pcrel code r2
|
||||
# won't be valid. Set it up.
|
||||
bcl 20,31,1f
|
||||
1:
|
||||
mflr %r12
|
||||
addis %r2,%r12,.TOC.-1b@ha
|
||||
addi %r2,%r2,.TOC.-1b@l
|
||||
#endif
|
||||
|
||||
# void __morestack_block_signals (void)
|
||||
bl JUMP_TARGET(__morestack_block_signals)
|
||||
|
||||
@ -199,6 +225,9 @@ ENTRY0(__morestack)
|
||||
# instructions after __morestack's return address.
|
||||
#
|
||||
ld %r12,LINKREG_SAVE(%r29)
|
||||
#if _CALL_ELF == 2
|
||||
ld %r2,R2_SAVE(%r29)
|
||||
#endif
|
||||
ld %r3,PARAMREG_SAVE+0(%r29) # restore arg regs
|
||||
ld %r4,PARAMREG_SAVE+8(%r29)
|
||||
ld %r5,PARAMREG_SAVE+16(%r29)
|
||||
@ -228,6 +257,15 @@ ENTRY0(__morestack)
|
||||
std %r10,PARAMREG_SAVE+56(%r29)
|
||||
#endif
|
||||
|
||||
#if _CALL_ELF == 2 && !defined __PCREL__
|
||||
# r2 was restored for calling back into our caller. Set it up again.
|
||||
bcl 20,31,1f
|
||||
1:
|
||||
mflr %r12
|
||||
addis %r2,%r12,.TOC.-1b@ha
|
||||
addi %r2,%r2,.TOC.-1b@l
|
||||
#endif
|
||||
|
||||
bl JUMP_TARGET(__morestack_block_signals)
|
||||
|
||||
# void *__generic_releasestack (size_t *pavailable)
|
||||
@ -249,6 +287,9 @@ ENTRY0(__morestack)
|
||||
# Restore return value regs, and return.
|
||||
ld %r0,LINKREG_SAVE(%r29)
|
||||
mtlr %r0
|
||||
#if _CALL_ELF == 2
|
||||
ld %r2,R2_SAVE(%r29)
|
||||
#endif
|
||||
ld %r3,PARAMREG_SAVE+0(%r29)
|
||||
ld %r4,PARAMREG_SAVE+8(%r29)
|
||||
ld %r5,PARAMREG_SAVE+16(%r29)
|
||||
|
Loading…
Reference in New Issue
Block a user