public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-2319] [POWER10] __morestack calls from pcrel code
@ 2021-07-15  5:58 Alan Modra
  0 siblings, 0 replies; only message in thread
From: Alan Modra @ 2021-07-15  5:58 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:cd6ca96f5d530e4ee07b65ac8b075119ba5bb035

commit r12-2319-gcd6ca96f5d530e4ee07b65ac8b075119ba5bb035
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Jun 29 13:31:45 2021 +0930

    [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.

Diff:
---
 libgcc/config/rs6000/morestack.S | 41 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/libgcc/config/rs6000/morestack.S b/libgcc/config/rs6000/morestack.S
index 4a07de927c5..a2e255e5c21 100644
--- a/libgcc/config/rs6000/morestack.S
+++ b/libgcc/config/rs6000/morestack.S
@@ -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)


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-07-15  5:58 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-15  5:58 [gcc r12-2319] [POWER10] __morestack calls from pcrel code Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).