Hi Eric, >> I know: a patch to fix this is almost ready, just needs a final round of >> testing. > > OK, thanks for the information.
here's what I've got. It took me two false starts, unfortunately: * Initially, I just tried linking with LD_OPTIONS='-z nocompstrtab': -z nocompstrtab Disables the compression of ELF string tables, and comment sec- tions. By default, string compression is applied to SHT_STRTAB sec- tions, to SHT_PROGBITS sections that have their SHF_MERGE and SHF_STRINGS section flags set, and to comment sections. While that worked, this approach has several disadvantages: if the objects are somehow linked without that option, the resulting executables will suddenly and mysteriously start to die with SIGBUS. It would be far better if the objects themselves are save to use in whatever way without relying on a special non-default linker option. Besides, it also disable string table compression, so has a far larger impact than necessary. * Next, I tried to disable HAVE_GAS_SHF_MERGE completely before Solaris 11.4. This also fixed the regressions you observed. Unfortunately, while this is what's used with as/ld since the Solaris assembler doesn't fully support setting SHF_MERGE/SHF_STRINGS yet, when gas is in use, hundreds of Go test start to FAIL on both sparc and x86: runtime stack: fatal error: DW_FORM_strp out of range in .debug_info at 166762 panic during panic The error is from libbacktrace/dwarf.c (read_attribute) which is linked into libgo.so.13. While readelf --debug-dump=info shows no problem, dwarfdump -a complains loudly. I haven't yet investigated what exactly is happening here. * Instead I tried an approach that one of the Solaris linker engineers suggested which both avoids the need for special linker options and a large part of the impact: it just disables string merging for sections with alignment > 1 with older (pre-Solaris 11.4) versions of Solaris ld. This one worked just fine and seems the preferred approach. While the Solaris 10/SPARC ld didn't show the regressions seen on 11.3, I've decided to apply the workaround there, too, to avoid running into problems if those objects are later relinked on Solaris 11. Bootstrapped without regressions on i386-pc-solaris2.1[01] and sparc-sun-solaris2.1[01] (both Solaris 11.3 and 11.4 each) with as/ld, gas/ld, and x86_64-pc-linux-gnu. Ok for mainline? Rainer -- ----------------------------------------------------------------------------- Rainer Orth, Center for Biotechnology, Bielefeld University 2018-10-19 Rainer Orth <r...@cebitec.uni-bielefeld.de> * configure.ac (gcc_cv_ld_aligned_shf_merge): New test. * configure: Regenerate. * config.in: Regenerate. * varasm.c (mergeable_string_section): Use readonly_data_section if linker doesn't support SHF_MERGE with alignment > 8. (mergeable_constant_section): Likewise.
# HG changeset patch # Parent 01647481afc4b26a304e22ee00c42bc5a9bbafe3 Disable string merging with alignment > 1 before Solaris 11.4/SPARC diff --git a/gcc/configure.ac b/gcc/configure.ac --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -3050,6 +3050,28 @@ AC_DEFINE_UNQUOTED(HAVE_GAS_SHF_MERGE, [`if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi`], [Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.]) +gcc_cv_ld_aligned_shf_merge=yes +case "$target" in + # While Solaris 10/SPARC ld isn't affected, disable to avoid problems + # relinking on Solaris 11 < 11.4. + sparc*-*-solaris2.10*) + if test x"$gnu_ld" = xno; then + gcc_cv_ld_aligned_shf_merge=no + fi + ;; + # SHF_MERGE support is broken in Solaris ld up to Solaris 11.3/SPARC for + # alignment > 1. + sparc*-*-solaris2.11*) + if test x"$gnu_ld" = xno \ + && test "$ld_vers_major" -lt 2 && test "$ld_vers_minor" -lt 3159; then + gcc_cv_ld_aligned_shf_merge=no + fi + ;; +esac +AC_DEFINE_UNQUOTED(HAVE_LD_ALIGNED_SHF_MERGE, + [`if test $gcc_cv_ld_aligned_shf_merge = yes; then echo 1; else echo 0; fi`], +[Define 0/1 if your linker supports the SHF_MERGE flag with section alignment > 1.]) + gcc_GAS_CHECK_FEATURE([stabs directive], gcc_cv_as_stabs_directive, ,, [.stabs "gcc2_compiled.",60,0,0,0],, [AC_DEFINE(HAVE_AS_STABS_DIRECTIVE, 1, diff --git a/gcc/varasm.c b/gcc/varasm.c --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -823,6 +823,9 @@ mergeable_string_section (tree decl ATTR if (align < modesize) align = modesize; + if (!HAVE_LD_ALIGNED_SHF_MERGE && align > 8) + return readonly_data_section; + str = TREE_STRING_POINTER (decl); unit = GET_MODE_SIZE (mode); @@ -861,7 +864,8 @@ mergeable_constant_section (machine_mode && known_le (GET_MODE_BITSIZE (mode), align) && align >= 8 && align <= 256 - && (align & (align - 1)) == 0) + && (align & (align - 1)) == 0 + && (HAVE_LD_ALIGNED_SHF_MERGE ? 1 : align == 8)) { const char *prefix = function_mergeable_rodata_prefix (); char *name = (char *) alloca (strlen (prefix) + 30);