This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH x86_64] Optimize access to globals in "-fpie -pie" builds with copy relocations
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Uros Bizjak <ubizjak at gmail dot com>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, Sriraman Tallam <tmsriram at google dot com>, Jakub Jelinek <jakub at redhat dot com>
- Date: Thu, 4 Dec 2014 08:46:48 -0800
- Subject: Re: [PATCH x86_64] Optimize access to globals in "-fpie -pie" builds with copy relocations
- Authentication-results: sourceware.org; auth=none
- References: <CAFULd4aMopCHZHTWa3V=6-CwVLq1grorwRqT7yCaOfpLWYZibw at mail dot gmail dot com> <CAMe9rOok=sUB=OVdFNt369gkpNWxVgzQKjeDVQT96SrSNRS=Vw at mail dot gmail dot com> <CAFULd4Z=WaenYMr=Ke1QLQAq4bVQpkOD_Wt3nW4w9F71fuaPAw at mail dot gmail dot com> <CAMe9rOpXge0X3Dz0OvnkWw1Q9HRPmNAFhYphVuquZj856J_RXQ at mail dot gmail dot com> <CAMe9rOr6BsvSgOtM2K+JfTgLktnTa19YFrfRUdRQpRPjDjOdmg at mail dot gmail dot com> <CAMe9rOpXupztWPgTWAxGx7yP7aynAjYoJbh-5L+wJ3S=qk8CvQ at mail dot gmail dot com> <CAFULd4aTkv0wjuqZMGCmYPiGJ50tLqWtf+-V0e3U5bFUj2Gfng at mail dot gmail dot com>
On Thu, Dec 4, 2014 at 4:44 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Wed, Dec 3, 2014 at 10:35 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>
>>>>>>> It would probably help reviewers if you pointed to actual path
>>>>>>> submission [1], which unfortunately contains the explanation in the
>>>>>>> patch itself [2], which further explains that this functionality is
>>>>>>> currently only supported with gold, patched with [3].
>>>>>>>
>>>>>>> [1] https://gcc.gnu.org/ml/gcc-patches/2014-09/msg00645.html
>>>>>>> [2] https://gcc.gnu.org/ml/gcc-patches/2014-09/txt2CHtu81P1O.txt
>>>>>>> [3] https://sourceware.org/ml/binutils/2014-05/msg00092.html
>>>>>>>
>>>>>>> After a bit of the above detective work, I think that new gcc option
>>>>>>> is not necessary. The configure should detect if new functionality is
>>>>>>> supported in the linker, and auto-configure gcc to use it when
>>>>>>> appropriate.
>>>>>>
>>>>>> I think GCC option is needed since one can use -fuse-ld= to
>>>>>> change linker.
>>>>>
>>>>> IMO, nobody will use this highly special x86_64-only option. It would
>>>>> be best for gnu-ld to reach feature parity with gold as far as this
>>>>> functionality is concerned. In this case, the optimization would be
>>>>> auto-configured, and would fire automatically, without any user
>>>>> intervention.
>>>>>
>>>>
>>>> Let's do it. I implemented the same feature in bfd linker on both
>>>> master and 2.25 branch.
>>>>
>>>
>>> +bool
>>> +i386_binds_local_p (const_tree exp)
>>> +{
>>> + /* Globals marked extern are treated as local when linker copy relocations
>>> + support is available with -f{pie|PIE}. */
>>> + if (TARGET_64BIT && ix86_copyrelocs && flag_pie
>>> + && TREE_CODE (exp) == VAR_DECL
>>> + && DECL_EXTERNAL (exp) && !DECL_WEAK (exp))
>>> + return true;
>>> + return default_binds_local_p (exp);
>>> +}
>>> +
>>>
>>> It returns true with -fPIE and false without -fPIE. It is lying to compiler.
>>> Maybe legitimate_pic_address_disp_p is a better place.
>
> Agreed.
>
>> Something like this?
>
> Yes.
>
> OK, if Jakub doesn't have any objections here. Please also add
> Sriraman as author to ChangeLog entry.
>
> Thanks,
> Uros.
Here is the patch. OK to install?
Thanks.
--
H.J.
---
Normally, with -fPIE/-fpie, GCC accesses globals that are extern to the
module using the GOT. This is two instructions, one to get the address
of the global from the GOT and the other to get the value. If it turns
out that the global gets defined in the executable at link-time, it still
needs to go through the GOT as it is too late then to generate a direct
access.
Examples:
foo.cc
------
int a_glob;
int main () {
return a_glob; // defined in this file
}
With -O2 -fpie -pie, the generated code directly accesses the global via
PC-relative insn:
5e0 <main>:
mov 0x165a(%rip),%eax # 1c40 <a_glob>
foo.cc
------
extern int a_glob;
int main () {
return a_glob; // defined in this file
}
With -O2 -fpie -pie, the generated code accesses global via GOT using
two memory loads:
6f0 <main>:
mov 0x1609(%rip),%rax # 1d00 <_DYNAMIC+0x230>
mov (%rax),%eax
This is true even if in the latter case the global was defined in the
executable through a different file.
Some experiments on google benchmarks shows that the extra memory loads
affects performance by 1% to 5%.
Solution - Copy Relocations:
When the linker supports copy relocations, GCC can always assume that
the global will be defined in the executable. For globals that are truly
extern (come from shared objects), the linker will create copy relocations
and have them defined in the executable. Result is that no global access
needs to go through the GOT and hence improves performance.
This optimization only applies to undefined, non-weak global data.
Undefined, weak global data access still must go through the GOT.
This patch checks if linker supports PIE with copy reloc, which is
enabled in gold and bfd linker in bininutils 2.25, at configure time
and enables this optimization if the linker support is available.
gcc/
* configure.ac (HAVE_LD_PIE_COPYRELOC): Defined to 1 if
Linux/x86-64 linker supports PIE with copy reloc.
* config.in: Regenerated.
* configure: Likewise.
* config/i386/i386.c (legitimate_pic_address_disp_p): Allow
pc-relative address for undefined, non-weak, non-function
symbol reference in 64-bit PIE if linker supports PIE with
copy reloc.
* doc/sourcebuild.texi: Document pie_copyreloc target.
gcc/testsuite/
* gcc.target/i386/pie-copyrelocs-1.c: New test.
* gcc.target/i386/pie-copyrelocs-2.c: Likewise.
* gcc.target/i386/pie-copyrelocs-3.c: Likewise.
* gcc.target/i386/pie-copyrelocs-4.c: Likewise.
* lib/target-supports.exp (check_effective_target_pie_copyreloc):
New procedure.
From d5559a969c541e5375da9372f6925f40b87df5f3 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 4 Dec 2014 08:27:22 -0800
Subject: [PATCH] x86-64: Optimize access to globals in PIE with copy reloc
Normally, with -fPIE/-fpie, GCC accesses globals that are extern to the
module using the GOT. This is two instructions, one to get the address
of the global from the GOT and the other to get the value. If it turns
out that the global gets defined in the executable at link-time, it still
needs to go through the GOT as it is too late then to generate a direct
access.
Examples:
foo.cc
------
int a_glob;
int main () {
return a_glob; // defined in this file
}
With -O2 -fpie -pie, the generated code directly accesses the global via
PC-relative insn:
5e0 <main>:
mov 0x165a(%rip),%eax # 1c40 <a_glob>
foo.cc
------
extern int a_glob;
int main () {
return a_glob; // defined in this file
}
With -O2 -fpie -pie, the generated code accesses global via GOT using
two memory loads:
6f0 <main>:
mov 0x1609(%rip),%rax # 1d00 <_DYNAMIC+0x230>
mov (%rax),%eax
This is true even if in the latter case the global was defined in the
executable through a different file.
Some experiments on google benchmarks shows that the extra memory loads
affects performance by 1% to 5%.
Solution - Copy Relocations:
When the linker supports copy relocations, GCC can always assume that
the global will be defined in the executable. For globals that are truly
extern (come from shared objects), the linker will create copy relocations
and have them defined in the executable. Result is that no global access
needs to go through the GOT and hence improves performance.
This optimization only applies to undefined, non-weak global data.
Undefined, weak global data access still must go through the GOT.
This patch checks if linker supports PIE with copy reloc, which is
enabled in gold and bfd linker in bininutils 2.25, at configure time
and enables this optimization if the linker support is available.
gcc/
* configure.ac (HAVE_LD_PIE_COPYRELOC): Defined to 1 if
Linux/x86-64 linker supports PIE with copy reloc.
* config.in: Regenerated.
* configure: Likewise.
* config/i386/i386.c (legitimate_pic_address_disp_p): Allow
pc-relative address for undefined, non-weak, non-function
symbol reference in 64-bit PIE if linker supports PIE with
copy reloc.
* doc/sourcebuild.texi: Document pie_copyreloc target.
gcc/testsuite/
* gcc.target/i386/pie-copyrelocs-1.c: New test.
* gcc.target/i386/pie-copyrelocs-2.c: Likewise.
* gcc.target/i386/pie-copyrelocs-3.c: Likewise.
* gcc.target/i386/pie-copyrelocs-4.c: Likewise.
* lib/target-supports.exp (check_effective_target_pie_copyreloc):
New procedure.
---
gcc/ChangeLog | 15 +++++++
gcc/config.in | 6 +++
gcc/config/i386/i386.c | 6 ++-
gcc/configure | 47 ++++++++++++++++++++++
gcc/configure.ac | 43 ++++++++++++++++++++
gcc/doc/sourcebuild.texi | 3 ++
gcc/testsuite/ChangeLog | 11 +++++
gcc/testsuite/gcc.target/i386/pie-copyrelocs-1.c | 14 +++++++
gcc/testsuite/gcc.target/i386/pie-copyrelocs-2.c | 14 +++++++
gcc/testsuite/gcc.target/i386/pie-copyrelocs-3.c | 14 +++++++
gcc/testsuite/gcc.target/i386/pie-copyrelocs-4.c | 17 ++++++++
gcc/testsuite/lib/target-supports.exp | 51 ++++++++++++++++++++++++
12 files changed, 240 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pie-copyrelocs-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/pie-copyrelocs-2.c
create mode 100644 gcc/testsuite/gcc.target/i386/pie-copyrelocs-3.c
create mode 100644 gcc/testsuite/gcc.target/i386/pie-copyrelocs-4.c
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 928b6b8..7835ab0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2014-12-04 Sriraman Tallam <tmsriram@google.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure.ac (HAVE_LD_PIE_COPYRELOC): Defined to 1 if
+ Linux/x86-64 linker supports PIE with copy reloc.
+ * config.in: Regenerated.
+ * configure: Likewise.
+
+ * config/i386/i386.c (legitimate_pic_address_disp_p): Allow
+ pc-relative address for undefined, non-weak, non-function
+ symbol reference in 64-bit PIE if linker supports PIE with
+ copy reloc.
+
+ * doc/sourcebuild.texi: Document pie_copyreloc target.
+
2014-12-03 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/64019
diff --git a/gcc/config.in b/gcc/config.in
index 65d5e42..f34adb5 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -1411,6 +1411,12 @@
#endif
+/* Define 0/1 if your linker supports -pie option with copy reloc. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_LD_PIE_COPYRELOC
+#endif
+
+
/* Define if your linker links a mix of read-only and read-write sections into
a read-write section. */
#ifndef USED_FOR_TARGET
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 211c9e6..4f1a18b 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -13113,7 +13113,11 @@ legitimate_pic_address_disp_p (rtx disp)
return true;
}
else if (!SYMBOL_REF_FAR_ADDR_P (op0)
- && SYMBOL_REF_LOCAL_P (op0)
+ && (SYMBOL_REF_LOCAL_P (op0)
+ || (HAVE_LD_PIE_COPYRELOC
+ && flag_pie
+ && !SYMBOL_REF_WEAK (op0)
+ && !SYMBOL_REF_FUNCTION_P (op0)))
&& ix86_cmodel != CM_LARGE_PIC)
return true;
break;
diff --git a/gcc/configure b/gcc/configure
index 6b46bbb..811f05d 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -27025,6 +27025,53 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_pie" >&5
$as_echo "$gcc_cv_ld_pie" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker PIE support with copy reloc" >&5
+$as_echo_n "checking linker PIE support with copy reloc... " >&6; }
+gcc_cv_ld_pie_copyreloc=no
+if test $gcc_cv_ld_pie = yes ; then
+ if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 25 -o "$gcc_cv_gld_major_version" -gt 2; then
+ gcc_cv_ld_pie_copyreloc=yes
+ fi
+ elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then
+ # Check if linker supports -pie option with copy reloc
+ case "$target" in
+ i?86-*-linux* | x86_64-*-linux*)
+ cat > conftest1.s <<EOF
+ .globl a_glob
+ .data
+ .type a_glob, @object
+ .size a_glob, 4
+a_glob:
+ .long 2
+EOF
+ cat > conftest2.s <<EOF
+ .text
+ .globl main
+ .type main, @function
+main:
+ movl %eax, a_glob(%rip)
+ .size main, .-main
+EOF
+ if $gcc_cv_as --64 -o conftest1.o conftest1.s > /dev/null 2>&1 \
+ && $gcc_cv_ld -shared -melf_x86_64 -o conftest1.so conftest1.o > /dev/null 2>&1 \
+ && $gcc_cv_as --64 -o conftest2.o conftest2.s > /dev/null 2>&1 \
+ && $gcc_cv_ld -pie -melf_x86_64 -o conftest conftest2.o conftest1.so > /dev/null 2>&1; then
+ gcc_cv_ld_pie_copyreloc=yes
+ fi
+ rm -f conftest conftest1.so conftest1.o conftest2.o conftest1.s conftest2.s
+ ;;
+ esac
+ fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LD_PIE_COPYRELOC `if test x"$gcc_cv_ld_pie_copyreloc" = xyes; then echo 1; else echo 0; fi`
+_ACEOF
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_pie_copyreloc" >&5
+$as_echo "$gcc_cv_ld_pie_copyreloc" >&6; }
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker EH-compatible garbage collection of sections" >&5
$as_echo_n "checking linker EH-compatible garbage collection of sections... " >&6; }
gcc_cv_ld_eh_gc_sections=no
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 48c8000..a33f3a5 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4693,6 +4693,49 @@ if test x"$gcc_cv_ld_pie" = xyes; then
fi
AC_MSG_RESULT($gcc_cv_ld_pie)
+AC_MSG_CHECKING(linker PIE support with copy reloc)
+gcc_cv_ld_pie_copyreloc=no
+if test $gcc_cv_ld_pie = yes ; then
+ if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 25 -o "$gcc_cv_gld_major_version" -gt 2; then
+ gcc_cv_ld_pie_copyreloc=yes
+ fi
+ elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then
+ # Check if linker supports -pie option with copy reloc
+ case "$target" in
+ i?86-*-linux* | x86_64-*-linux*)
+ cat > conftest1.s <<EOF
+ .globl a_glob
+ .data
+ .type a_glob, @object
+ .size a_glob, 4
+a_glob:
+ .long 2
+EOF
+ cat > conftest2.s <<EOF
+ .text
+ .globl main
+ .type main, @function
+main:
+ movl %eax, a_glob(%rip)
+ .size main, .-main
+EOF
+ if $gcc_cv_as --64 -o conftest1.o conftest1.s > /dev/null 2>&1 \
+ && $gcc_cv_ld -shared -melf_x86_64 -o conftest1.so conftest1.o > /dev/null 2>&1 \
+ && $gcc_cv_as --64 -o conftest2.o conftest2.s > /dev/null 2>&1 \
+ && $gcc_cv_ld -pie -melf_x86_64 -o conftest conftest2.o conftest1.so > /dev/null 2>&1; then
+ gcc_cv_ld_pie_copyreloc=yes
+ fi
+ rm -f conftest conftest1.so conftest1.o conftest2.o conftest1.s conftest2.s
+ ;;
+ esac
+ fi
+ AC_DEFINE_UNQUOTED(HAVE_LD_PIE_COPYRELOC,
+ [`if test x"$gcc_cv_ld_pie_copyreloc" = xyes; then echo 1; else echo 0; fi`],
+ [Define 0/1 if your linker supports -pie option with copy reloc.])
+fi
+AC_MSG_RESULT($gcc_cv_ld_pie_copyreloc)
+
AC_MSG_CHECKING(linker EH-compatible garbage collection of sections)
gcc_cv_ld_eh_gc_sections=no
if test $in_tree_ld = yes ; then
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 20a206d..98ba1a6 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -1717,6 +1717,9 @@ or @code{EM_SPARCV9} executables.
@item vect_cmdline_needed
Target requires a command line argument to enable a SIMD instruction set.
+
+@item pie_copyreloc
+The x86-64 target linker supports PIE with copy reloc.
@end table
@subsubsection Environment attributes
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0b4d31f..c31a0d9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2014-12-04 Sriraman Tallam <tmsriram@google.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * gcc.target/i386/pie-copyrelocs-1.c: New test.
+ * gcc.target/i386/pie-copyrelocs-2.c: Likewise.
+ * gcc.target/i386/pie-copyrelocs-3.c: Likewise.
+ * gcc.target/i386/pie-copyrelocs-4.c: Likewise.
+
+ * lib/target-supports.exp (check_effective_target_pie_copyreloc):
+ New procedure.
+
2014-12-03 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/63558
diff --git a/gcc/testsuite/gcc.target/i386/pie-copyrelocs-1.c b/gcc/testsuite/gcc.target/i386/pie-copyrelocs-1.c
new file mode 100644
index 0000000..67711e3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pie-copyrelocs-1.c
@@ -0,0 +1,14 @@
+/* Check that GOTPCREL isn't used to access glob_a. */
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-require-effective-target pie_copyreloc } */
+/* { dg-options "-O2 -fpie" } */
+
+extern int glob_a;
+
+int foo ()
+{
+ return glob_a;
+}
+
+/* glob_a should never be accessed with a GOTPCREL. */
+/* { dg-final { scan-assembler-not "glob_a@GOTPCREL" { target { ! ia32 } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pie-copyrelocs-2.c b/gcc/testsuite/gcc.target/i386/pie-copyrelocs-2.c
new file mode 100644
index 0000000..923bd68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pie-copyrelocs-2.c
@@ -0,0 +1,14 @@
+/* Check that GOTPCREL isn't used to access glob_a. */
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-require-effective-target pie_copyreloc } */
+/* { dg-options "-O2 -fpie" } */
+
+int glob_a;
+
+int foo ()
+{
+ return glob_a;
+}
+
+/* glob_a should never be accessed with a GOTPCREL. */
+/* { dg-final { scan-assembler-not "glob_a@GOTPCREL" { target { ! ia32 } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pie-copyrelocs-3.c b/gcc/testsuite/gcc.target/i386/pie-copyrelocs-3.c
new file mode 100644
index 0000000..3d695f1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pie-copyrelocs-3.c
@@ -0,0 +1,14 @@
+/* Check that PLT is used to access glob_a. */
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-require-effective-target pie_copyreloc } */
+/* { dg-options "-O2 -fpie" } */
+
+extern int glob_a (void);
+
+int foo ()
+{
+ return glob_a ();
+}
+
+/* glob_a should be accessed with a PLT. */
+/* { dg-final { scan-assembler "glob_a@PLT" { target { ! ia32 } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pie-copyrelocs-4.c b/gcc/testsuite/gcc.target/i386/pie-copyrelocs-4.c
new file mode 100644
index 0000000..8066e1d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pie-copyrelocs-4.c
@@ -0,0 +1,17 @@
+/* Check that GOTPCREL is used to access glob_a. */
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-require-effective-target pie_copyreloc } */
+/* { dg-options "-O2 -fpie" } */
+
+extern int glob_a __attribute__((weak));
+
+int foo ()
+{
+ if (&glob_a != 0)
+ return glob_a;
+ else
+ return 0;
+}
+
+/* weak glob_a should be accessed with a GOTPCREL. */
+/* { dg-final { scan-assembler "glob_a@GOTPCREL" { target { ! ia32 } } } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index ac04d95..8169865 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -6090,3 +6090,54 @@ proc force_conventional_output_for { test } {
}
}
+# Return 1 if the x86-64 target supports PIE with copy reloc, 0
+# otherwise. Cache the result.
+
+proc check_effective_target_pie_copyreloc { } {
+ global pie_copyreloc_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 pie_copyreloc_available_saved] {
+ verbose "check_effective_target_pie_copyreloc returning saved $pie_copyreloc_available_saved" 2
+ } 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_PIE_COPYRELOC == 0"
+ puts $f "# error Linker does not support PIE with copy reloc."
+ puts $f "#endif"
+ close $f
+
+ verbose "check_effective_target_pie_copyreloc 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_pie_copyreloc testfile compilation passed" 2
+ set pie_copyreloc_available_saved 1
+ } else {
+ verbose "check_effective_target_pie_copyreloc testfile compilation failed" 2
+ set pie_copyreloc_available_saved 0
+ }
+ }
+
+ return $pie_copyreloc_available_saved
+}
--
1.9.3