configure: Extend SHF_GNU_RETAIN conftest to check for unsupported gold

Message ID 20201216183928.nfyti2k652ygoma6@jozef-acer-manjaro
State New
Headers show
Series
  • configure: Extend SHF_GNU_RETAIN conftest to check for unsupported gold
Related show

Commit Message

Jozef Lawrynowicz Dec. 16, 2020, 6:39 p.m.
Since "6fbec038f7a Use SHF_GNU_RETAIN to preserve symbol definitions",
GCC could create sections with the 'R' flag, which GAS would map to
SHF_GNU_RETAIN.

SHF_GNU_RETAIN support was not available in gold until Binutils commit
ff4bc37d77, on 2020-12-14. Until the support was added, invalid binaries
could be created if some special sections, such as .init_array, had
SHF_GNU_RETAIN set.

HAVE_GAS_SHF_GNU_RETAIN is now disabled if a version of gold without
SHF_GNU_RETAIN support is detected.

I tested that HAVE_GAS_SHF_GNU_RETAIN was enabled/disabled as
appropriate in a number of configurations, using both in-tree and
out-of-tree Binutils:
- Before the Binutils gold patch:
  * gold disabled == SHF_GNU_RETAIN enabled
  * gold enabled == SHF_GNU_RETAIN disabled
- After the Binutils gold patch:
  * gold disabled == SHF_GNU_RETAIN enabled
  * gold enabled == SHF_GNU_RETAIN enabled 

Successfully bootstrapped for x86_64-pc-linux-gnu.

Ok to apply?
From af3000bbacc6d8ca57581c11790032b73ea944ac Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <jozef.l@mittosystems.com>

Date: Wed, 16 Dec 2020 18:33:54 +0000
Subject: [PATCH] configure: Extend SHF_GNU_RETAIN conftest to check for
 unsupported gold

Since "6fbec038f7a Use SHF_GNU_RETAIN to preserve symbol definitions",
GCC could create sections with the 'R' flag, which GAS would map to
SHF_GNU_RETAIN.

SHF_GNU_RETAIN support was not available in gold until Binutils commit
ff4bc37d77, on 2020-12-14. Until the support was added, invalid binaries
could be created if some special sections, such as .init_array, had
SHF_GNU_RETAIN set.

HAVE_GAS_SHF_GNU_RETAIN is now disabled if a version of gold without
SHF_GNU_RETAIN support is detected.

gcc/ChangeLog:

	PR target/98210
	* configure: Regenerate.
	* configure.ac (gcc_cv_as_shf_gnu_retain): Disable
	HAVE_GAS_SHF_GNU_RETAIN for gold versions that do not support it.
---
 gcc/configure    | 60 ++++++++++++++++++++++++++++++++++++++++++++-
 gcc/configure.ac | 64 +++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 120 insertions(+), 4 deletions(-)

-- 
2.29.2

Comments

H.J. Lu via Gcc-patches Jan. 4, 2021, 9:50 p.m. | #1
On 12/16/20 11:39 AM, Jozef Lawrynowicz wrote:
> Since "6fbec038f7a Use SHF_GNU_RETAIN to preserve symbol definitions",

> GCC could create sections with the 'R' flag, which GAS would map to

> SHF_GNU_RETAIN.

>

> SHF_GNU_RETAIN support was not available in gold until Binutils commit

> ff4bc37d77, on 2020-12-14. Until the support was added, invalid binaries

> could be created if some special sections, such as .init_array, had

> SHF_GNU_RETAIN set.

>

> HAVE_GAS_SHF_GNU_RETAIN is now disabled if a version of gold without

> SHF_GNU_RETAIN support is detected.

>

> I tested that HAVE_GAS_SHF_GNU_RETAIN was enabled/disabled as

> appropriate in a number of configurations, using both in-tree and

> out-of-tree Binutils:

> - Before the Binutils gold patch:

>   * gold disabled == SHF_GNU_RETAIN enabled

>   * gold enabled == SHF_GNU_RETAIN disabled

> - After the Binutils gold patch:

>   * gold disabled == SHF_GNU_RETAIN enabled

>   * gold enabled == SHF_GNU_RETAIN enabled 

>

> Successfully bootstrapped for x86_64-pc-linux-gnu.

>

> Ok to apply?

>

> 0001-configure-Extend-SHF_GNU_RETAIN-conftest-to-check-fo.patch

>

> From af3000bbacc6d8ca57581c11790032b73ea944ac Mon Sep 17 00:00:00 2001

> From: Jozef Lawrynowicz <jozef.l@mittosystems.com>

> Date: Wed, 16 Dec 2020 18:33:54 +0000

> Subject: [PATCH] configure: Extend SHF_GNU_RETAIN conftest to check for

