Re: [PATCH] Extend -fno-plt to normal non-PIC branches on x86

2015-06-01 Thread Uros Bizjak
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

2015-05-28 Thread H.J. Lu
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

2015-05-28 Thread H.J. Lu
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