diff mbox series

[RS6000] Don't support inline PLT for ABI_V4 bss-plt

Message ID 20190208003557.GC5398@bubble.grove.modra.org
State New
Headers show
Series [RS6000] Don't support inline PLT for ABI_V4 bss-plt | expand

Commit Message

Alan Modra Feb. 8, 2019, 12:35 a.m. UTC
Inline PLT calls need PLT to be an array of addresses.  bss-plt works
differently.

Bootstrap and regression test on powerpc64-linux biarch in progress.
OK assuming no regressions?

	* config/rs6000/rs6000.c (rs6000_longcall_ref): Don't use
	inline plt for ABI_V4 bss-plt.
	(rs6000_call_sysv): Likewise.

Comments

Segher Boessenkool Feb. 8, 2019, 10:53 p.m. UTC | #1
Hi Alan,

On Fri, Feb 08, 2019 at 11:05:57AM +1030, Alan Modra wrote:
> Inline PLT calls need PLT to be an array of addresses.  bss-plt works
> differently.
> 
> Bootstrap and regression test on powerpc64-linux biarch in progress.
> OK assuming no regressions?
> 
> 	* config/rs6000/rs6000.c (rs6000_longcall_ref): Don't use
> 	inline plt for ABI_V4 bss-plt.
> 	(rs6000_call_sysv): Likewise.
> 
> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index 711278c7422..cced90bb518 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -32819,7 +32819,8 @@ rs6000_longcall_ref (rtx call_ref, rtx arg)
>      }
>  
>    if (HAVE_AS_PLTSEQ
> -      && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4))
> +      && (DEFAULT_ABI == ABI_ELFv2
> +	  || (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT)))
>      {
>        rtx base = const0_rtx;
>        int regno;
> @@ -37981,7 +37982,7 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
>        func = rs6000_longcall_ref (func_desc, tlsarg);
>        /* If the longcall was implemented using PLT16 relocs, then r11
>  	 needs to be valid at the call for lazy linking.  */

This comment could use some work.

> -      if (HAVE_AS_PLTSEQ)
> +      if (HAVE_AS_PLTSEQ && REGNO (func) == 11)

This (and all occurrences below) need some explanation.  It is probably
best if you factor out

  bool something = (REGNO (func) == 11));

(with a descriptive name) and use that?

The patch is okay (for all branches) with those things improved.  Thanks!


Segher
Alan Modra Feb. 11, 2019, 12:38 a.m. UTC | #2
On Fri, Feb 08, 2019 at 04:53:44PM -0600, Segher Boessenkool wrote:
> > @@ -37981,7 +37982,7 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
> >        func = rs6000_longcall_ref (func_desc, tlsarg);
> >        /* If the longcall was implemented using PLT16 relocs, then r11
> >  	 needs to be valid at the call for lazy linking.  */
> 
> This comment could use some work.

True.  I've rectified that and combined this patch with the
-mno-pltseq patch, documented as requested and enhanced to emit errors
and warnings when invalid options are combined.  The two patches go
together, because someone building their ppc32 compiler with
--enable-secureplt but having old -mbss-plt relocatable objects on
their system will find that linking new -msecure-plt -mlongcall
objects against -mbss-plt objects will fail.  One solution to that
problem is to compile with -mbss-plt whenever -mlongcall is needed,
but -mlongcall -mno-pltseq provides a way to transition everything to
-msecure-plt objects.

