Rainer Orth <[email protected]> writes:

> Just like the HAVE_GNU_AS case, the majority of HAVE_GNU_LD uses are in
> Solaris-specific code to distinguish GNU ld from Solaris ld.  Again,
> it's easier to turn the check around, checking for Solaris ld directly,
> which this patch does.
>
> Tested on sparcv9-sun-solaris2.11, amd64-pc-solaris2.11,
> sparc64-unknown-linux-gnu, and x86_64-pc-linux-gnu.

It turned out this is not just a cleanup but crucial to avoid a
regression when using GNU ld on Solaris.

As in the companion HAVE_SOLARIS_AS patch, I'm omitting the switch from
checking solaris_ld instead of gnu_ld_flag in acinclude.m4 and
configure.ac and will post that part in stage 1.

I'm committing the following.

        Rainer

---------------------------------------------------------------------------

When configuring GCC to use GNU ld on Solaris, gcc/configure can get
inconsistent ideas about gnu_ld_flag, which results in wrong settings
for various macros:

* Toplevel configure determines LD from PATH using
  NCN_STRICT_CHECK_TOOLS(LD, ld).  This may be either Solaris ld or GNU ld.

* The resulting LD is always passed to gcc/configure in stages 1 to 3.

* However, when LD and the value of --with-ld differ, there can result
  two values of gnu_ld_flag in different sections of gcc/configure:

** config/lib-ld.m4 (AC_LIB_PROG_LD_GNU) determines gnu_ld_flag from $LD.

** However, gcc/configure also checks gcc_cv_ld which can come from
   either --with-ld or PATH.

* When this happens, several linker tests arrive at wrong values,
  e.g. Solaris ld versions of LD_AS_NEEDED_OPTION when actually GNU ld
  is used.

To avoid this, this patch determines gnu_ld_flag from ld -V/--version
once gcc_cv_ld has finally been set.

Besides, just like the HAVE_GNU_AS case, the majority of HAVE_GNU_LD
uses are in Solaris-specific code to distinguish GNU ld from Solaris ld.
Again, it's easier to turn the check around, checking for Solaris ld
directly, which this patch does.

Bootstrapped without regressions on sparcv9-sun-solaris2.11,
amd64-pc-solaris2.11, sparc64-unknown-linux-gnu, and
x86_64-pc-linux-gnu.

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University


2026-02-08  Rainer Orth  <[email protected]>

        gcc:
        * configure.ac (solaris_ld): New check.
        Test solaris_ld instead of gnu_ld_flag.
        * configure: Regenerate.
        * config.in: Regenerate.
        * config/i386/sol2.h: Switch to HAVE_SOLARIS_LD.
        * config/sol2.h: Likewise.
        * config/sparc/sol2.h: Likewise.
        * config/sparc/sparc.md: Likewise.

        gcc/go:
        * gospec.cc (lang_specific_driver): Switch to HAVE_SOLARIS_LD.

# HG changeset patch
# Parent  08219dedfee41fa8cd8d176257f8c5e74bd40a07
Switch to HAVE_SOLARIS_LD

diff --git a/gcc/config.in b/gcc/config.in
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -2043,6 +2043,12 @@
 #endif
 
 
+/* Define to 1 if using the Solaris linker. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_SOLARIS_LD
+#endif
+
+
 /* Define to 1 if you have the <stddef.h> header file. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_STDDEF_H
diff --git a/gcc/config/i386/sol2.h b/gcc/config/i386/sol2.h
--- a/gcc/config/i386/sol2.h
+++ b/gcc/config/i386/sol2.h
@@ -85,7 +85,7 @@ along with GCC; see the file COPYING3.  
 
 #define ARCH64_SUBDIR "amd64"
 
-#if HAVE_GNU_LD
+#if !HAVE_SOLARIS_LD
 #define ARCH32_EMULATION "elf_i386_sol2"
 #define ARCH64_EMULATION "elf_x86_64_sol2"
 #endif
@@ -218,7 +218,7 @@ along with GCC; see the file COPYING3.  
 
 /* Unlike GNU ld, Sun ld doesn't coalesce .ctors.N/.dtors.N sections, so
    inhibit their creation.  Also cf. sparc/sysv4.h.  */
