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 <[email protected]>
* 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);