Bootstrapped and regression tested powerpc64le-linux and
powerpc64-linux biarch.  I also built an rs6000-aix7.2 cross compiler
(well, cc1 and cc1plus, I don't have the aix headers to build libgcc)
to ensure the patch didn't introduce undefined references in powerpc 
targets not using sysv4.h.  OK for mainline?

I'd also like to fix the formatting in linux64.h
SUBSUBTARGET_OVERRIDE_OPTIONS by moving all the continuation
backslashes one tab stop to the right when I commit this patch.  Is
that OK too?

	* doc/invoke.texi (man page RS/6000 and PowerPC Options): Mention
	-mlongcall and -mpltseq.
	(RS/6000 and PowerPC Options <-mlongcall>): Mention inline PLT calls.
	(RS/6000 and PowerPC Options <-mpltseq>): Document.
	* config/rs6000/rs6000.h (TARGET_PLTSEQ): Define.
	* config/rs6000/sysv4.opt (mpltseq): New option.
	* config/rs6000/sysv4.h (TARGET_PLTSEQ): Redefine.
	(SUBTARGET_OVERRIDE_OPTIONS): Error if given -mpltseq when assembler
	support is lacking.  Don't allow -mpltseq with -mbss-plt.
	* config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Warn if
	-mpltseq given for ELFv1.
	* config/rs6000/rs6000.c (rs6000_call_aix): Comment on UNSPEC_PLTSEQ.
	Only use UNSPEC_PLTSEQ for inline PLT calls.
	(rs6000_call_sysv, rs6000_sibcall_sysv): Expand comments.  Only
	use UNSPEC_PLTSEQ for inline PLT calls.
	(rs6000_indirect_call_template_1, rs6000_longcall_ref),
	(rs6000_call_aix, rs6000_call_sysv, rs6000_sibcall_sysv): Replace
	uses of HAVE_AS_PLTSEQ with TARGET_PLTSEQ, simplifying.
	* config/rs6000/rs6000.md (pltseq_tocsave_<mode>),
	(pltseq_plt16_ha_<mode>, pltseq_plt16_lo_<mode>),
	(pltseq_mtctr_<mode>): Likewise.

diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 29e9afa7f3d..df1d8a9f45a 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -155,6 +155,13 @@ extern int dot_symbols;
 		    TARGET_NO_SUM_IN_TOC = 0;			\
 		}						\
 	    }							\
+	  if (TARGET_PLTSEQ && DEFAULT_ABI != ABI_ELFv2)	\
+	    {							\
+	      if (global_options_set.x_rs6000_pltseq)		\
+		warning (0, "%qs unsupported for this ABI",	\
+			 "-mpltseq");				\
+	      rs6000_pltseq = false;				\
+	    }							\
 	}							\
       else							\
 	{							\
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b4ff18d414c..99f04bba148 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -21665,7 +21665,7 @@ rs6000_indirect_call_template_1 (rtx *operands, unsigned int funop,
 		    || (REG_P (operands[funop])
 			&& REGNO (operands[funop]) == LR_REGNO));
 
-  if (!TARGET_MACHO && HAVE_AS_PLTSEQ && GET_CODE (operands[funop]) == UNSPEC)
+  if (!TARGET_MACHO && TARGET_PLTSEQ && GET_CODE (operands[funop]) == UNSPEC)
     {
       const char *rel64 = TARGET_64BIT ? "64" : "";
       char tls[29];
@@ -32827,8 +32827,7 @@ rs6000_longcall_ref (rtx call_ref, rtx arg)
       call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
     }
 
-  if (HAVE_AS_PLTSEQ
-      && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4))
+  if (TARGET_PLTSEQ)
     {
       rtx base = const0_rtx;
       int regno;
@@ -37793,14 +37792,20 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
   rtx call[4];
   int n_call;
   rtx insn;
+  bool is_pltseq_longcall;
 
   if (global_tlsarg)
     tlsarg = global_tlsarg;
 
   /* Handle longcall attributes.  */
+  is_pltseq_longcall = false;
   if ((INTVAL (cookie) & CALL_LONG) != 0
       && GET_CODE (func_desc) == SYMBOL_REF)
-    func = rs6000_longcall_ref (func_desc, tlsarg);
+    {
+      func = rs6000_longcall_ref (func_desc, tlsarg);
+      if (TARGET_PLTSEQ)
+	is_pltseq_longcall = true;
+    }
 
   /* Handle indirect calls.  */
   if (!SYMBOL_REF_P (func)
@@ -37825,10 +37830,12 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
 					     gen_rtx_PLUS (Pmode, stack_ptr,
 							   stack_toc_offset));
 	  MEM_VOLATILE_P (stack_toc_mem) = 1;
-	  if (HAVE_AS_PLTSEQ
-	      && DEFAULT_ABI == ABI_ELFv2
-	      && GET_CODE (func_desc) == SYMBOL_REF)
+	  if (is_pltseq_longcall)
 	    {
+	      /* Use USPEC_PLTSEQ here to emit every instruction in an
+		 inline PLT call sequence with a reloc, enabling the
+		 linker to edit the sequence back to a direct call
+		 when that makes sense.  */
 	      rtvec v = gen_rtvec (3, toc_reg, func_desc, tlsarg);
 	      rtx mark_toc_reg = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ);
 	      emit_insn (gen_rtx_SET (stack_toc_mem, mark_toc_reg));
@@ -37849,8 +37856,7 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
 	     calls via LR, so move the address there.  Needed to mark
 	     this insn for linker plt sequence editing too.  */
 	  func_addr = gen_rtx_REG (Pmode, CTR_REGNO);
-	  if (HAVE_AS_PLTSEQ
-	      && GET_CODE (func_desc) == SYMBOL_REF)
+	  if (is_pltseq_longcall)
 	    {
 	      rtvec v = gen_rtvec (3, abi_reg, func_desc, tlsarg);
 	      rtx mark_func = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ);
@@ -37988,9 +37994,15 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
       && GET_CODE (func_desc) == SYMBOL_REF)
     {
       func = rs6000_longcall_ref (func_desc, tlsarg);
-      /* If the longcall was implemented using PLT16 relocs, then r11
-	 needs to be valid at the call for lazy linking.  */
-      if (HAVE_AS_PLTSEQ)
+      /* If the longcall was implemented as an inline PLT call using
+	 PLT unspecs then func will be REG:r11.  If not, func will be
+	 a pseudo reg.  The inline PLT call sequence supports lazy
+	 linking (and longcalls to functions in dlopen'd libraries).
+	 The other style of longcalls don't.  The lazy linking entry
+	 to the dynamic symbol resolver requires r11 be the function
+	 address (as it is for linker generated PLT stubs).  Ensure
+	 r11 stays valid to the bctrl by marking r11 used by the call.  */
+      if (TARGET_PLTSEQ)
 	abi_reg = func;
     }
 