>  unsupported gold

>

> Since "6fbec038f7a Use SHF_GNU_RETAIN to preserve symbol definitions",

> GCC could create sections with the 'R' flag, which GAS would map to

> SHF_GNU_RETAIN.

>

> SHF_GNU_RETAIN support was not available in gold until Binutils commit

> ff4bc37d77, on 2020-12-14. Until the support was added, invalid binaries

> could be created if some special sections, such as .init_array, had

> SHF_GNU_RETAIN set.

>

> HAVE_GAS_SHF_GNU_RETAIN is now disabled if a version of gold without

> SHF_GNU_RETAIN support is detected.

>

> gcc/ChangeLog:

>

> 	PR target/98210

> 	* configure: Regenerate.

> 	* configure.ac (gcc_cv_as_shf_gnu_retain): Disable

> 	HAVE_GAS_SHF_GNU_RETAIN for gold versions that do not support it.

Sorry.  I would strongly recommend against testing like this using
version numbers.  Test the feature, not the version #, date, etc.

jeff

Patch

diff --git a/gcc/configure b/gcc/configure
index 9a27e459f14..544ec92463e 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -24442,7 +24442,63 @@  case "${target}" in
     gcc_cv_as_shf_gnu_retain=no
     ;;
   *)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for section 'R' flag" >&5
