https://sourceware.org/bugzilla/show_bug.cgi?id=32783

            Bug ID: 32783
           Summary: [RISC-V] Spurious dynamic weakdef symbols in binary
           Product: binutils
           Version: 2.45 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: laanwj at protonmail dot com
  Target Milestone: ---

While performing deterministic guix builds for different architectures, we
noticed one specific behavior only in RISC-V builds: apparently randomly (but
deterministically), dynamic symbols were exported from the binary. 

To reproduce, create a small C++ test program:

#include <iostream>

int main()
{
    std::string test{"12345"};
    std::cout << test << std::endl;

    return 0;
}

The resulting binary will contain a spurious symbol
"_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag":

$ riscv64-linux-gnu-g++ test.cpp -o test.rv -Wl,--exclude-libs,ALL
-fvisibility=hidden  -static-libstdc++ 
$ riscv64-linux-gnu-objdump -T test.rv|grep "\.text"
00000000000176b0 l    d  .text  0000000000000000              .text
0000000000018810  w   DF .text  00000000000000fe  Base       
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag

X86, for comparison; all other architectures i've tried behave like this:

$ x86_64-linux-gnu-g++ test.cpp -o test.x64 -Wl,--exclude-libs,ALL
-fvisibility=hidden  -static-libstdc++ 
$ x86_64-linux-gnu-objdump -T test.x64|grep "\.text"
(no output)

Even though libc++ is linked statically, default visibility is hidden, and all
libs are excluded from export, the weakdef symbol leaks into the final binary.

Eventually we narrowed it down to the following code in allocate_dynrelocs in
bfd/elf64-riscv.c:

      /* Make sure this symbol is output as a dynamic symbol.
         Undefined weak syms won't yet be marked as dynamic.  */
      if (h->dynindx == -1
          && !h->forced_local)
        {
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return false;
        }

Commenting out this specific call to bfd_elf_link_record_dynamic_symbol makes
the spurious symbols disappear. i don't, however, understand the motivation for
this logic–what do relocations have to do with whether to export symbols?–so
this is where we get stuck.

More details of the investigation can be found in
https://github.com/bitcoin/bitcoin/issues/28095 . Let me know if you need more
information.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to