-#if !HAVE_GNU_LD
+#if HAVE_SOLARIS_LD
 #define CTORS_SECTION_ASM_OP	"\t.section\t.ctors, \"aw\""
 #define DTORS_SECTION_ASM_OP	"\t.section\t.dtors, \"aw\""
 #endif
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -228,7 +228,7 @@ along with GCC; see the file COPYING3.  
    in that case, and for executable link with --{,no-}whole-archive around
    it to force everything into the executable.  */
 
-#if !HAVE_GNU_LD
+#if HAVE_SOLARIS_LD
 #define LD_WHOLE_ARCHIVE_OPTION "-z allextract"
 #define LD_NO_WHOLE_ARCHIVE_OPTION "-z defaultextract"
 #else
@@ -280,14 +280,14 @@ along with GCC; see the file COPYING3.  
    %{YP,*} \
    %{R*}"
 
-#if !HAVE_GNU_LD
+#if HAVE_SOLARIS_LD
 #define LINK_ARCH_SPEC_1 \
   "%{mcmodel=medlow:-M /usr/lib/ld/map.below4G} " LINK_ARCH_SPEC_BASE
 #else
 #define LINK_ARCH_SPEC_1 LINK_ARCH_SPEC_BASE
 #endif
 
-#if HAVE_GNU_LD
+#if !HAVE_SOLARIS_LD
 #if DEFAULT_ARCH32_P
 #define ARCH_DEFAULT_EMULATION ARCH32_EMULATION
 #else
@@ -325,7 +325,7 @@ along with GCC; see the file COPYING3.  
   { "endfile_vtv",		ENDFILE_VTV_SPEC },		\
   SUBTARGET_CPU_EXTRA_SPECS
 
-#if !HAVE_GNU_LD
+#if HAVE_SOLARIS_LD
 /* With Sun ld, -rdynamic is a no-op.  */
 #define RDYNAMIC_SPEC ""
 #else
@@ -333,12 +333,12 @@ along with GCC; see the file COPYING3.  
 #define RDYNAMIC_SPEC "--export-dynamic"
 #endif
 
-#if !HAVE_GNU_LD
+#if HAVE_SOLARIS_LD
 /* Prefer native form with Solaris ld.  */
 #define SYSROOT_SPEC "-z sysroot=%R"
 #endif
 
-#if !HAVE_GNU_LD && defined(ENABLE_SHARED_LIBGCC)
+#if HAVE_SOLARIS_LD && defined(ENABLE_SHARED_LIBGCC)
 /* With Sun ld, use mapfile to enforce direct binding to libgcc_s unwinder.  */
 #define LINK_LIBGCC_MAPFILE_SPEC \
   "%{shared|shared-libgcc:-M %slibgcc-unwind.map}"
@@ -387,12 +387,12 @@ along with GCC; see the file COPYING3.  
 #define USE_LD_AS_NEEDED 1
 #endif
 
-#if HAVE_GNU_LD
+#if !HAVE_SOLARIS_LD
 /* GNU ld needs --eh-frame-hdr to create the required .eh_frame_hdr sections.  */
 #define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} "
 #endif
 
-#if HAVE_GNU_LD
+#if !HAVE_SOLARIS_LD
 /* Assert -z text by default to match Solaris ld.  */
 #define LD_PIE_SPEC "-pie %{!mimpure-text:-z text}"
 #else
diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -264,7 +264,7 @@ extern const char *host_detect_local_cpu
 %{!mcpu*:%(asm_cpu_default)} \
 "
 
-#if HAVE_GNU_LD
+#if !HAVE_SOLARIS_LD
 #define ARCH32_EMULATION "elf32_sparc_sol2"
 #define ARCH64_EMULATION "elf64_sparc_sol2"
 #endif
@@ -356,7 +356,7 @@ extern const char *host_detect_local_cpu
 #endif /* HAVE_SOLARIS_AS */
 
 /* Undefine this so that attribute((init_priority)) works with GNU ld.  */
