+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-04 Marek Polacek <polacek@redhat.com>
PR middle-end/56917
#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
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;
{ $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
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
@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
+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-04 Marek Polacek <polacek@redhat.com>
PR middle-end/56917
--- /dev/null
+/* 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 } } } } */
--- /dev/null
+/* 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 } } } } */
--- /dev/null
+/* 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 } } } } */
--- /dev/null
+/* 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 } } } } */
}
}
+# 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
+}