@@ -38000,11 +38012,12 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
       func = force_reg (Pmode, func);
 
       /* Indirect calls via CTR are strongly preferred over indirect
-	 calls via LR, so move the address there.  Needed to mark
-	 this insn for linker plt sequence editing too.  */
+	 calls via LR, so move the address there.  That can't be left
+	 to reload because we want to mark every instruction in an
+	 inline PLT call sequence with a reloc, enabling the linker to
+	 edit the sequence back to a direct call when that makes sense.  */
       func_addr = gen_rtx_REG (Pmode, CTR_REGNO);
-      if (HAVE_AS_PLTSEQ
-	  && GET_CODE (func_desc) == SYMBOL_REF)
+      if (abi_reg)
 	{
 	  rtvec v = gen_rtvec (3, func, func_desc, tlsarg);
 	  rtx mark_func = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ);
@@ -38058,9 +38071,15 @@ rs6000_sibcall_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
       && GET_CODE (func_desc) == SYMBOL_REF)
     {
       func = rs6000_longcall_ref (func_desc, tlsarg);
-      /* If the longcall was implemented using PLT16 relocs, then r11
-	 needs to be valid at the call for lazy linking.  */
-      if (HAVE_AS_PLTSEQ)
+      /* If the longcall was implemented as an inline PLT call using
+	 PLT unspecs then func will be REG:r11.  If not, func will be
+	 a pseudo reg.  The inline PLT call sequence supports lazy
+	 linking (and longcalls to functions in dlopen'd libraries).
+	 The other style of longcalls don't.  The lazy linking entry
+	 to the dynamic symbol resolver requires r11 be the function
+	 address (as it is for linker generated PLT stubs).  Ensure
+	 r11 stays valid to the bctr by marking r11 used by the call.  */
+      if (TARGET_PLTSEQ)
 	abi_reg = func;
     }
 
