Bug 6022 - local wildcard breaks versioning scripts for -rdynamic executables
Summary: local wildcard breaks versioning scripts for -rdynamic executables
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.18
: P2 normal
Target Milestone: ---
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-04-02 10:19 UTC by Pierre Habouzit
Modified: 2009-01-24 03:12 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2009-01-23 01:49:35


Attachments
tarball with a makefile, a simple source, and two version scripts (614 bytes, application/x-tar)
2008-04-02 10:20 UTC, Pierre Habouzit
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Pierre Habouzit 2008-04-02 10:19:22 UTC
Basically, as soon as you have a version script with a { local: *; } wildcard, 
the symbols from other versions are *not* exported in executables built for 
back-linking.

Attached is a tarball with a simple test case for the issue.

Right now running make shows the following output. The issue being obviously 
that there is no `VER_2 sym_ver2` in the executable linked with a version 
script using local wildcards, OTOH a shared object obviously has the expected 
results.

Using explicit versioning from the C source using internal symbols (e.g. 
internal_sym_ver{1,2}) with asm(".symver internal_sym_ver2,sym_ver2@@VER_2") 
fails in the same way.

=====================================================
$ make
gcc -rdynamic -DMAIN -Wl,--version-script=local.ver   -O2 -Wall -Wextra -o exe 
test.c
gcc -rdynamic -DMAIN -Wl,--version-script=nolocal.ver -O2 -Wall -Wextra -o 
exe-no test.c
gcc -shared -fPIC    -Wl,--version-script=local.ver   -O2 -Wall -Wextra -o 
lib.so test.c
gcc -shared -fPIC    -Wl,--version-script=nolocal.ver -O2 -Wall -Wextra -o 
lib-no.so test.c
objdump -T exe exe-no

exe:     file format elf64-x86-64

DYNAMIC SYMBOL TABLE:
0000000000000000  w   D  *UND*	0000000000000000              __gmon_start__
0000000000000000      DF *UND*	00000000000001c2  GLIBC_2.2.5 
__libc_start_main
0000000000000000 g    DO *ABS*	0000000000000000  VER_1       VER_1
0000000000000000 g    DO *ABS*	0000000000000000  VER_2       VER_2
0000000000400570 g    DF .text	0000000000000002  VER_1       sym_ver1



exe-no:     file format elf64-x86-64

DYNAMIC SYMBOL TABLE:
0000000000000000  w   D  *UND*	0000000000000000              __gmon_start__
0000000000000000      DF *UND*	00000000000001c2  GLIBC_2.2.5 
__libc_start_main
0000000000000000 g    DO *ABS*	0000000000000000  VER_1       VER_1
0000000000000000 g    DO *ABS*	0000000000000000  VER_2       VER_2
00000000004005a0 g    DF .text	0000000000000002  VER_1       sym_ver1
00000000004005b0 g    DF .text	0000000000000002  VER_2       sym_ver2


objdump -T lib.so lib-no.so

lib.so:     file format elf64-x86-64

DYNAMIC SYMBOL TABLE:
0000000000000418 l    d  .init	0000000000000000              .init
0000000000000000  w   D  *UND*	0000000000000000              __gmon_start__
0000000000000000  w   D  *UND*	0000000000000000              
_Jv_RegisterClasses
0000000000000000  w   DF *UND*	00000000000000c5  GLIBC_2.2.5 __cxa_finalize
0000000000000000 g    DO *ABS*	0000000000000000  VER_1       VER_1
0000000000000000 g    DO *ABS*	0000000000000000  VER_2       VER_2
0000000000000530 g    DF .text	0000000000000002  VER_1       sym_ver1
0000000000000540 g    DF .text	0000000000000002  VER_2       sym_ver2



lib-no.so:     file format elf64-x86-64

DYNAMIC SYMBOL TABLE:
00000000000004f0 l    d  .init	0000000000000000              .init
0000000000000000  w   D  *UND*	0000000000000000              __gmon_start__
0000000000000000  w   D  *UND*	0000000000000000              
_Jv_RegisterClasses
0000000000000000  w   DF *UND*	00000000000000c5  GLIBC_2.2.5 __cxa_finalize
0000000000200910 g    D  *ABS*	0000000000000000  Base        _end
0000000000000000 g    DO *ABS*	0000000000000000  VER_1       VER_1
0000000000200900 g    D  *ABS*	0000000000000000  Base        _edata
0000000000000000 g    DO *ABS*	0000000000000000  VER_2       VER_2
0000000000200900 g    D  *ABS*	0000000000000000  Base        __bss_start
0000000000000610 g    DF .text	0000000000000002  VER_1       sym_ver1
00000000000004f0 g    DF .init	0000000000000000  Base        _init
0000000000000668 g    DF .fini	0000000000000000  Base        _fini
0000000000000620 g    DF .text	0000000000000002  VER_2       sym_ver2
=====================================================

ld --version
GNU ld (GNU Binutils for Debian) 2.18.0.20080103
Comment 1 Pierre Habouzit 2008-04-02 10:20:04 UTC
Created attachment 2344 [details]
tarball with a makefile, a simple source, and two version scripts
Comment 2 Pierre Habouzit 2008-04-02 10:28:10 UTC
Further fiddling with the issue shows that local: * works properly if you put 
it in the _last_ version section of the version script. E.g. a script like:

-----8<----
VER_1 {
    global:
        sym_ver1;
};
VER_2 {
    global:
        sym_ver1;
    local:
        *;
} VER_1;
----->8----

or even:

-----8<----
VER_1 {
    global:
        sym_ver1;
};
VER_2 {
    global:
        sym_ver1;
} VER_1;
PRIVATE {
    local:
        *;
};
----->8----

product the expected results. If you put PRIVATE { local: *; }; first, it 
breaks.
Comment 3 cvs-commit@gcc.gnu.org 2009-01-24 03:10:57 UTC
Subject: Bug 6022

CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2009-01-24 03:10:43

Modified files:
	bfd            : ChangeLog elflink.c 

Log message:
	PR 6022
	* elflink.c (find_version_for_sym): New function split out from,
	but without export_dynamic test, ..
	(_bfd_elf_link_assign_sym_version): ..here.
	(_bfd_elf_export_symbol): Use it.

Patches:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.4434&r2=1.4435
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&r1=1.326&r2=1.327

Comment 4 Alan Modra 2009-01-24 03:12:35 UTC
.