+    # gold did not support SHF_GNU_RETAIN until 2.35.50.20201215.
+    # Support for SHF_GNU_RETAIN in GCC was only added on 2020-12-01, so rather
+    # than only disabling the GCC functionality if gold is the default, disable
+    # it if a gold without the support has been built at all.
+
+    ld_gold=`which ${gcc_cv_ld}.gold`
+    check_gold_ver=no
+    if test x$ld_is_gold = xyes; then
+      # Always check_gold_ver when gold is the default linker.
+      check_gold_ver=yes
+      gold_date=$ld_date
+    elif test -f ../gold/ld-new$build_exeext; then
+      # Always check_gold_ver when gold has been built in-tree.
+      check_gold_ver=yes
+      gold_ver=`../gold/ld-new$build_exeext --version 2>/dev/null | sed 1q`
+      gold_date=`echo $gold_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)\(-*\)\([01][0-9]\)\2\([0-3][0-9]\).*$,\1\3\4,p'`
+    elif test -n "$ld_gold"; then
+      gold_ver=`${gcc_cv_ld}.gold --version 2>/dev/null | sed 1q`
+      gold_vers=`echo $gold_ver | sed -n \
+	  -e 's,^[^)]*[	 ]\([0-9][0-9]*\.[0-9][0-9]*[^)]*\)) .*$,\1,p'`
+      gold_date=`echo $gold_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)\(-*\)\([01][0-9]\)\2\([0-3][0-9]\).*$,\1\3\4,p'`
+      gold_vers_major=`expr "$gold_vers" : '\([0-9]*\)'`
+      gold_vers_minor=`expr "$gold_vers" : '[0-9]*\.\([0-9]*\)'`
+      gold_vers_patch=`expr "$gold_vers" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
+
+      # If gold exists but is not the default linker, we assume that it is
+      # still intended to be used if the version matches the default ld.
+      if test 0"$gold_vers_major" -eq 0"$ld_vers_major" \
+	  && test 0"$gold_vers_minor" -eq 0"$ld_vers_minor" \
+	  && test 0"$gold_vers_patch" -eq 0"$ld_vers_patch" \
+	  && test 0"$gold_date" -eq 0"$ld_date"; then
+	check_gold_ver=yes
+      fi
+    fi
+
+    # To test for the period of time when the SHF_GNU_RETAIN flag is supported
+    # in ld, but not in gold, check the date in the version string.  If there
+    # is no date, then we let gcc_GAS_CHECK_FEATURE make the correct
+    # choice.
+    if test $check_gold_ver = yes && test -n "$gold_date" \
+	&& test 0"$gold_date" -lt 20201215; then
+      gcc_cv_as_shf_gnu_retain=no
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking gold support for SHF_GNU_RETAIN" >&5
+$as_echo_n "checking gold support for SHF_GNU_RETAIN... " >&6; }
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_shf_gnu_retain" >&5
+$as_echo "$gcc_cv_as_shf_gnu_retain" >&6; }
+    else
+      # Versions of Binutils with SHF_GNU_RETAIN support do not directly
+      # correspond to a maj.min.patchlevel version, so even for in-tree GAS we
+      # always want to run the assembly test to check for support it, rather
+      # than looking at the version.  Temporarily overriding in_tree_gas allows
+      # the assembly test to run.
+      # The first version of Binutils with SHF_GNU_RETAIN support is
+      # 2.35.50.20201118.
+      saved_in_tree_gas=$in_tree_gas
+      in_tree_gas=no
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for section 'R' flag" >&5
 $as_echo_n "checking assembler for section 'R' flag... " >&6; }
 if ${gcc_cv_as_shf_gnu_retain+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -24475,6 +24531,8 @@  fi
 $as_echo "$gcc_cv_as_shf_gnu_retain" >&6; }
 
 
+      in_tree_gas=$saved_in_tree_gas
+    fi
     ;;
 esac
 
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 062f57fa12b..dd92d9bfb8f 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -3340,10 +3340,68 @@  case "${target}" in
     gcc_cv_as_shf_gnu_retain=no
     ;;
   *)
-    gcc_GAS_CHECK_FEATURE([section 'R' flag], gcc_cv_as_shf_gnu_retain,
-      [elf,2,36,0], [--fatal-warnings],
-      [.section .foo,"awR",%progbits
+    # gold did not support SHF_GNU_RETAIN until 2.35.50.20201215.
+    # Support for SHF_GNU_RETAIN in GCC was only added on 2020-12-01, so rather
+    # than only disabling the GCC functionality if gold is the default, disable
+    # it if a gold without the support has been built at all.
+    changequote(,)dnl
+
+    ld_gold=`which ${gcc_cv_ld}.gold`
+    check_gold_ver=no
+    if test x$ld_is_gold = xyes; then
+      # Always check_gold_ver when gold is the default linker.
+      check_gold_ver=yes
+      gold_date=$ld_date
+    elif test -f ../gold/ld-new$build_exeext; then
+      # Always check_gold_ver when gold has been built in-tree.
+      check_gold_ver=yes
+      gold_ver=`../gold/ld-new$build_exeext --version 2>/dev/null | sed 1q`
+      gold_date=`echo $gold_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)\(-*\)\([01][0-9]\)\2\([0-3][0-9]\).*$,\1\3\4,p'`
+    elif test -n "$ld_gold"; then
+      gold_ver=`${gcc_cv_ld}.gold --version 2>/dev/null | sed 1q`
+      gold_vers=`echo $gold_ver | sed -n \
+	  -e 's,^[^)]*[	 ]\([0-9][0-9]*\.[0-9][0-9]*[^)]*\)) .*$,\1,p'`
+      gold_date=`echo $gold_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)\(-*\)\([01][0-9]\)\2\([0-3][0-9]\).*$,\1\3\4,p'`
+      gold_vers_major=`expr "$gold_vers" : '\([0-9]*\)'`
+      gold_vers_minor=`expr "$gold_vers" : '[0-9]*\.\([0-9]*\)'`
+      gold_vers_patch=`expr "$gold_vers" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
+
+      # If gold exists but is not the default linker, we assume that it is
+      # still intended to be used if the version matches the default ld.
+      if test 0"$gold_vers_major" -eq 0"$ld_vers_major" \
+	  && test 0"$gold_vers_minor" -eq 0"$ld_vers_minor" \
+	  && test 0"$gold_vers_patch" -eq 0"$ld_vers_patch" \
+	  && test 0"$gold_date" -eq 0"$ld_date"; then
+	check_gold_ver=yes
+      fi
+    fi
+    changequote([,])dnl
+
+    # To test for the period of time when the SHF_GNU_RETAIN flag is supported
+    # in ld, but not in gold, check the date in the version string.  If there
+    # is no date, then we let gcc_GAS_CHECK_FEATURE make the correct
+    # choice.
+    if test $check_gold_ver = yes && test -n "$gold_date" \
+	&& test 0"$gold_date" -lt 20201215; then
+      gcc_cv_as_shf_gnu_retain=no
+      AC_MSG_CHECKING(gold support for SHF_GNU_RETAIN)
+      AC_MSG_RESULT($gcc_cv_as_shf_gnu_retain)
+    else
+      # Versions of Binutils with SHF_GNU_RETAIN support do not directly
+      # correspond to a maj.min.patchlevel version, so even for in-tree GAS we
+      # always want to run the assembly test to check for support it, rather
+      # than looking at the version.  Temporarily overriding in_tree_gas allows
+      # the assembly test to run.
+      # The first version of Binutils with SHF_GNU_RETAIN support is
+      # 2.35.50.20201118.
+      saved_in_tree_gas=$in_tree_gas
+      in_tree_gas=no
+      gcc_GAS_CHECK_FEATURE([section 'R' flag], gcc_cv_as_shf_gnu_retain,
+	[elf,2,36,0], [--fatal-warnings],
+	[.section .foo,"awR",%progbits
 .byte 0])
+      in_tree_gas=$saved_in_tree_gas
+    fi
     ;;
 esac
 AC_DEFINE_UNQUOTED(HAVE_GAS_SHF_GNU_RETAIN,