bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gold/23268] New: gold doesn't handle symbol versions like BFD ld wh


From: mh-sourceware at glandium dot org
Subject: [Bug gold/23268] New: gold doesn't handle symbol versions like BFD ld when linking executable with both -E and --version-script
Date: Wed, 06 Jun 2018 23:06:15 +0000

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

            Bug ID: 23268
           Summary: gold doesn't handle symbol versions like BFD ld when
                    linking executable with both -E and --version-script
           Product: binutils
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: gold
          Assignee: ccoutant at gmail dot com
          Reporter: mh-sourceware at glandium dot org
                CC: ian at airs dot com
  Target Milestone: ---

$ cat foo.c
void foo() {}
int main() { return 0; }

$ cat ver
FOO {
    global: foo;
};

$ gcc -o foo foo.c -Wl,--version-script,ver -fuse-ld=gold -rdynamic

$ objdump -T foo | grep -e '\b\(main\|foo\)$'
000000000000085a g    DF .text  0000000000000007  Base        foo
0000000000000861 g    DF .text  000000000000000b  Base        main

The above is actually confusing because of bug 23267.

$ readelf -V foo

Version symbols section '.gnu.version' contains 20 entries:
 Addr: 00000000000005dc  Offset: 0x0005dc  Link: 4 (.dynsym)
  000:   0 (*local*)       2 (GLIBC_2.2.5)   2 (GLIBC_2.2.5)   0 (*local*)    
  004:   0 (*local*)       0 (*local*)       1 (*global*)      1 (*global*)   
  008:   1 (*global*)      1 (*global*)      1 (*global*)      1 (*global*)   
  00c:   1 (*global*)      1 (*global*)      1 (*global*)      1 (*global*)   
  010:   1 (*global*)      1 (*global*)      1 (*global*)      1 (*global*)   

Version definition section '.gnu.version_d' contains 1 entry:
  Addr: 0x0000000000000604  Offset: 0x000604  Link: 5 (.dynstr)
  000000: Rev: 1  Flags: none  Index: 1  Cnt: 1  Name: FOO

Version needs section '.gnu.version_r' contains 1 entry:
 Addr: 0x0000000000000620  Offset: 0x000620  Link: 5 (.dynstr)
  000000: Version: 1  File: libc.so.6  Cnt: 1
  0x0010:   Name: GLIBC_2.2.5  Flags: none  Version: 2

So the problem here is that both exported symbols end up with the same version,
named FOO.

What BFD ld does is:
$ objdump -T foo | grep -e '\b\(main\|foo\)$'
000000000000084a g    DF .text  0000000000000007  FOO         foo
0000000000000851 g    DF .text  000000000000000b  Base        main

$ readelf -V foo

Version symbols section '.gnu.version' contains 20 entries:
 Addr: 00000000000005ba  Offset: 0x0005ba  Link: 5 (.dynsym)
  000:   0 (*local*)       0 (*local*)       3 (GLIBC_2.2.5)   0 (*local*)    
  004:   0 (*local*)       3 (GLIBC_2.2.5)   1 (*global*)      1 (*global*)   
  008:   2 (FOO)           1 (*global*)      1 (*global*)      2 (FOO)        
  00c:   1 (*global*)      1 (*global*)      1 (*global*)      1 (*global*)   
  010:   1 (*global*)      1 (*global*)      1 (*global*)      1 (*global*)   

Version definition section '.gnu.version_d' contains 2 entries:
  Addr: 0x00000000000005e8  Offset: 0x0005e8  Link: 6 (.dynstr)
  000000: Rev: 1  Flags: BASE  Index: 1  Cnt: 1  Name: foo
  0x001c: Rev: 1  Flags: none  Index: 2  Cnt: 1  Name: FOO

Version needs section '.gnu.version_r' contains 1 entry:
 Addr: 0x0000000000000620  Offset: 0x000620  Link: 6 (.dynstr)
  000000: Version: 1  File: libc.so.6  Cnt: 1
  0x0010:   Name: GLIBC_2.2.5  Flags: none  Version: 3

That is, it places main in the Base version, and foo in the FOO version.

Please note that gold actually does that when linking libraries:

$ gcc -shared -o libfoo.so foo.c -Wl,--version-script,ver -fuse-ld=gold
$ objdump -T libfoo.so | grep -e '\b\(main\|foo\)$'
000000000000069a g    DF .text  0000000000000007  FOO         foo
00000000000006a1 g    DF .text  000000000000000b  Base        main

And more than skipping the base version, it actually attributes all symbols to
the first version in executables:
$ cat ver2
FOO {
    global: foo;
};
BAR {
    global: main;
};

$ gcc -o foo foo.c -Wl,--version-script,ver2 -fuse-ld=gold -rdynamic

$ LANG=C objdump -T foo | grep -e '\b\(main\|foo\)$'
000000000000089a g    DF .text  0000000000000007  Base        foo
00000000000008a1 g    DF .text  000000000000000b  Base        main

$ readelf -V foo
Version symbols section '.gnu.version' contains 21 entries:
 Addr: 00000000000005f8  Offset: 0x0005f8  Link: 4 (.dynsym)
  000:   0 (*local*)       3 (GLIBC_2.2.5)   3 (GLIBC_2.2.5)   0 (*local*)    
  004:   0 (*local*)       0 (*local*)       1 (*global*)      1 (*global*)   
  008:   1 (*global*)      1 (*global*)      1 (*global*)      1 (*global*)   
  00c:   1 (*global*)      1 (*global*)      1 (*global*)      1 (*global*)   
  010:   1 (*global*)      1 (*global*)      1 (*global*)      1 (*global*)   
  014:   1 (*global*)   

Version definition section '.gnu.version_d' contains 2 entries:
  Addr: 0x0000000000000624  Offset: 0x000624  Link: 5 (.dynstr)
  000000: Rev: 1  Flags: none  Index: 1  Cnt: 1  Name: FOO
  0x001c: Rev: 1  Flags: none  Index: 2  Cnt: 1  Name: BAR

Version needs section '.gnu.version_r' contains 1 entry:
 Addr: 0x000000000000065c  Offset: 0x00065c  Link: 5 (.dynstr)
  000000: Version: 1  File: libc.so.6  Cnt: 1
  0x0010:   Name: GLIBC_2.2.5  Flags: none  Version: 3

Here, main is not even associated to version BAR.

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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]