From: Alan Modra <amodra@gmail.com>
To: gcc-patches@gcc.gnu.org, Segher Boessenkool <segher@kernel.crashing.org>
Subject: [POWER10] __morestack calls from pcrel code
Date: Wed, 30 Jun 2021 16:25:05 +0930 [thread overview]
Message-ID: <YNwVSUSNjUn3UNv3@squeak.grove.modra.org> (raw)
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.
Bootstrapped and regression tested power64le-linux with both
-mcpu=power10 and -mcpu=power9. OK for mainline and backporting to
gcc-11 and gcc-10?
* config/rs6000/morestack.S (R2_SAVE): Define.
(__morestack): Save and restore r2. Set up r2 for called
functions.
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)
--
Alan Modra
Australia Development Lab, IBM
next reply other threads:[~2021-06-30 6:55 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-30 6:55 Alan Modra [this message]
2021-06-30 20:06 ` Tulio Magno Quites Machado Filho
2021-07-15 0:01 ` Alan Modra
2021-07-15 0:24 ` David Edelsohn
[not found] ` <YPfa4cOkPbk/mzMF@squeak.grove.modra.org>
[not found] ` <CAGWvny=ZuYZAKzMejDygoxDcr=h8uyk-oZm_wg5xaTEP8jGRsw@mail.gmail.com>
2021-07-22 4:55 ` Alan Modra
2021-07-22 6:41 ` Richard Biener
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YNwVSUSNjUn3UNv3@squeak.grove.modra.org \
--to=amodra@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=segher@kernel.crashing.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).