Re: [PATCH] Extend -fno-plt to normal non-PIC branches on x86
On Fri, May 29, 2015 at 1:02 AM, H.J. Lu wrote: > On Thu, May 28, 2015 at 10:37:53AM -0700, H.J. Lu wrote: >> This patch extends -fno-plt to normal non-PIC calls on x86. -fno-plt >> works in 64-bit mode with the existing binutils. For 32-bit, we need >> the updated assembler and linker to support "call/jmp *foo@GOT" with >> a new relocation different from R_386_GOT32 to indicate that this >> relocation applies to indirect branches. A configure time check is >> added to verify that 32-bit assembler generates a known relocation >> which is different from R_386_GOT32. A new 32-bit relocaton is needed >> since "call/jmp *foo@GOT" requires a different relocation from R_386_GOT32 >> which is used together with a GOT register in "call/jmp *foo@GOT(%reg)". >> >> OK for master? >> >> Thanks. >> >> H.J. >> --- >> * configure.ac (HAVE_AS_INDIRECT_BRANCH_VIA_GOT): New. Defined >> if 32-bit assembler generates a known relocation which is >> different from R_386_GOT32. >> * config.in: Regenerated. >> * configure: Likewise. >> * config/i386/i386.c (ix86_output_call_insn): Extend -fno-plt >> to normal non-PIC branches. > > > Here is the updated patch to properly handle local functions with > testcases. Please get someone to review the functional aspect of the patch. I'm not that familiar with all linker details to do any meaningful review here. Uros.
Re: [PATCH] Extend -fno-plt to normal non-PIC branches on x86
On Thu, May 28, 2015 at 10:37:53AM -0700, H.J. Lu wrote: > This patch extends -fno-plt to normal non-PIC calls on x86. -fno-plt > works in 64-bit mode with the existing binutils. For 32-bit, we need > the updated assembler and linker to support "call/jmp *foo@GOT" with > a new relocation different from R_386_GOT32 to indicate that this > relocation applies to indirect branches. A configure time check is > added to verify that 32-bit assembler generates a known relocation > which is different from R_386_GOT32. A new 32-bit relocaton is needed > since "call/jmp *foo@GOT" requires a different relocation from R_386_GOT32 > which is used together with a GOT register in "call/jmp *foo@GOT(%reg)". > > OK for master? > > Thanks. > > H.J. > --- > * configure.ac (HAVE_AS_INDIRECT_BRANCH_VIA_GOT): New. Defined > if 32-bit assembler generates a known relocation which is > different from R_386_GOT32. > * config.in: Regenerated. > * configure: Likewise. > * config/i386/i386.c (ix86_output_call_insn): Extend -fno-plt > to normal non-PIC branches. Here is the updated patch to properly handle local functions with testcases. H.J. --- gcc/ * configure.ac (HAVE_AS_INDIRECT_BRANCH_VIA_GOT): New. Defined if 32-bit assembler generates a known relocation which is different from R_386_GOT32. * config.in: Regenerated. * configure: Likewise. * config/i386/i386.c (ix86_output_call_insn): Extend -fno-plt to normal non-PIC branches. * config/i386/i386.h (TARGET_ELF): New. gcc/testsuite/ * gcc.target/i386/pr66232-6.c: New tests. * gcc.target/i386/pr66232-7.c: Likewise. * gcc.target/i386/pr66232-8.c: Likewise. * gcc.target/i386/pr66232-9.c: Likewise. * gcc.target/i386/pr66232-10.c: Likewise. * gcc.target/i386/pr66232-11.c: Likewise. * gcc.target/i386/pr66232-12.c: Likewise. * gcc.target/i386/pr66232-13.c: Likewise. * lib/target-supports.exp (check_effective_target_branch_via_got): New. --- gcc/config.in | 14 +--- gcc/config/i386/i386.c | 40 +-- gcc/config/i386/i386.h | 2 ++ gcc/configure | 47 ++- gcc/configure.ac | 18 ++- gcc/testsuite/gcc.target/i386/pr66232-10.c | 13 gcc/testsuite/gcc.target/i386/pr66232-11.c | 14 gcc/testsuite/gcc.target/i386/pr66232-12.c | 13 gcc/testsuite/gcc.target/i386/pr66232-13.c | 13 gcc/testsuite/gcc.target/i386/pr66232-6.c | 13 gcc/testsuite/gcc.target/i386/pr66232-7.c | 14 gcc/testsuite/gcc.target/i386/pr66232-8.c | 13 gcc/testsuite/gcc.target/i386/pr66232-9.c | 13 gcc/testsuite/lib/target-supports.exp | 52 ++ 14 files changed, 271 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-10.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-11.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-12.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-13.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-6.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-7.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-8.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-9.c diff --git a/gcc/config.in b/gcc/config.in index daaf906..0ee5c38 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -363,6 +363,12 @@ #endif +/* Define true if the assembler supports 'call *foo@GOT'. */ +#ifndef USED_FOR_TARGET +#undef HAVE_AS_INDIRECT_BRANCH_VIA_GOT +#endif + + /* Define if your assembler supports the Sun syntax for cmov. */ #ifndef USED_FOR_TARGET #undef HAVE_AS_IX86_CMOV_SUN_SYNTAX @@ -686,8 +692,8 @@ #endif -/* Define to 1 if we found a declaration for 'basename', otherwise define to - 0. */ +/* Define to 1 if you have the declaration of `basename(const char*)', and to + 0 if you don't. */ #ifndef USED_FOR_TARGET #undef HAVE_DECL_BASENAME #endif @@ -963,8 +969,8 @@ #endif -/* Define to 1 if we found a declaration for 'strstr', otherwise define to 0. - */ +/* Define to 1 if you have the declaration of `strstr(const char*,const + char*)', and to 0 if you don't. */ #ifndef USED_FOR_TARGET #undef HAVE_DECL_STRSTR #endif diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index e77cd04..63ebc7f 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -25611,7 +25611,25 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) if (SIBLING_CALL_P (insn)) { if (direct_p) - xasm = "%!jmp\t%P0"; + { + if (!SYMBOL_REF_LOCAL_P (call_op) + && !flag_plt + && !flag_pic + && TARGET_ELF) + { + /* Avoid PLT. */ +
[PATCH] Extend -fno-plt to normal non-PIC branches on x86
This patch extends -fno-plt to normal non-PIC calls on x86. -fno-plt works in 64-bit mode with the existing binutils. For 32-bit, we need the updated assembler and linker to support "call/jmp *foo@GOT" with a new relocation different from R_386_GOT32 to indicate that this relocation applies to indirect branches. A configure time check is added to verify that 32-bit assembler generates a known relocation which is different from R_386_GOT32. A new 32-bit relocaton is needed since "call/jmp *foo@GOT" requires a different relocation from R_386_GOT32 which is used together with a GOT register in "call/jmp *foo@GOT(%reg)". OK for master? Thanks. H.J. --- * configure.ac (HAVE_AS_INDIRECT_BRANCH_VIA_GOT): New. Defined if 32-bit assembler generates a known relocation which is different from R_386_GOT32. * config.in: Regenerated. * configure: Likewise. * config/i386/i386.c (ix86_output_call_insn): Extend -fno-plt to normal non-PIC branches. --- gcc/config.in | 14 ++ gcc/config/i386/i386.c | 42 -- gcc/configure | 47 ++- gcc/configure.ac | 18 +- 4 files changed, 113 insertions(+), 8 deletions(-) diff --git a/gcc/config.in b/gcc/config.in index daaf906..0ee5c38 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -363,6 +363,12 @@ #endif +/* Define true if the assembler supports 'call *foo@GOT'. */ +#ifndef USED_FOR_TARGET +#undef HAVE_AS_INDIRECT_BRANCH_VIA_GOT +#endif + + /* Define if your assembler supports the Sun syntax for cmov. */ #ifndef USED_FOR_TARGET #undef HAVE_AS_IX86_CMOV_SUN_SYNTAX @@ -686,8 +692,8 @@ #endif -/* Define to 1 if we found a declaration for 'basename', otherwise define to - 0. */ +/* Define to 1 if you have the declaration of `basename(const char*)', and to + 0 if you don't. */ #ifndef USED_FOR_TARGET #undef HAVE_DECL_BASENAME #endif @@ -963,8 +969,8 @@ #endif -/* Define to 1 if we found a declaration for 'strstr', otherwise define to 0. - */ +/* Define to 1 if you have the declaration of `strstr(const char*,const + char*)', and to 0 if you don't. */ #ifndef USED_FOR_TARGET #undef HAVE_DECL_STRSTR #endif diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index e77cd04..5ca19f2 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -25611,7 +25611,26 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) if (SIBLING_CALL_P (insn)) { if (direct_p) - xasm = "%!jmp\t%P0"; + { + if (!flag_plt + && !flag_pic + && !TARGET_MACHO + && !TARGET_SEH + && !TARGET_PECOFF) + { + /* Avoid PLT. */ + if (TARGET_64BIT) + xasm = "%!jmp\t*%p0@GOTPCREL(%%rip)"; + else +#ifdef HAVE_AS_INDIRECT_BRANCH_VIA_GOT + xasm = "%!jmp\t*%p0@GOT"; +#else + xasm = "%!jmp\t%P0"; +#endif + } + else + xasm = "%!jmp\t%P0"; + } /* SEH epilogue detection requires the indirect branch case to include REX.W. */ else if (TARGET_SEH) @@ -25654,7 +25673,26 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) } if (direct_p) -xasm = "%!call\t%P0"; +{ + if (!flag_plt + && !flag_pic + && !TARGET_MACHO + && !TARGET_SEH + && !TARGET_PECOFF) + { + /* Avoid PLT. */ + if (TARGET_64BIT) + xasm = "%!call\t*%p0@GOTPCREL(%%rip)"; + else +#ifdef HAVE_AS_INDIRECT_BRANCH_VIA_GOT + xasm = "%!call\t*%p0@GOT"; +#else + xasm = "%!call\t%P0"; +#endif + } + else + xasm = "%!call\t%P0"; +} else xasm = "%!call\t%A0"; diff --git a/gcc/configure b/gcc/configure index a9a76d6..4419035 100755 --- a/gcc/configure +++ b/gcc/configure @@ -25361,7 +25361,7 @@ $as_echo "#define HAVE_AS_IX86_DIFF_SECT_DELTA 1" >>confdefs.h fi -# These two are used unconditionally by i386.[ch]; it is to be defined +# These three are used unconditionally by i386.[ch]; it is to be defined # to 1 if the feature is present, 0 otherwise. as_ix86_gotoff_in_data_opt= if test x$gas = xyes; then @@ -25407,6 +25407,51 @@ cat >>confdefs.h <<_ACEOF _ACEOF +as_ix86_indirect_branch_via_got_opt= +if test x$gas = xyes; then + as_ix86_indirect_branch_via_got_opt="--32" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for call *foo@GOT" >&5 +$as_echo_n "checking assembler for call *foo@GOT... " >&6; } +if test "${gcc_cv_as_ix86_indirect_branch_via_got+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + gcc_cv_as_ix86_indirect_branch_via_got=no +if test $in_tree_gas = yes; then +if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 26 \) \* 1000 + 0` + then gcc_cv_as_ix86_indirect_branch_via_g