@@ -38069,11 +38088,12 @@ rs6000_sibcall_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
     {
       func = force_reg (Pmode, func);
 
-      /* Indirect sibcalls must go via CTR.  Needed to mark
-	 this insn for linker plt sequence editing too.  */
+      /* Indirect sibcalls must go via CTR.  That can't be left to
+	 reload because we want to mark every instruction in an inline
+	 PLT call sequence with a reloc, enabling the linker to edit
+	 the sequence back to a direct call when that makes sense.  */
       func_addr = gen_rtx_REG (Pmode, CTR_REGNO);
-      if (HAVE_AS_PLTSEQ
-	  && GET_CODE (func_desc) == SYMBOL_REF)
+      if (abi_reg)
 	{
 	  rtvec v = gen_rtvec (3, func, func_desc, tlsarg);
 	  rtx mark_func = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ);
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index bfe557d6325..3b705255219 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -226,6 +226,10 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 #define HAVE_AS_PLTSEQ 0
 #endif
 
+#ifndef TARGET_PLTSEQ
+#define TARGET_PLTSEQ 0
+#endif
+
 #ifndef TARGET_LINK_STACK
 #define TARGET_LINK_STACK 0
 #endif
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index d246c30d136..5bca96b70d1 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -10179,7 +10179,7 @@ (define_insn "*pltseq_tocsave_<mode>"
 		   (match_operand:P 2 "symbol_ref_operand" "s")
 		   (match_operand:P 3 "" "")]
 		  UNSPEC_PLTSEQ))]
-  "HAVE_AS_PLTSEQ
+  "TARGET_PLTSEQ
    && DEFAULT_ABI == ABI_ELFv2"
 {
   return rs6000_pltseq_template (operands, 0);
@@ -10191,8 +10191,7 @@ (define_insn "*pltseq_plt16_ha_<mode>"
 		   (match_operand:P 2 "symbol_ref_operand" "s")
 		   (match_operand:P 3 "" "")]
 		  UNSPEC_PLT16_HA))]
-  "HAVE_AS_PLTSEQ
-   && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)"
+  "TARGET_PLTSEQ"
 {
   return rs6000_pltseq_template (operands, 1);
 })
@@ -10203,8 +10202,7 @@ (define_insn "*pltseq_plt16_lo_<mode>"
 		   (match_operand:P 2 "symbol_ref_operand" "s")
 		   (match_operand:P 3 "" "")]
 		  UNSPEC_PLT16_LO))]
-  "HAVE_AS_PLTSEQ
-   && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)"
+  "TARGET_PLTSEQ"
 {
   return rs6000_pltseq_template (operands, 2);
 }
@@ -10216,8 +10214,7 @@ (define_insn "*pltseq_mtctr_<mode>"
 		   (match_operand:P 2 "symbol_ref_operand" "s")
 		   (match_operand:P 3 "" "")]
 		  UNSPEC_PLTSEQ))]
-  "HAVE_AS_PLTSEQ
-   && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)"
+  "TARGET_PLTSEQ"
 {
   return rs6000_pltseq_template (operands, 3);
 })
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 22452b3c4f0..3861efdfee6 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -59,6 +59,11 @@
 #define TARGET_SECURE_PLT	secure_plt
 #endif
 
