Bug #3800
openld: fatal: file ...crtbegin.o; section [7].eh_frame and file .libs/sjlj.o; section [12].eh_frame have incompatibile attributes and cannot be merged into a single output section
0%
Description
I've noticed lately while building gcc47 and gcc48 the following:
checking for log10... libtool: link: /tmp/pkgsrc/lang/gcc48/work/build/./gcc/xgcc -B/tmp/pkgsrc/lang/gcc48/work/build/./gcc/ -B/opt/pkg/gcc48/i386-sun-solaris2.11/bin/ -B/opt/pkg/gcc48/i386-sun-solaris2.11/lib/ -isystem /opt/pkg/gcc48/i386-sun-solaris2.11/include -isystem /opt/pkg/gcc48/i386-sun-solaris2.11/sys-include -m64 -shared -Wl,-z -Wl,text -Wl,-h -Wl,libitm.so.1 -o .libs/libitm.so.1.0.0 .libs/aatree.o .libs/alloc.o .libs/alloc_c.o .libs/alloc_cpp.o .libs/barrier.o .libs/beginend.o .libs/clone.o .libs/eh_cpp.o .libs/local.o .libs/query.o .libs/retry.o .libs/rwlock.o .libs/useraction.o .libs/util.o .libs/sjlj.o .libs/tls.o .libs/method-serial.o .libs/method-gl.o .libs/method-ml.o .libs/x86_sse.o .libs/x86_avx.o -mrtm -pthread -m64 -Wl,-M -Wl,../../../../gcc-4.8.0/libitm/clearcap.map -Wl,-R/opt/pkg/lib -m64 -Wl,-M -Wl,libitm.map-sun ld: fatal: file /tmp/pkgsrc/lang/gcc48/work/build/./gcc/amd64/crtbegin.o; section [7].eh_frame and file .libs/sjlj.o; section [12].eh_frame have incompatibile attributes and cannot be merged into a single output section collect2: error: ld returned 1 exit status gmake[8]: *** [libitm.la] Error 1 gmake[8]: Leaving directory `/tmp/pkgsrc/lang/gcc48/work/build/i386-sun-solaris2.11/amd64/libitm' gmake[7]: *** [all-recursive] Error 1 gmake[7]: Leaving directory `/tmp/pkgsrc/lang/gcc48/work/build/i386-sun-solaris2.11/amd64/libitm' gmake[6]: *** [all] Error 2 gmake[6]: Leaving directory `/tmp/pkgsrc/lang/gcc48/work/build/i386-sun-solaris2.11/amd64/libitm' gmake[5]: *** [multi-do] Error 1 gmake[5]: Leaving directory `/tmp/pkgsrc/lang/gcc48/work/build/i386-sun-solaris2.11/libitm' gmake[4]: *** [all-multi] Error 2 gmake[4]: Leaving directory `/tmp/pkgsrc/lang/gcc48/work/build/i386-sun-solaris2.11/libitm' yes checking for __sync_add_and_fetch_8... gmake[3]: *** [all-recursive] Error 1 gmake[3]: Leaving directory `/tmp/pkgsrc/lang/gcc48/work/build/i386-sun-solaris2.11/libitm' gmake[2]: *** [all] Error 2 gmake[2]: Leaving directory `/tmp/pkgsrc/lang/gcc48/work/build/i386-sun-solaris2.11/libitm' gmake[1]: *** [all-target-libitm] Error 2
Here are the attributes:
richard@dev32:/tmp/pkgsrc/lang/gcc48/work/build/i386-sun-solaris2.11/amd64/libitm$ /usr/bin/nm -s .libs/sjlj.o .libs/sjlj.o: [Index] Value Size Type Bind Other Shname Name [1] | 0| 0|SECT |LOCL |0 |.text | [2] | 0| 0|SECT |LOCL |0 |.data | [3] | 0| 0|SECT |LOCL |0 |.bss | [4] | 0| 0|SECT |LOCL |0 |.debug_info | [5] | 0| 0|SECT |LOCL |0 |.debug_abbrev | [6] | 0| 0|SECT |LOCL |0 |.debug_line | [7] | 0| 0|SECT |LOCL |0 |.debug_aranges| [8] | 0| 0|SECT |LOCL |0 |.eh_frame | [9] | 0| 56|FUNC |GLOB |0 |.text |_ITM_beginTransaction [10] | 0| 0|NOTY |GLOB |0 |UNDEF |GTM_begin_transaction [11] | 56| 35|FUNC |GLOB |2 |.text |GTM_longjmp richard@dev32:/tmp/pkgsrc/lang/gcc48/work/build/i386-sun-solaris2.11/amd64/libitm$ /usr/bin/nm -s /tmp/pkgsrc/lang/gcc48/work/build/./gcc/amd64/crtbegin.o /tmp/pkgsrc/lang/gcc48/work/build/./gcc/amd64/crtbegin.o: [Index] Value Size Type Bind Other Shname Name [24] | 0| 0|SECT |LOCL |0 |.init | [2] | 0| 0|SECT |LOCL |0 |.text | [3] | 0| 0|SECT |LOCL |0 |.data | [4] | 0| 0|SECT |LOCL |0 |.bss | [25] | 0| 0|SECT |LOCL |0 |.comment | [6] | 0| 0|SECT |LOCL |0 |.ctors | [12] | 0| 0|SECT |LOCL |0 |.jcr | [8] | 0| 0|SECT |LOCL |0 |.dtors | [21] | 0| 0|SECT |LOCL |0 |.fini | [10] | 0| 0|SECT |LOCL |0 |.eh_frame | [14] | 0| 0|SECT |LOCL |0 |.tm_clone_table| [7] | 0| 0|OBJT |LOCL |0 |.ctors |__CTOR_LIST__ [32] | 0| 0|NOTY |WEAK |0 |UNDEF |__deregister_frame_info_bases [18] | 112| 0|FUNC |LOCL |0 |.text |__do_global_dtors_aux [30] | 8| 0|OBJT |GLOB |2 |.data |__dso_handle [31] | 0| 0|NOTY |GLOB |2 |UNDEF |__DTOR_END__ [9] | 0| 0|OBJT |LOCL |0 |.dtors |__DTOR_LIST__ [11] | 0| 0|OBJT |LOCL |0 |.eh_frame |__EH_FRAME_BEGIN__ [13] | 0| 0|OBJT |LOCL |0 |.jcr |__JCR_LIST__ [33] | 0| 0|NOTY |WEAK |0 |UNDEF |__register_frame_info_bases [26] | 0| 0|NOTY |GLOB |2 |UNDEF |__TMC_END__ [15] | 0| 0|OBJT |LOCL |0 |.tm_clone_table|__TMC_LIST__ [27] | 0| 0|NOTY |GLOB |0 |UNDEF |_GLOBAL_OFFSET_TABLE_ [28] | 0| 0|NOTY |WEAK |0 |UNDEF |_ITM_deregisterTMCloneTable [29] | 0| 0|NOTY |WEAK |0 |UNDEF |_ITM_registerTMCloneTable [34] | 0| 0|NOTY |WEAK |0 |UNDEF |_Jv_RegisterClasses [19] | 0| 1|OBJT |LOCL |0 |.bss |completed.5372 [1] | 0| 0|FILE |LOCL |0 |ABS |crtstuff.c [16] | 0| 0|FUNC |LOCL |0 |.text |deregister_tm_clones [20] | 8| 8|OBJT |LOCL |0 |.bss |dtor_idx.5374 [5] | 0| 0|OBJT |LOCL |0 |.data |force_to_data [22] | 240| 0|FUNC |LOCL |0 |.text |frame_dummy [23] | 32| 48|OBJT |LOCL |0 |.bss |object.5384 [17] | 48| 0|FUNC |LOCL |0 |.text |register_tm_clones
and attached is an LD_OPTIONS output from the following command:
LD_OPTIONS=-Dfiles,detail,reloc,move,unused,got,sections,segments /tmp/pkgsrc/lang/gcc48/work/build/./gcc/xgcc -B/tmp/pkgsrc/lang/gcc48/work/build/./gcc/ -B/opt/pkg/gcc48/i386-sun-solaris2.11/bin/ -B/opt/pkg/gcc48/i386-sun-solaris2.11/lib/ -isystem /opt/pkg/gcc48/i386-sun-solaris2.11/include -isystem /opt/pkg/gcc48/i386-sun-solaris2.11/sys-include -m64 -shared -Wl,-z -Wl,text -Wl,-h -Wl,libitm.so.1 -o .libs/libitm.so.1.0.0 .libs/aatree.o .libs/alloc.o .libs/alloc_c.o .libs/alloc_cpp.o .libs/barrier.o .libs/beginend.o .libs/clone.o .libs/eh_cpp.o .libs/local.o .libs/query.o .libs/retry.o .libs/rwlock.o .libs/useraction.o .libs/util.o .libs/sjlj.o .libs/tls.o .libs/method-serial.o .libs/method-gl.o .libs/method-ml.o .libs/x86_sse.o .libs/x86_avx.o -mrtm -pthread -m64 -Wl,-M -Wl,../../../../gcc-4.8.0/libitm/clearcap.map -Wl,-R/opt/pkg/lib -m64 -Wl,-M -Wl,libitm.map-sun
Is it possible that this is related to the recent fixes?
BTW - for some very strange reason, I seem to be able get over this if I force builds to use pkgsrc's binutils-2.23.2
I can make a tarball available.
Files
Updated by Richard PALO over 10 years ago
Apparently I'm not alone:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53902
Updated by Richard PALO over 10 years ago
looking at https://github.com/richlowe/gcc/commit/610511a2a04185795a2e0d08ff25369126719346
it appears that the current gcc48 source has more or less the same:
[case "$target" in *-*-solaris*) # If the linker used on Solaris (like Sun ld) isn't capable of merging # read-only and read-write sections, we need to make sure that the # assembler used emits read-write .eh_frame sections. if test "x$gcc_cv_ld_ro_rw_mix" != xread-write; then if test "x$gcc_cv_objdump" != x; then if $gcc_cv_objdump -h conftest.o 2>/dev/null | \\ sed -e /.eh_frame/!d -e N | grep READONLY > /dev/null; then gcc_cv_as_cfi_directive=no else case "$target" in i?86-*-solaris2.1[[0-9]]* | x86_64-*-solaris2.1[[0-9]]*) # On Solaris/x86, make sure that GCC and gas agree on using # read-only .eh_frame sections for 64-bit. if $gcc_cv_as --64 -o conftest.o conftest.s > /dev/null 2>&1 && \\ $gcc_cv_objdump -h conftest.o 2>/dev/null | \\ sed -e /.eh_frame/!d -e N | \\ grep READONLY > /dev/null; then gcc_cv_as_cfi_directive=yes else gcc_cv_as_cfi_directive=no fi ;; *) gcc_cv_as_cfi_directive=yes ;; esac fi else # no objdump, err on the side of caution gcc_cv_as_cfi_directive=no fi else gcc_cv_as_cfi_directive=yes fi ;; *-*-*) gcc_cv_as_cfi_directive=yes ;; esac])
richard@dev32:/tmp/pkgsrc/lang/gcc48/work/gcc-4.8.0/gcc$ gas -v /dev/null GNU assembler version 2.19 (i386-pc-solaris2.11) using BFD version (GNU Binutils) 2.19
and as we can see by the following:
richard@dev32:/tmp/pkgsrc/lang/gcc48/work/build/i386-sun-solaris2.11/amd64/libitm$ gobjdump -h .libs/sjlj.o .libs/sjlj.o: file format elf64-x86-64 Sections: Idx Name Size VMA LMA File off Algn 0 .text 0000005b 0000000000000000 0000000000000000 00000040 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 1 .data 00000000 0000000000000000 0000000000000000 0000009c 2**2 CONTENTS, ALLOC, LOAD, DATA 2 .bss 00000000 0000000000000000 0000000000000000 0000009c 2**2 ALLOC 3 .debug_line 0000005c 0000000000000000 0000000000000000 0000009c 2**0 CONTENTS, RELOC, READONLY, DEBUGGING 4 .debug_info 00000087 0000000000000000 0000000000000000 000000f8 2**0 CONTENTS, RELOC, READONLY, DEBUGGING 5 .debug_abbrev 00000014 0000000000000000 0000000000000000 0000017f 2**0 CONTENTS, READONLY, DEBUGGING 6 .debug_aranges 00000030 0000000000000000 0000000000000000 000001a0 2**4 CONTENTS, RELOC, READONLY, DEBUGGING 7 .eh_frame 00000050 0000000000000000 0000000000000000 000001d0 2**3 CONTENTS, ALLOC, LOAD, RELOC, DATA richard@dev32:/tmp/pkgsrc/lang/gcc48/work/build/i386-sun-solaris2.11/amd64/libitm$ gobjdump -h /tmp/pkgsrc/lang/gcc48/work/build/./gcc/amd64/crtbegin.o /tmp/pkgsrc/lang/gcc48/work/build/./gcc/amd64/crtbegin.o: file format elf64-x86-64 Sections: Idx Name Size VMA LMA File off Algn 0 .text 00000145 0000000000000000 0000000000000000 00000040 2**4 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 1 .data 00000010 0000000000000000 0000000000000000 00000188 2**3 CONTENTS, ALLOC, LOAD, DATA 2 .bss 00000050 0000000000000000 0000000000000000 000001a0 2**5 ALLOC 3 .ctors 00000008 0000000000000000 0000000000000000 000001a0 2**3 CONTENTS, ALLOC, LOAD, DATA 4 .dtors 00000008 0000000000000000 0000000000000000 000001a8 2**3 CONTENTS, ALLOC, LOAD, DATA 5 .eh_frame 00000000 0000000000000000 0000000000000000 000001b0 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .jcr 00000000 0000000000000000 0000000000000000 000001b0 2**3 CONTENTS, ALLOC, LOAD, DATA 7 .tm_clone_table 00000000 0000000000000000 0000000000000000 000001b0 2**3 CONTENTS, ALLOC, LOAD, DATA 8 .fini 00000005 0000000000000000 0000000000000000 000001b0 2**0 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 9 .init 00000005 0000000000000000 0000000000000000 000001b5 2**0 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 10 .comment 00000012 0000000000000000 0000000000000000 000001ba 2**0 CONTENTS, READONLY
.eh_frame is READONLY in crtbegin.o but not in .libs/sjlj.o
and double checking in config.log (here is an extract)
configure:22434: checking assembler for cfi directives configure:22449: /usr/sfw/bin/gas -o conftest.o conftest.s >&5 configure:22452: $? = 0 configure:22503: result: no configure:22556: checking assembler for cfi personality directive configure:22568: /usr/sfw/bin/gas -o conftest.o conftest.s >&5 configure:22571: $? = 0 configure:22582: result: yes configure:22592: checking assembler for cfi sections directive configure:22604: /usr/sfw/bin/gas -o conftest.o conftest.s >&5 conftest.s: Assembler messages: conftest.s:2: Error: unknown pseudo-op: `.cfi_sections' configure:22607: $? = 1 configure: failed program was .text .cfi_sections .debug_frame, .eh_frame .cfi_startproc .cfi_endproc configure:22633: result: no configure:22646: checking assembler for eh_frame optimization configure:22691: /usr/sfw/bin/gas -o conftest.o conftest.s >&5 configure:22694: $? = 0 configure:22737: result: yes configure:22747: checking assembler for section merging support configure:22761: /usr/sfw/bin/gas --fatal-warnings -o conftest.o conftest.s >&5 configure:22764: $? = 0 configure:22775: result: yes configure:22817: checking assembler for COMDAT group support (GNU as) configure:22831: /usr/sfw/bin/gas --fatal-warnings -o conftest.o conftest.s >&5 configure:22834: $? = 0 configure:22845: result: yes ... ... gcc_cv_as=/usr/sfw/bin/gas gcc_cv_as_balign_and_p2align=yes gcc_cv_as_cfi_advance_working=no gcc_cv_as_cfi_directive=no gcc_cv_as_cfi_personality_directive=yes gcc_cv_as_cfi_sections_directive=no gcc_cv_as_comdat_group=yes gcc_cv_as_comdat_group_group=no gcc_cv_as_comdat_group_percent=no gcc_cv_as_debug_prefix_map_flag=yes gcc_cv_as_discriminator=no gcc_cv_as_dwarf2_debug_line=yes gcc_cv_as_dwarf2_file_buggy=no gcc_cv_as_eh_frame=yes gcc_cv_as_flags=' ' gcc_cv_as_gas_srcdir=../../gcc-4.8.0/gas gcc_cv_as_gdwarf2_flag=yes gcc_cv_as_gnu_unique_object=no gcc_cv_as_gstabs_flag=yes gcc_cv_as_hidden=yes gcc_cv_as_ix86_cmov_sun_syntax=no gcc_cv_as_ix86_diff_sect_delta=yes gcc_cv_as_ix86_ffreep=yes gcc_cv_as_ix86_fildq=yes gcc_cv_as_ix86_filds=yes gcc_cv_as_ix86_gotoff_in_data=yes gcc_cv_as_ix86_hle=no gcc_cv_as_ix86_quad=yes gcc_cv_as_ix86_rep_lock_prefix=no gcc_cv_as_ix86_sahf=yes gcc_cv_as_ix86_swap=no gcc_cv_as_ix86_tlsgdplt=no gcc_cv_as_ix86_tlsldmplt=no gcc_cv_as_lcomm_with_alignment=no gcc_cv_as_leb128=yes gcc_cv_as_line_zero=yes gcc_cv_as_literal16=no gcc_cv_as_max_skip_p2align=yes gcc_cv_as_nsubspa_comdat=no gcc_cv_as_shf_merge=yes gcc_cv_as_subsection_m1=yes gcc_cv_as_tls=yes gcc_cv_as_weak=yes gcc_cv_as_weakref=yes
I should probably add, although I highly doubt it is pertinent, but the bootstrap compiler it /opt/gcc/4.4.4/bin/gcc (illumos-gcc)
Updated by Rich Lowe over 10 years ago
- Status changed from New to Feedback
The attributes you've pasted aren't the attributes which ld means, it means the flags on the section (elfdump -c). This problem has existed previously, and Rainer fixed it. Generally, as the GCC source you pasted shows, .eh_frame is writable in one object and read-only in another. ld is entirely correct to refuse to merge these, the compiler/assembler combination should never produce them.
If I were guessing, I'd say that something has changed, probably in the binutils you're using, that's causing the configure check to not work as well as it used to. I still firmly believe that we shouldn't merge unlike sections (I wonder what GNU ld does, promote everything to writable itself?), and that GCC shouldn't do this to us. You should look into why GCC has (re-)started doing this. This got fixed previously, by the code you've shown.
Updated by Richard PALO over 10 years ago
Well, it's gas 2.19 from OI that doesn't work. Seemingly 2.32 is fine when forced
(BTW I notice that omnios now seems to ship 2.32 by default)...
extract from elfdump -c for sjlj.o:
... En-tête de section[12] : sh_name : .eh_frame sh_addr: 0 sh_flags: [ SHF_WRITE SHF_ALLOC ] sh_size: 0x50 sh_type: [ SHT_AMD64_UNWIND ] sh_offset: 0x1d0 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x8 En-tête de section[13] : sh_name : .rela.eh_frame sh_addr: 0 sh_flags: 0 sh_size: 0x30 sh_type: [ SHT_RELA ] sh_offset: 0x908 sh_entsize: 0x18 (2 entries) sh_link: 15 sh_info: 12 sh_addralign: 0x8 ...
and for crtbegin.o:
... En-tête de section[7] : sh_name : .eh_frame sh_addr: 0 sh_flags: [ SHF_ALLOC ] sh_size: 0 sh_type: [ SHT_AMD64_UNWIND ] sh_offset: 0x1b0 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 ...
In both cases I'm using /usr/bin/ld.
Seems interesting in that given crtbegin.o's eh_frame has size zero, perhaps in this case there would be no "badness" in compressing the sections together, or is there some particular semantic meaning reserved for zero-length readonly sections?
(Notwithstanding the alignment difference...)
I wonder as well if both objects are built during the same "stage"?
Anyway, from what you're saying, if there is no coherent fix for solaris ld, then the only correct approach seems indeed to be updating to a more recent binutils as found out by the workaround.
BTW, currently I'm still using openindiana (with the same binutils) to build illumos-gate, this problem has not been seen elsewhere, has it? only to build gcc47/48 itself?
I'm trying to move to omnios but am still having some teething pains that don't seem to manifest on OI...
Updated by Richard PALO over 10 years ago
is this perhaps the gas change?
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gas/dw2gencfi.c.diff?r1=1.51&r2=1.52&cvsroot=src
Updated by Richard PALO over 10 years ago
If I were guessing, I'd say that something has changed, probably in the binutils you're using, >that's causing the configure check to not work as well as it used to. I still firmly believe that >we shouldn't merge unlike sections (I wonder what GNU ld does, promote everything to >writable itself?), and that GCC shouldn't do this to us. You should look into why GCC has >(re-)started doing this. This got fixed previously, by the code you've shown.
Hmm, the patch seems to imply that, on the contrary, .eh_frame should now always be read-only. This particular check should be relatively easy to implement in solaris ld, no?
Updated by Richard PALO over 10 years ago
Seems that things differ a bit already between i386 and x86_64
(not presuming that these are assember output as I believe they are generated by the gcc)...
richard@smicro:~$ elfdump -c -N .eh_frame /usr/sfw/lib/gcc/i386-pc-solaris2.11/3.4.3/crtbegin.o En-tête de section[7] : sh_name : .eh_frame sh_addr: 0 sh_flags: [ SHF_WRITE SHF_ALLOC ] sh_size: 0 sh_type: [ SHT_PROGBITS ] sh_offset: 0x100 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 richard@smicro:~$ elfdump -c -N .eh_frame /usr/sfw/lib/gcc/i386-pc-solaris2.11/3.4.3/amd64/crtbegin.o En-tête de section[7] : sh_name : .eh_frame sh_addr: 0 sh_flags: [ SHF_ALLOC ] sh_size: 0x68 sh_type: [ SHT_AMD64_UNWIND ] sh_offset: 0x110 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x8 richard@smicro:~$ elfdump -c -N .eh_frame /opt/gcc/4.4.4/lib/gcc/i386-pc-solaris2.11/4.4.4/crtbegin.o En-tête de section[7] : sh_name : .eh_frame sh_addr: 0 sh_flags: [ SHF_WRITE SHF_ALLOC ] sh_size: 0 sh_type: [ SHT_PROGBITS ] sh_offset: 0x11c sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 richard@smicro:~$ elfdump -c -N .eh_frame /opt/gcc/4.4.4/lib/gcc/i386-pc-solaris2.11/4.4.4/amd64/crtbegin.o En-tête de section[7] : sh_name : .eh_frame sh_addr: 0 sh_flags: [ SHF_ALLOC ] sh_size: 0 sh_type: [ SHT_AMD64_UNWIND ] sh_offset: 0x130 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4
Updated by Richard PALO over 10 years ago
after reading the following thread, and others similar for other platforms, I can only conclude that this stuff appears thoroughly convoluted and leaves absolutely no place for someone not deeply involved (like me).
From: Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> Newsgroups: gmane.comp.gnu.binutils Subject: PATCH: Make .eh_frame sections read-only on 64-bit Solaris/x86 Date: Mon, 18 Jan 2010 19:44:27 +0100
Updated by Rich Lowe over 10 years ago
The complaint from the linker is the variance in whether the section is writable. I'll look around on my systems to see if anything has changed.
I think the problem as you're seeing it is probably that the configure check as to whether CFI is safe is mis-firing, as I said. The major difference that upgrading binutils would get you is a gas that understands CFI in a way that agrees with GCC. It's unlikely that anything we've done lately should confuse this, but I can check. The reason I think the configure check is misbehaving is that this is literally the exact problem that used to occur before Rainer fixed it (the same problem object, even).
I can try to discover what GNU do with conflicting attributes, and see if maybe there's some sane heuristic if this is a recurring and common problem but if the problem is really the ancient binutils and somewhat modern GCC, it's far better that people stop using the ancient binutils.