https://gcc.gnu.org/g:96f3b4dfe16984299d65d7a071a5586dafcbd046
commit r16-7832-g96f3b4dfe16984299d65d7a071a5586dafcbd046 Author: Rainer Orth <[email protected]> Date: Sun Mar 1 18:32:26 2026 +0100 Switch to HAVE_SOLARIS_LD 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. 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. Diff: --- gcc/config.in | 6 ++++++ gcc/config/i386/sol2.h | 4 ++-- gcc/config/sol2.h | 16 ++++++++-------- gcc/config/sparc/sol2.h | 4 ++-- gcc/config/sparc/sparc.md | 2 +- gcc/configure | 24 ++++++++++++++++++++++++ gcc/configure.ac | 19 +++++++++++++++++++ gcc/go/gospec.cc | 2 +- 8 files changed, 63 insertions(+), 14 deletions(-) diff --git a/gcc/config.in b/gcc/config.in index 6decd21a86fe..a4fd5e0c1086 100644 --- 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 index 3d271a7f5388..097c4621e926 100644 --- a/gcc/config/i386/sol2.h +++ b/gcc/config/i386/sol2.h @@ -85,7 +85,7 @@ along with GCC; see the file COPYING3. If not see #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. If not see /* 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 index 01d0a669618b..ba260e5a14b4 100644 --- a/gcc/config/sol2.h +++ b/gcc/config/sol2.h @@ -228,7 +228,7 @@ along with GCC; see the file COPYING3. If not see 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. If not see %{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. If not see { "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. If not see #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. If not see #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 index 48f0308ee086..edf6aa741032 100644 --- a/gcc/config/sparc/sol2.h +++ b/gcc/config/sparc/sol2.h @@ -264,7 +264,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); %{!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 (int argc, const char **argv); #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 index 4740e255c295..0fa2f8150ca9 100644 --- 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 index 3d9521f8d754..81bb8ed38415 100755 --- 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 index 466fc388f254..c641d2f9af3c 100644 --- 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 index 6e7d05197e8e..df1987b76633 100644 --- a/gcc/go/gospec.cc +++ b/gcc/go/gospec.cc @@ -438,7 +438,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, 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
