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 hongjiu...@intel.com 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.  */
+ if (TARGET_64BIT)
+  

[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_got=yes
+fi
+  elif test x$gcc_cv_as != x; then
+$as_echo '