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..eb43bc6 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13113,7 +13113,10 @@ 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_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 < conftest2.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 < conftest2.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