https://sourceware.org/bugzilla/show_bug.cgi?id=28021
Bug ID: 28021 Summary: riscv: wrong double relaxation with LTO Product: binutils Version: 2.37 (HEAD) Status: NEW Severity: normal Priority: P2 Component: ld Assignee: unassigned at sourceware dot org Reporter: matz at suse dot de Target Milestone: --- This is related to the fix for PR22756, which turns out to be incomplete. We have seen the problem with GCC11 and it needs LTO, which makes this a bit involved to reproduce. See https://bugzilla.suse.com/show_bug.cgi?id=1187542 for how it came to be, but it contains unrelated things. Eventually I came up with a single file testcase without compiler, but that involved a hex-edited .o file. After much back and forth I came up with a two-file testcase that only involves assembler, no compiler, and that I believe faithfully reflects the error mode. So, the files: % cat relax-twice-1.s .file "<artificial>" .option pic .text # this align is here so that the .text section starts at 0x1000, # in order to make matching of testcase results easier .align 12 .globl foobar_new .weak foobar_new .type foobar_new, @function foobar_new: jr ra .size foobar_new, .-foobar_new .symver foobar_new, foobar@@New .section .note.GNU-stack,"",@progbits % cat relax-twice-2.s .file "<artificial>" .option pic .text .section .rodata.str1.8,"aMS",@progbits,1 .align 3 .LC0: .string "%u" .text .align 1 .globl relaxme .type relaxme, @function relaxme: addi sp,sp,-32 addi a2,sp,12 lla a1,.LC0 li a0,0 sd ra,24(sp) call sscanf@plt ld ra,24(sp) addi sp,sp,32 jr ra .size relaxme, .-relaxme .align 1 .globl foobar_new .type foobar_new, @function foobar_new: li a0,1 ret .size foobar_new, .-foobar_new .symver foobar_new, foobar@@New .align 1 .globl foobar_old .type foobar_old, @function foobar_old: addi sp,sp,-16 sd ra,8(sp) call foobar@plt ld ra,8(sp) snez a0,a0 addi sp,sp,16 jr ra .size foobar_old, .-foobar_old .symver foobar_old, foobar@Old .section .note.GNU-stack,"",@progbits % cat relax-twice.ver Old { global: foobar; relaxme; local: *; }; New { global: foobar; } Old; % ../as-new -o relax-twice-1.o relax-twice-1.s % ../as-new -o relax-twice-2.o relax-twice-2.s % ../ld-new -o bla.so --relax -shared --version-script relax-twice.ver relax-twice-1.o relax-twice-2.o % nm bla.so ... 000000000000102c t foobar_new 0000000000001028 T foobar@@New ... Note how these two symbols are supposed to point to the same address. (The stunt with the weak variant of foobar_new and foobar@@New in relax-twice-1.s is only there to prime the internal symbol table of ld in the same way as it would have been with LTO and the linker plugin. The prevailing variants are the ones from relax-twice-2.s) The reason is the one already analyzed in PR22756: multiple entries in sym_hashes[] pointing to the same symbol entry, such that the relaxation code adjusts the same entry multiple times. That is the situation always created by aliases, and the PR22756 patch fixes it for hidden aliases (created by non-default symbol versions, i.e. foobar@BLA). Of course the same can happen with non-hidden aliases, as above demonstrates. A definitely working fix would be to always check for duplicates, but a slowdown for that can then only be avoided by extending the elf symbol hash structure to contain an already-handled flag. The more immediate, but possibly also still incomplete fix is simply: --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -3993,7 +3993,7 @@ riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count, foo becomes an alias for foo@BAR, and hence they need the same treatment. */ if (link_info->wrap_hash != NULL - || sym_hash->versioned == versioned_hidden) + || sym_hash->versioned != unversioned) { struct elf_link_hash_entry **cur_sym_hashes; I will note that the problem exists for all targets that implement relaxation that can also delete bytes from sections (it seems to all have been copied around for decades), at least MIPS and AVR seem somewhat relevant still, but it's also m10[23]00, cr16, h8300, ip2k, m32c, m68hc11, msp430, rl78, rx and v850. Only riscv goes to an effort to remidy the situation with symbol aliases. -- You are receiving this mail because: You are on the CC list for the bug.