+#if HAVE_AS_PLTSEQ
+#undef TARGET_PLTSEQ
+#define TARGET_PLTSEQ rs6000_pltseq
+#endif
+
 #define SDATA_DEFAULT_SIZE 8
 
 /* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to
@@ -192,6 +197,26 @@ do {									\
       error ("%qs not supported by your assembler", "-msecure-plt");	\
     }									\
 									\
+  if (TARGET_PLTSEQ != rs6000_pltseq					\
+      && global_options_set.x_rs6000_pltseq)				\
+    {									\
+      error ("%qs not supported by your assembler", "-mpltseq");	\
+    }									\
+									\
+  if (DEFAULT_ABI == ABI_V4 && TARGET_PLTSEQ && !TARGET_SECURE_PLT)	\
+    {									\
+      if (global_options_set.x_rs6000_pltseq)				\
+	{								\
+	  if (global_options_set.x_secure_plt)				\
+	    error ("%qs and %qs are incompatible",			\
+		   "-mpltseq", "-mbss-plt");				\
+	  else								\
+	    secure_plt = true;						\
+	}								\
+      if (!TARGET_SECURE_PLT)						\
+	rs6000_pltseq = false;						\
+    }									\
+									\
   if (flag_pic > 1 && DEFAULT_ABI == ABI_V4)				\
     {									\
       /* Note: flag_pic should not change any option flags that would	\
diff --git a/gcc/config/rs6000/sysv4.opt b/gcc/config/rs6000/sysv4.opt
index 45399a08806..07e6df72495 100644
--- a/gcc/config/rs6000/sysv4.opt
+++ b/gcc/config/rs6000/sysv4.opt
@@ -160,6 +160,10 @@ mbss-plt
 Target Report RejectNegative Var(secure_plt, 0) Save
 Generate code for old exec BSS PLT.
 
+mpltseq
+Target Report Var(rs6000_pltseq) Init(1) Save
+Use inline plt sequences to implement long calls and -fno-plt.
+
 mgnu-attribute
 Target Report Var(rs6000_gnu_attr) Init(1) Save
 Emit .gnu_attribute tags.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index c625350d04d..7bf14c1c08d 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1095,6 +1095,7 @@ See RS/6000 and PowerPC Options.
 -mtraceback=@var{traceback_type} @gol
 -maix-struct-return  -msvr4-struct-return @gol
 -mabi=@var{abi-type}  -msecure-plt  -mbss-plt @gol
+-mlongcall  -mno-longcall  -mpltseq  -mno-pltseq  @gol
 -mblock-move-inline-limit=@var{num} @gol
 -mblock-compare-inline-limit=@var{num} @gol
 -mblock-compare-inline-loop-limit=@var{num} @gol
@@ -24834,6 +24835,11 @@ generate slower code.  As of this writing, the AIX linker can do this,
 as can the GNU linker for PowerPC/64.  It is planned to add this feature
 to the GNU linker for 32-bit PowerPC systems as well.
 
+On PowerPC64le and 32-bit PowerPC systems with newer GNU linkers, GCC
+can generate long calls using an inline PLT call sequence (see
+@option{-mpltseq}).  PowerPC with @option{-mbss-plt} and PowerPC64
+ELFv1 (big-endian) do not support inline PLT calls.
+
 On Darwin/PPC systems, @code{#pragma longcall} generates @code{jbsr
 callee, L42}, plus a @dfn{branch island} (glue code).  The two target
 addresses represent the callee and the branch island.  The
@@ -24851,6 +24857,20 @@ to use or discard it.
 In the future, GCC may ignore all longcall specifications
 when the linker is known to generate glue.
 
+@item -mpltseq
+@itemx -mno-pltseq
+@opindex mpltseq
+@opindex mno-pltseq
+Implement (do not implement) -fno-plt and long calls using an inline
+PLT call sequence that supports lazy linking and long calls to
+functions in dlopen'd shared libraries.  Inline PLT calls are only
+supported on PowerPC64le and 32-bit PowerPC systems with newer GNU
+linkers, and are enabled by default if the support is detected when
+configuring GCC, and, in the case of 32-bit PowerPC, if GCC is
+configured with @option{--enable-secureplt}.  @option{-mpltseq} code
+and @option{-mbss-plt} 32-bit PowerPC relocatable objects may not be
+linked together.
+
 @item -mtls-markers
 @itemx -mno-tls-markers
 @opindex mtls-markers
Segher Boessenkool Feb. 11, 2019, 12:09 p.m. UTC | #3
Hi!

On Mon, Feb 11, 2019 at 11:08:12AM +1030, Alan Modra wrote:
> On Fri, Feb 08, 2019 at 04:53:44PM -0600, Segher Boessenkool wrote:
> > > @@ -37981,7 +37982,7 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
> > >        func = rs6000_longcall_ref (func_desc, tlsarg);
> > >        /* If the longcall was implemented using PLT16 relocs, then r11
> > >  	 needs to be valid at the call for lazy linking.  */
> > 
> > This comment could use some work.
> 
> True.  I've rectified that and combined this patch with the
> -mno-pltseq patch, documented as requested and enhanced to emit errors
> and warnings when invalid options are combined.  The two patches go
> together, because someone building their ppc32 compiler with
> --enable-secureplt but having old -mbss-plt relocatable objects on
> their system will find that linking new -msecure-plt -mlongcall
> objects against -mbss-plt objects will fail.  One solution to that
> problem is to compile with -mbss-plt whenever -mlongcall is needed,
> but -mlongcall -mno-pltseq provides a way to transition everything to
> -msecure-plt objects.

Okay.  The best is much nicer now, thanks!

