<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - lld --exclude-libs exports symbol with .symver directive (if version exists in version script)"
   href="https://bugs.llvm.org/show_bug.cgi?id=48702">48702</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>lld --exclude-libs exports symbol with .symver directive (if version exists in version script)
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>lld
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>ELF
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>rprichard@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, smithp352@googlemail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>If an input file uses .symver to assign versions to a symbol, and that version
is present in a version script, then --exclude-libs doesn't localize the
symbol. If the version is missing, then lld does localize the symbol, which is
behavior that Bionic's dynamic loader currently relies on.

ld.bfd/gold do localize the symbol in this situation.

I'm not quite sure what the right behavior is, but lld's behavior might make it
harder to fix <a href="https://issuetracker.google.com/73020933">https://issuetracker.google.com/73020933</a>.

Test script:

    #!/bin/bash
    set -e

    LLVM=/x/llvm-upstream/stage1/bin
    CC="$LLVM/clang -target x86_64-linux-gnu"
    AR="$LLVM/llvm-ar"

    cat >archive_func.c <<EOF
      void func_impl() {}
      void func_impl2() {}

      #define __AEABI_SYMVERS(fn_name) \
      __asm__(".symver " #fn_name "_impl, " #fn_name "@@LIBC_N"); \
      __asm__(".symver " #fn_name "_impl2, " #fn_name "@LIBC_PRIVATE")

      __AEABI_SYMVERS(func);
    EOF

    cat >dso_func.c <<EOF
      void func();
      void func2() { func(); }
      void __loader_dlopen() {}
    EOF

    cat >version.txt <<EOF
    LINKER {
      global:
        __loader_dlopen;
      local:
        *;
    };
    LIBC_N { local: *; };
    LIBC_PRIVATE { local: *; };
    EOF

    $CC archive_func.c -fpic -c
    rm -fr libarchive.a
    $AR rcs libarchive.a archive_func.o

    $CC -c dso_func.c -fpic
    $CC -fuse-ld=lld -nostdlib dso_func.o -shared -o libdso.so libarchive.a
-Wl,--exclude-libs,libarchive.a -Wl,--version-script=version.txt

    $LLVM/llvm-readelf -s -W -r libdso.so


Output (with lld):

    Relocation section '.rela.plt' at offset 0x3a0 contains 1 entries:
        Offset             Info             Type               Symbol's Value 
Symbol's Name + Addend
    00000000000035e8  0000000200000007 R_X86_64_JUMP_SLOT     00000000000014b0
func@@LIBC_N + 0

    Symbol table '.dynsym' contains 4 entries:
       Num:    Value          Size Type    Bind   Vis       Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND 
         1: 00000000000014a0     6 FUNC    GLOBAL DEFAULT    10
__loader_dlopen@@LINKER
         2: 00000000000014b0     6 FUNC    GLOBAL DEFAULT    10 func@@LIBC_N
         3: 00000000000014c0     6 FUNC    GLOBAL DEFAULT    10
func@LIBC_PRIVATE

    Symbol table '.symtab' contains 10 entries:
       Num:    Value          Size Type    Bind   Vis       Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND 
         1: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS dso_func.c
         2: 0000000000001490    13 FUNC    LOCAL  DEFAULT    10 func2
         3: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS archive_func.c
         4: 00000000000014b0     6 FUNC    LOCAL  DEFAULT    10 func_impl
         5: 00000000000014c0     6 FUNC    LOCAL  DEFAULT    10 func_impl2
         6: 00000000000024f0     0 NOTYPE  LOCAL  HIDDEN     12 _DYNAMIC
         7: 00000000000014a0     6 FUNC    GLOBAL DEFAULT    10 __loader_dlopen
         8: 00000000000014b0     6 FUNC    GLOBAL DEFAULT    10 func
         9: 00000000000014c0     6 FUNC    GLOBAL DEFAULT    10 func

With ld.bfd, the symbol is instead hidden:

    There are no relocations in this file.

    Symbol table '.dynsym' contains 5 entries:
       Num:    Value          Size Type    Bind   Vis       Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND 
         1: 0000000000000000     0 OBJECT  GLOBAL DEFAULT   ABS
LIBC_PRIVATE@@LIBC_PRIVATE
         2: 0000000000000000     0 OBJECT  GLOBAL DEFAULT   ABS LINKER@@LINKER
         3: 0000000000001010     6 FUNC    GLOBAL DEFAULT     7
__loader_dlopen@@LINKER
         4: 0000000000000000     0 OBJECT  GLOBAL DEFAULT   ABS LIBC_N@@LIBC_N

    Symbol table '.symtab' contains 26 entries:
       Num:    Value          Size Type    Bind   Vis       Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND 
         1: 0000000000000200     0 SECTION LOCAL  DEFAULT     1 .hash
         2: 0000000000000228     0 SECTION LOCAL  DEFAULT     2 .gnu.hash
         3: 0000000000000260     0 SECTION LOCAL  DEFAULT     3 .dynsym
         4: 00000000000002d8     0 SECTION LOCAL  DEFAULT     4 .dynstr
         5: 000000000000030e     0 SECTION LOCAL  DEFAULT     5 .gnu.version
         6: 0000000000000318     0 SECTION LOCAL  DEFAULT     6 .gnu.version_d
         7: 0000000000001000     0 SECTION LOCAL  DEFAULT     7 .text
         8: 0000000000002000     0 SECTION LOCAL  DEFAULT     8 .eh_frame_hdr
         9: 0000000000002030     0 SECTION LOCAL  DEFAULT     9 .eh_frame
        10: 0000000000003f10     0 SECTION LOCAL  DEFAULT    10 .dynamic
        11: 0000000000000000     0 SECTION LOCAL  DEFAULT    11 .comment
        12: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS dso_func.c
        13: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS archive_func.c
        14: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS 
        15: 0000000000003f10     0 OBJECT  LOCAL  DEFAULT    10 _DYNAMIC
        16: 0000000000001020     6 FUNC    LOCAL  DEFAULT     7 func@@LIBC_N
        17: 0000000000002000     0 NOTYPE  LOCAL  DEFAULT     8
__GNU_EH_FRAME_HDR
        18: 0000000000001000    13 FUNC    LOCAL  DEFAULT     7 func2
        19: 0000000000001030     6 FUNC    LOCAL  DEFAULT     7 func_impl2
        20: 0000000000001020     6 FUNC    LOCAL  DEFAULT     7 func_impl
        21: 0000000000001030     6 FUNC    LOCAL  DEFAULT     7
func@LIBC_PRIVATE
        22: 0000000000001010     6 FUNC    GLOBAL DEFAULT     7 __loader_dlopen
        23: 0000000000000000     0 OBJECT  GLOBAL DEFAULT   ABS LIBC_PRIVATE
        24: 0000000000000000     0 OBJECT  GLOBAL DEFAULT   ABS LINKER
        25: 0000000000000000     0 OBJECT  GLOBAL DEFAULT   ABS LIBC_N

FWIW: ld.gold warns about the wildcards:

    /usr/bin/x86_64-linux-gnu-ld.gold: warning: wildcard match appears in both
version 'LINKER' and 'LIBC_N' in script
    /usr/bin/x86_64-linux-gnu-ld.gold: warning: wildcard match appears in both
version 'LIBC_N' and 'LIBC_PRIVATE' in script

I see the same behavior if I leave the LIBC_N and LIBC_PRIVATE version blocks
empty:

    LIBC_N {};
    LIBC_PRIVATE {};</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>