From: Alan Modra Date: Mon, 11 Feb 2019 15:19:59 +0000 (+1030) Subject: [RS6000] No inline PLT for V4 bss-plt, implement -mno-pltseq X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ff7fa4886350037f892f9565f5a26c3ecd7ffc16;p=gcc.git [RS6000] No inline PLT for V4 bss-plt, implement -mno-pltseq Inline PLT calls need PLT to be an array of addresses. PowerPC 32-bit bss-plt works differently, so this patch disables inline PLT calls when -mbss-plt. The patch also adds support for a new -mno-pltseq option, which may be required when linking with -mbss-plt code. * 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_), (pltseq_plt16_ha_, pltseq_plt16_lo_), (pltseq_mtctr_): Likewise. From-SVN: r268770 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bea63a9e09a..b43bf022066 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +2019-02-11 Alan Modra + + * 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_), + (pltseq_plt16_ha_, pltseq_plt16_lo_), + (pltseq_mtctr_): Likewise. + 2019-02-11 Rainer Orth * acinclude.m4 (gcc_AC_INITFINI_ARRAY): Use 8-byte strings with 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..b4db03203a2 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_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 @@ (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 @@ (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 @@ (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 @@ (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..f5044a6294d 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 PowerPC64 ELFv2 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 PowerPC64 ELFv2 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