This is an automated email from the git hooks/post-receive script.
unknown user pushed a commit to branch hjl/indbr/master in repository gcc.
commit a5a47d58717c67273508335238b5c8e561046445 Author: H.J. Lu hjl.tools@gmail.com Date: Thu Jul 23 13:09:27 2015 -0700
Generate indirect branch relocation
This patch extends -fno-plt to non-PIC 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.
gcc/
* config/i386/i386.c (ix86_nopic_noplt_attribute_p): Check HAVE_LD_IX86_INDBR_RELOC == 0 before returning false. (ix86_output_call_insn): Generate "%!jmp/call\t*%p0@GOT" for 32-bit.
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_indbr_reloc): New.
HAVE_AS_INDIRECT_BRANCH_VIA_GOT --- gcc/config.in | 27 ++++++++++------ gcc/config/i386/i386.c | 36 +++++++++++++++++++-- gcc/config/i386/i386.h | 2 ++ gcc/configure | 46 +++++++++++++++++++++++++- gcc/configure.ac | 19 ++++++++++- 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, 274 insertions(+), 14 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..81392d4 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -363,6 +363,12 @@ #endif
+/* Define 0/1 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 @@ -624,12 +630,6 @@ #endif
-/* Define to 1 if you have the `atoll' function. */ -#ifndef USED_FOR_TARGET -#undef HAVE_ATOLL -#endif - - /* Define to 1 if you have the `atoq' function. */ #ifndef USED_FOR_TARGET #undef HAVE_ATOQ @@ -686,8 +686,15 @@ #endif
-/* Define to 1 if we found a declaration for 'basename', otherwise define to - 0. */ +/* Define to 1 if we found a declaration for 'atoll', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#undef HAVE_DECL_ATOLL +#endif + + +/* 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 +970,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..2a1896a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -25611,7 +25611,23 @@ 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) + xasm = "%!jmp\t*%p0@GOTPCREL(%%rip)"; + else if (HAVE_AS_INDIRECT_BRANCH_VIA_GOT) + xasm = "%!jmp\t*%p0@GOT"; + else + xasm = "%!jmp\t%P0"; + } + else + xasm = "%!jmp\t%P0"; + } /* SEH epilogue detection requires the indirect branch case to include REX.W. */ else if (TARGET_SEH) @@ -25654,7 +25670,23 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) }
if (direct_p) - xasm = "%!call\t%P0"; + { + if (!SYMBOL_REF_LOCAL_P (call_op) + && !flag_plt + && !flag_pic + && TARGET_ELF) + { + /* Avoid PLT. */ + if (TARGET_64BIT) + xasm = "%!call\t*%p0@GOTPCREL(%%rip)"; + else if (HAVE_AS_INDIRECT_BRANCH_VIA_GOT) + xasm = "%!call\t*%p0@GOT"; + else + xasm = "%!call\t%P0"; + } + else + xasm = "%!call\t%P0"; + } else xasm = "%!call\t%A0";
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 34ef343..9b7f10f 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -584,6 +584,8 @@ extern tree x86_mfence; /* This is re-defined by cygming.h. */ #define TARGET_PECOFF 0
+#define TARGET_ELF (!TARGET_MACHO && !TARGET_SEH && !TARGET_PECOFF) + /* The default abi used by target. */ #define DEFAULT_ABI SYSV_ABI
diff --git a/gcc/configure b/gcc/configure index b26a86f..ae89233 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,50 @@ 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@ [...] +$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 ' .text + call *foo@GOT' > conftest.s + if { ac_try='$gcc_cv_as $gcc_cv_as_flags $as_ix86_indirect_branch_via_got_ [...] + { { eval echo ""$as_me":${as_lineno-$LINENO}: "$ac_try""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: $? = $ac_status" >&5 + test $ac_status = 0; }; } + then + if test x$gcc_cv_readelf != x \ + && $gcc_cv_readelf -r conftest.o | grep R_386_ | grep -v R_386_GOT32 > /dev/ [...] + gcc_cv_as_ix86_indirect_branch_via_got=yes + fi + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_indirect_bran [...] +$as_echo "$gcc_cv_as_ix86_indirect_branch_via_got" >&6; } + + +cat >>confdefs.h <<_ACEOF +#define HAVE_AS_INDIRECT_BRANCH_VIA_GOT `if test x"$gcc_cv_as_ix86_indirect_br [...] +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for rep and lo [...] $as_echo_n "checking assembler for rep and lock prefix... " >&6; } if test "${gcc_cv_as_ix86_rep_lock_prefix+set}" = set; then : diff --git a/gcc/configure.ac b/gcc/configure.ac index c09f3ae5..973c25d 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -3953,7 +3953,7 @@ foo: nop [AC_DEFINE(HAVE_AS_IX86_DIFF_SECT_DELTA, 1, [Define if your assembler supports the subtraction of symbols in diffe [...]
- # 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 @@ -3971,6 +3971,23 @@ foo: nop [`if test $gcc_cv_as_ix86_gotoff_in_data = yes; then echo 1; else echo 0; fi`], [Define true if the assembler supports '.long foo@GOTOFF'.])
+ as_ix86_indirect_branch_via_got_opt= + if test x$gas = xyes; then + as_ix86_indirect_branch_via_got_opt="--32" + fi + gcc_GAS_CHECK_FEATURE([call *foo@GOT], + gcc_cv_as_ix86_indirect_branch_via_got, [2,26,0], + [$as_ix86_indirect_branch_via_got_opt], +[ .text + call *foo@GOT], + [if test x$gcc_cv_readelf != x \ + && $gcc_cv_readelf -r conftest.o | grep R_386_ | grep -v R_386_GOT32 > /dev/ [...] + gcc_cv_as_ix86_indirect_branch_via_got=yes + fi]) + AC_DEFINE_UNQUOTED(HAVE_AS_INDIRECT_BRANCH_VIA_GOT, + [`if test x"$gcc_cv_as_ix86_indirect_branch_via_got" = xyes; then echo 1 [...] + [Define 0/1 if the assembler supports 'call *foo@GOT'.]) + gcc_GAS_CHECK_FEATURE([rep and lock prefix], gcc_cv_as_ix86_rep_lock_prefix,,, [rep movsl diff --git a/gcc/testsuite/gcc.target/i386/pr66232-10.c b/gcc/testsuite/gcc.tar [...] new file mode 100644 index 0000000..e95c789 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-10.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern void bar (void) __attribute__((visibility("hidden"))); + +void +foo (void) +{ + bar (); +} + +/* { dg-final { scan-assembler-not "jmp[ \t]*.bar@GOTPCREL" { target { ! ia3 [...] +/* { dg-final { scan-assembler-not "jmp[ \t]*.bar@GOT" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-11.c b/gcc/testsuite/gcc.tar [...] new file mode 100644 index 0000000..63a1809 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-11.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern void bar (void) __attribute__((visibility("hidden"))); + +int +foo (void) +{ + bar (); + return 0; +} + +/* { dg-final { scan-assembler-not "call[ \t]*.bar@GOTPCREL" { target { ! ia [...] +/* { dg-final { scan-assembler-not "call[ \t]*.bar@GOT" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-12.c b/gcc/testsuite/gcc.tar [...] new file mode 100644 index 0000000..89bb605 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-12.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern int bar (void) __attribute__((visibility("hidden"))); + +int +foo (void) +{ + return bar (); +} + +/* { dg-final { scan-assembler-not "jmp[ \t]*.bar@GOTPCREL" { target { ! ia3 [...] +/* { dg-final { scan-assembler-not "jmp[ \t]*.bar@GOT" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-13.c b/gcc/testsuite/gcc.tar [...] new file mode 100644 index 0000000..4aec477 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-13.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern int bar (void) __attribute__((visibility("hidden"))); + +int +foo (void) +{ + return bar () + 1; +} + +/* { dg-final { scan-assembler-not "call[ \t]*.bar@GOTPCREL" { target { ! ia [...] +/* { dg-final { scan-assembler-not "call[ \t]*.bar@GOT" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-6.c b/gcc/testsuite/gcc.targ [...] new file mode 100644 index 0000000..b465e59 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-6.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern void bar (void); + +void +foo (void) +{ + bar (); +} + +/* { dg-final { scan-assembler "jmp[ \t]*.bar@GOTPCREL" { target { ! ia32 } [...] +/* { dg-final { scan-assembler "jmp[ \t]*.bar@GOT" { target { ia32 && branch [...] diff --git a/gcc/testsuite/gcc.target/i386/pr66232-7.c b/gcc/testsuite/gcc.targ [...] new file mode 100644 index 0000000..2908541 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-7.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern void bar (void); + +int +foo (void) +{ + bar (); + return 0; +} + +/* { dg-final { scan-assembler "call[ \t]*.bar@GOTPCREL" { target { ! ia32 } [...] +/* { dg-final { scan-assembler "call[ \t]*.bar@GOT" { target { ia32 && branc [...] diff --git a/gcc/testsuite/gcc.target/i386/pr66232-8.c b/gcc/testsuite/gcc.targ [...] new file mode 100644 index 0000000..c23d6bb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-8.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern int bar (void); + +int +foo (void) +{ + return bar (); +} + +/* { dg-final { scan-assembler "jmp[ \t]*.bar@GOTPCREL" { target { ! ia32 } [...] +/* { dg-final { scan-assembler "jmp[ \t]*.bar@GOT" { target { ia32 && branch [...] diff --git a/gcc/testsuite/gcc.target/i386/pr66232-9.c b/gcc/testsuite/gcc.targ [...] new file mode 100644 index 0000000..b0cd40b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-9.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern int bar (void); + +int +foo (void) +{ + return bar () + 1; +} + +/* { dg-final { scan-assembler "call[ \t]*.bar@GOTPCREL" { target { ! ia32 } [...] +/* { dg-final { scan-assembler "call[ \t]*.bar@GOT" { target { ia32 && branc [...] diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-s [...] index f0c209f..182e284 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -6320,6 +6320,58 @@ proc check_effective_target_pie_copyreloc { } { return $pie_copyreloc_available_saved }
+# Return 1 if the x86 target supports "call *foo@GOT", 0 otherwise. +# Cache the result. + +proc check_effective_target_branch_via_got { } { + global branch_via_got_available_saved + global tool + global GCC_UNDER_TEST + + if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } { + return 0 + } + + # Need auto-host.h to check linker support. + if { ![file exists ../../auto-host.h ] } { + return 0 + } + + if [info exists branch_via_got_available_saved] { + verbose "check_effective_target_branch_via_got returning saved $branch_via_go [...] + } else { + # Set up and compile to see if linker supports PIE with copy + # reloc. Include the current process ID in the file names to + # prevent conflicts with invocations for multiple testsuites. + + set src pie[pid].c + set obj pie[pid].o + + set f [open $src "w"] + puts $f "#include "../../auto-host.h"" + puts $f "#if HAVE_AS_INDIRECT_BRANCH_VIA_GOT == 0" + puts $f "# error Assembler does not support call *foo@GOT." + puts $f "#endif" + close $f + + verbose "check_effective_target_branch_via_got compiling testfile $src" 2 + set lines [${tool}_target_compile $src $obj object ""] + + file delete $src + file delete $obj + + if [string match "" $lines] then { + verbose "check_effective_target_branch_via_got testfile compilation passed" 2 + set branch_via_got_available_saved 1 + } else { + verbose "check_effective_target_branch_via_got testfile compilation failed" 2 + set branch_via_got_available_saved 0 + } + } + + return $branch_via_got_available_saved +} + # Return 1 if the target uses comdat groups.
proc check_effective_target_comdat_group {} { -- 2.4.3 --- gcc/config/i386/i386.c | 19 +++++++++-- 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 ++++++++++++++++++++++++++++++ 10 files changed, 174 insertions(+), 3 deletions(-)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 9413c87..0d11d5a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -25764,7 +25764,8 @@ static bool ix86_nopic_noplt_attribute_p (rtx call_op) { if (flag_pic || ix86_cmodel == CM_LARGE - || !TARGET_64BIT || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF + || (!TARGET_64BIT && HAVE_LD_IX86_INDBR_RELOC == 0) + || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF || SYMBOL_REF_LOCAL_P (call_op)) return false;
@@ -25789,8 +25790,14 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
if (SIBLING_CALL_P (insn)) { + /* ix86_nopic_noplt_attribute_p returns false for PIC. */ if (direct_p && ix86_nopic_noplt_attribute_p (call_op)) - xasm = "%!jmp\t*%p0@GOTPCREL(%%rip)"; + { + if (TARGET_64BIT) + xasm = "%!jmp\t*%p0@GOTPCREL(%%rip)"; + else + xasm = "%!jmp\t*%p0@GOT"; + } else if (direct_p) xasm = "%!jmp\t%P0"; /* SEH epilogue detection requires the indirect branch case @@ -25834,8 +25841,14 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) seh_nop_p = true; }
+ /* ix86_nopic_noplt_attribute_p returns false for PIC. */ if (direct_p && ix86_nopic_noplt_attribute_p (call_op)) - xasm = "%!call\t*%p0@GOTPCREL(%%rip)"; + { + if (TARGET_64BIT) + xasm = "%!call\t*%p0@GOTPCREL(%%rip)"; + else + xasm = "%!call\t*%p0@GOT"; + } else if (direct_p) xasm = "%!call\t%P0"; else diff --git a/gcc/testsuite/gcc.target/i386/pr66232-10.c b/gcc/testsuite/gcc.target/ [...] new file mode 100644 index 0000000..e95c789 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-10.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern void bar (void) __attribute__((visibility("hidden"))); + +void +foo (void) +{ + bar (); +} + +/* { dg-final { scan-assembler-not "jmp[ \t]*.bar@GOTPCREL" { target { ! ia32 } [...] +/* { dg-final { scan-assembler-not "jmp[ \t]*.bar@GOT" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-11.c b/gcc/testsuite/gcc.target/ [...] new file mode 100644 index 0000000..63a1809 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-11.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern void bar (void) __attribute__((visibility("hidden"))); + +int +foo (void) +{ + bar (); + return 0; +} + +/* { dg-final { scan-assembler-not "call[ \t]*.bar@GOTPCREL" { target { ! ia32 } [...] +/* { dg-final { scan-assembler-not "call[ \t]*.bar@GOT" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-12.c b/gcc/testsuite/gcc.target/ [...] new file mode 100644 index 0000000..89bb605 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-12.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern int bar (void) __attribute__((visibility("hidden"))); + +int +foo (void) +{ + return bar (); +} + +/* { dg-final { scan-assembler-not "jmp[ \t]*.bar@GOTPCREL" { target { ! ia32 } [...] +/* { dg-final { scan-assembler-not "jmp[ \t]*.bar@GOT" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-13.c b/gcc/testsuite/gcc.target/ [...] new file mode 100644 index 0000000..4aec477 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-13.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern int bar (void) __attribute__((visibility("hidden"))); + +int +foo (void) +{ + return bar () + 1; +} + +/* { dg-final { scan-assembler-not "call[ \t]*.bar@GOTPCREL" { target { ! ia32 } [...] +/* { dg-final { scan-assembler-not "call[ \t]*.bar@GOT" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-6.c b/gcc/testsuite/gcc.target/i [...] new file mode 100644 index 0000000..078f956 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-6.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern void bar (void); + +void +foo (void) +{ + bar (); +} + +/* { dg-final { scan-assembler "jmp[ \t]*.bar@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "jmp[ \t]*.bar@GOT" { target { ia32 && indbr_relo [...] diff --git a/gcc/testsuite/gcc.target/i386/pr66232-7.c b/gcc/testsuite/gcc.target/i [...] new file mode 100644 index 0000000..9a9ccd4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-7.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern void bar (void); + +int +foo (void) +{ + bar (); + return 0; +} + +/* { dg-final { scan-assembler "call[ \t]*.bar@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "call[ \t]*.bar@GOT" { target { ia32 && indbr_rel [...] diff --git a/gcc/testsuite/gcc.target/i386/pr66232-8.c b/gcc/testsuite/gcc.target/i [...] new file mode 100644 index 0000000..ee26f5f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-8.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern int bar (void); + +int +foo (void) +{ + return bar (); +} + +/* { dg-final { scan-assembler "jmp[ \t]*.bar@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "jmp[ \t]*.bar@GOT" { target { ia32 && indbr_relo [...] diff --git a/gcc/testsuite/gcc.target/i386/pr66232-9.c b/gcc/testsuite/gcc.target/i [...] new file mode 100644 index 0000000..eb5d602 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-9.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fno-plt" } */ + +extern int bar (void); + +int +foo (void) +{ + return bar () + 1; +} + +/* { dg-final { scan-assembler "call[ \t]*.bar@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "call[ \t]*.bar@GOT" { target { ia32 && indbr_rel [...] diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 1988301..b1437d5 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -6341,6 +6341,58 @@ proc check_effective_target_pie_copyreloc { } { return $pie_copyreloc_available_saved }
+# Return 1 if the x86 target supports "call *foo@GOT", 0 otherwise. +# Cache the result. + +proc check_effective_target_indbr_reloc { } { + global indbr_reloc_available_saved + global tool + global GCC_UNDER_TEST + + if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } { + return 0 + } + + # Need auto-host.h to check linker support. + if { ![file exists ../../auto-host.h ] } { + return 0 + } + + if [info exists indbr_reloc_available_saved] { + verbose "check_effective_target_indbr_reloc returning saved $indbr_reloc_availabl [...] + } else { + # Set up and compile to see if linker supports PIE with copy + # reloc. Include the current process ID in the file names to + # prevent conflicts with invocations for multiple testsuites. + + set src pie[pid].c + set obj pie[pid].o + + set f [open $src "w"] + puts $f "#include "../../auto-host.h"" + puts $f "#if HAVE_LD_IX86_INDBR_RELOC == 0" + puts $f "# error Assembler does not support call *foo@GOT." + puts $f "#endif" + close $f + + verbose "check_effective_target_indbr_reloc compiling testfile $src" 2 + set lines [${tool}_target_compile $src $obj object ""] + + file delete $src + file delete $obj + + if [string match "" $lines] then { + verbose "check_effective_target_indbr_reloc testfile compilation passed" 2 + set indbr_reloc_available_saved 1 + } else { + verbose "check_effective_target_indbr_reloc testfile compilation failed" 2 + set indbr_reloc_available_saved 0 + } + } + + return $indbr_reloc_available_saved +} + # Return 1 if the target uses comdat groups.
proc check_effective_target_comdat_group {} {