> Bootstrapped and regression tested powerpc64le-linux and
> powerpc64-linux biarch.  I also built an rs6000-aix7.2 cross compiler
> (well, cc1 and cc1plus, I don't have the aix headers to build libgcc)

There are gcc111 and gcc119 in the cfarm.  Bootstrap is slow, but
--disable-bootstrap is okayish (but a bit fiddly).  You could also just
make a sysroot from them (no idea if that works, I haven't tried).

> I'd also like to fix the formatting in linux64.h
> SUBSUBTARGET_OVERRIDE_OPTIONS by moving all the continuation
> backslashes one tab stop to the right when I commit this patch.  Is
> that OK too?

I wonder if we could get rid of that completely?  Use an inline function
instead?  Or a real function, shock horror.

> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index b4ff18d414c..99f04bba148 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -21665,7 +21665,7 @@ rs6000_indirect_call_template_1 (rtx *operands, unsigned int funop,
>  		    || (REG_P (operands[funop])
>  			&& REGNO (operands[funop]) == LR_REGNO));
>  
> -  if (!TARGET_MACHO && HAVE_AS_PLTSEQ && GET_CODE (operands[funop]) == UNSPEC)
> +  if (!TARGET_MACHO && TARGET_PLTSEQ && GET_CODE (operands[funop]) == UNSPEC)

Does this need !TARGET_MACHO?  That's implied by TARGET_PLTSEQ?

> @@ -24834,6 +24835,11 @@ generate slower code.  As of this writing, the AIX linker can do this,
>  as can the GNU linker for PowerPC/64.  It is planned to add this feature
>  to the GNU linker for 32-bit PowerPC systems as well.
>  
> +On PowerPC64le and 32-bit PowerPC systems with newer GNU linkers, GCC

The mixed capitalisation in "PowerPC64le" makes my head hurt.  Luckily,
what you really mean are PowerPC64 ELFv2 systems.  Right?  (Once more
below).

Okay for trunk, with those little tweaks (the inline thing is for another
day of course).

This was the last linker-related thing for GCC 9, right?

Thanks,


Segher
diff mbox series

Patch

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 711278c7422..cced90bb518 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -32819,7 +32819,8 @@  rs6000_longcall_ref (rtx call_ref, rtx arg)
     }
 
   if (HAVE_AS_PLTSEQ
-      && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4))
+      && (DEFAULT_ABI == ABI_ELFv2
+	  || (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT)))
     {
       rtx base = const0_rtx;
       int regno;
@@ -37981,7 +37982,7 @@  rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
       func = rs6000_longcall_ref (func_desc, tlsarg);
       /* If the longcall was implemented using PLT16 relocs, then r11
 	 needs to be valid at the call for lazy linking.  */
-      if (HAVE_AS_PLTSEQ)
+      if (HAVE_AS_PLTSEQ && REGNO (func) == 11)
 	abi_reg = func;
     }
 
@@ -37994,7 +37995,7 @@  rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
 	 calls via LR, so move the address there.  Needed to mark
 	 this insn for linker plt sequence editing too.  */
       func_addr = gen_rtx_REG (Pmode, CTR_REGNO);
-      if (HAVE_AS_PLTSEQ
+      if (HAVE_AS_PLTSEQ && REGNO (func) == 11
 	  && GET_CODE (func_desc) == SYMBOL_REF)
 	{
 	  rtvec v = gen_rtvec (3, func, func_desc, tlsarg);
@@ -38051,7 +38052,7 @@  rs6000_sibcall_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
       func = rs6000_longcall_ref (func_desc, tlsarg);
       /* If the longcall was implemented using PLT16 relocs, then r11
 	 needs to be valid at the call for lazy linking.  */
-      if (HAVE_AS_PLTSEQ)
+      if (HAVE_AS_PLTSEQ && REGNO (func) == 11)
 	abi_reg = func;
     }
 
@@ -38063,7 +38064,7 @@  rs6000_sibcall_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
       /* Indirect sibcalls must go via CTR.  Needed to mark
 	 this insn for linker plt sequence editing too.  */
       func_addr = gen_rtx_REG (Pmode, CTR_REGNO);
-      if (HAVE_AS_PLTSEQ
+      if (HAVE_AS_PLTSEQ && REGNO (func) == 11
 	  && GET_CODE (func_desc) == SYMBOL_REF)
 	{
 	  rtvec v = gen_rtvec (3, func, func_desc, tlsarg);