-#if HAVE_GNU_LD
+#if !HAVE_SOLARIS_LD
 #undef CTORS_SECTION_ASM_OP
 #undef DTORS_SECTION_ASM_OP
 #endif
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -557,7 +557,7 @@
 
 ;; Attributes for branch scheduling
 (define_attr "tls_delay_slot" "false,true"
-  (symbol_ref "((!HAVE_SOLARIS_AS && HAVE_GNU_LD) != 0
+  (symbol_ref "(!HAVE_SOLARIS_AS && !HAVE_SOLARIS_LD
 		? TLS_DELAY_SLOT_TRUE : TLS_DELAY_SLOT_FALSE)"))
 
 (define_attr "in_sibcall_delay" "false,true"
diff --git a/gcc/configure b/gcc/configure
--- a/gcc/configure
+++ b/gcc/configure
@@ -25649,6 +25649,30 @@ else
 fi
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Solaris linker" >&5
+$as_echo_n "checking Solaris linker... " >&6; }
+case $target in
+  *-*-solaris2*)
+    if $gcc_cv_ld -V 2>/dev/null | grep 'Solaris Link Editors' > /dev/null; then
+      gnu_ld_flag=no
+      solaris_ld=yes
+    elif $gcc_cv_ld --version 2>/dev/null | grep GNU > /dev/null; then
+      gnu_ld_flag=yes
+    fi
+    ;;
+  *)
+    solaris_ld=no
+    ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $solaris_ld" >&5
+$as_echo "$solaris_ld" >&6; }
+solaris_ld_bool=`if test $solaris_ld = yes; then echo 1; else echo 0; fi`
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SOLARIS_LD $solaris_ld_bool
+_ACEOF
+
+
 ORIGINAL_PLUGIN_LD_FOR_TARGET=$gcc_cv_ld
 PLUGIN_LD_SUFFIX=`basename $gcc_cv_ld | sed -e "s,$target_alias-,,"`
 # if the PLUGIN_LD is set ld-new, just have it as ld
diff --git a/gcc/configure.ac b/gcc/configure.ac
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2838,6 +2838,25 @@ gnu_ld_flag="$with_gnu_ld",
    gnu_ld_flag=no
  fi])
 
+AC_MSG_CHECKING(Solaris linker)
+case $target in
+  *-*-solaris2*)
+    if $gcc_cv_ld -V 2>/dev/null | grep 'Solaris Link Editors' > /dev/null; then
+      gnu_ld_flag=no
+      solaris_ld=yes
+    elif $gcc_cv_ld --version 2>/dev/null | grep GNU > /dev/null; then
+      gnu_ld_flag=yes
+    fi
+    ;;
+  *)
+    solaris_ld=no
+    ;;
+esac
+AC_MSG_RESULT($solaris_ld)
+solaris_ld_bool=`if test $solaris_ld = yes; then echo 1; else echo 0; fi`
+AC_DEFINE_UNQUOTED(HAVE_SOLARIS_LD, $solaris_ld_bool,
+	[Define to 1 if using the Solaris linker.])
+
 ORIGINAL_PLUGIN_LD_FOR_TARGET=$gcc_cv_ld
 PLUGIN_LD_SUFFIX=`basename $gcc_cv_ld | sed -e "s,$target_alias-,,"`
 # if the PLUGIN_LD is set ld-new, just have it as ld
diff --git a/gcc/go/gospec.cc b/gcc/go/gospec.cc
--- a/gcc/go/gospec.cc
+++ b/gcc/go/gospec.cc
@@ -438,7 +438,7 @@ lang_specific_driver (struct cl_decoded_
       j++;
     }
 
-#if defined(TARGET_SOLARIS) && !HAVE_GNU_LD
+#if HAVE_SOLARIS_LD
   /* We use a common symbol for go$zerovalue.  On Solaris, when not
      using the GNU linker, the Solaris linker needs an option to not
      warn about this.  Everything works without this option, but you

Reply via email to