[llvm-bugs] [Bug 36295] New: symbol version "has undefined version error" when all symbols with version are hidden.

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Feb 8 02:53:31 PST 2018


https://bugs.llvm.org/show_bug.cgi?id=36295

            Bug ID: 36295
           Summary: symbol version "has undefined version error" when all
                    symbols with version are hidden.
           Product: lld
           Version: unspecified
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: ELF
          Assignee: unassignedbugs at nondot.org
          Reporter: peter.smith at linaro.org
                CC: llvm-bugs at lists.llvm.org

While attempting to build the Android dynamic linker on Arm I ran into many
errors of the form:
"out/soong/.intermediates/bionic/libc/libc_nomalloc/android_arm_armv7-a_static_core/libc_nomalloc.a(__aeabi.o):
symbol __aeabi_memcpy at LIBC_PRIVATE has undefined version LIBC_PRIVATE"
"error:
out/soong/.intermediates/bionic/libc/libc_nomalloc/android_arm_armv7-a_static_core/libc_nomalloc.a(__aeabi.o):
symbol __aeabi_memmove8@@LIBC_N has undefined version LIBC_N"

I did not get these errors with ld.gold, although I did get them with ld.bfd.
The errors are only Arm specific on the dynamic linker because the file
__aeabi.o is Arm specific.

It turns out that there was indeed no version script [*] so the LIBC_PRIVATE
and LIBC_N were not defined. However the dynamic linker links with the flag
"--exclude-libs ALL" which prevents symbols in the library from being exported
into the dynamic symbol table.

A simplified reproducer on x86:
t.s:
        .globl foo_impl2
foo_impl2:
        ret

        .symver foo_impl, foo@@LIBC_N
        .symver foo_impl2, foo at LIBC_PRIVATE
t2.s:
        .text
        .globl foo
        .globl _start
_start:        
        ret

        .data
        .quad foo
clang -fPIC t.s t2.s -c
ld.gold --shared t2.o t.a -o t2.so --exclude-libs ALL # All works fine
ld.bfd --shared t2.o t.a -o t2.so --exclude-libs ALL
t2.so: version node not found for symbol foo at LIBC_PRIVATE
ld.lld --shared t2.o t.a -o t2.so --exclude-libs ALL 
ld.lld: error: t.a(t.o): symbol foo@@LIBC_N has undefined version LIBC_N
ld.lld: error: t.a(t.o): symbol foo at LIBC_PRIVATE has undefined version
LIBC_PRIVATE


Something like "--exclude-libs ALL" is important to get this past gold as the
.symver foo_impl, foo@@VERSION will always create the symbol foo with
STV_DEFAULT visibility.

I don't think that there is a clear answer in the symbol versioning
specification as to whether the linker should give an error in this case. It is
true that the version isn't defined, but if the symbol isn't in the dynamic
symbol table then do we care? Gold will give an error message if a symbol
definition in the dynamic symbol table has an undefined version. Personally I
have some sympathy for Gold's view, for example lld doesn't give an error
message for an undefined version in an executable.

For what it is worth, and this could be a separate PR, I noticed that when I
wrote a simple symbol version script for LLD to force the symbols local, they
were exported into the dynamic symbol table with default visibility:

LIBC_PRIVATE
{
local:
  foo;
};

LIBC_N
{
local:
 foo;
};
ld.lld --shared t2.o t.a -o t2.so --exclude-libs ALL --version-script=t.version
readelf --dyn-syms t2.so
Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000001000     0 NOTYPE  GLOBAL DEFAULT    8 _start
     2: 0000000000001004     0 NOTYPE  GLOBAL DEFAULT    8 foo@@LIBC_N
     3: 0000000000001005     0 NOTYPE  GLOBAL DEFAULT    8 foo at LIBC_PRIVATE

My understanding of local: was that it was supposed to prevent symbols from
being exported into the symbol table, and this is the behaviour I see from gold
and bfd. It could be that my symbol version script is wrong though.

I think that there are potentially two changes that could be made:
- Do not error if there is no version defined for a symbol that isn't in the
dynamic symbol table.
- LLD's local: implementation doesn't seem to be working for the version script
above. 

[*] The libc_nomalloc.a library is used in the bionic libc library where LIBC_N
and LIBC_PRIVATE are defined in a version script, and in the dynamic linker
where there are no definitions.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20180208/0721a5a5/attachment-0001.html>


More information about the llvm-bugs mailing list