Bug 13577

Summary: Gold linker does not respect --dynamic-list option
Product: binutils Reporter: Kevin Funk <kfunk>
Component: goldAssignee: Cary Coutant <ccoutant>
Status: RESOLVED FIXED    
Severity: normal CC: ccoutant
Priority: P2    
Version: 2.21   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: Test case
Test case - command line output

Description Kevin Funk 2012-01-09 21:32:18 UTC
Created attachment 6154 [details]
Test case

We encountered some problems with regards to symbols not being relocatable in DSOs.

The shared libraries in our case are compiled with -Bsymbolic-functions turned on. To avoid that certain symbols are bound to the definition within the shared library we specificy the --dynamic-list option. This seems to work fine when ld.bfd is used, but does seem to be ignored when ld.gold is used instead.

I've attached a small test case showing the issue. There is the source file libtest.cpp containing an symbol "foo" which in turn is called by "test_foo". The symbol "foo" is supposed to be relocatable even if compiled with -Bsymbolic. To achieve this --dynamic-list is passed, pointing to a file which declares "foo" global.

When ld.bfd is in use, the resulting libtestsym.so (which is compiled with -Bsymbolic-functions -Wl,--dynamic-list=libtest_syms.txt) contains a symbol "foo" which is relocatable (checked with "objdump -D libtestsym.so | grep foo | grep plt").
When being linked by ld.gold, however, "foo" in libtestsym.so does not seem to be relocatable, as seen by the missing .PLT entry for "foo".

I'm attaching the test case + command line sequence to show this problem.

Note: I've also tested with latest trunk version of gold, still did not work.
Comment 1 Kevin Funk 2012-01-09 21:33:41 UTC
Created attachment 6155 [details]
Test case - command line output
Comment 2 Kevin Funk 2013-12-13 14:48:40 UTC
Bump. Anyone working on that?
Comment 3 Cary Coutant 2013-12-14 00:04:47 UTC
> Bump. Anyone working on that?

Sorry, no one that I know of.

Gold's implementation of --dynamic-list seems to do nothing more than force the linker to create a dynamic symbol table entry for it -- it does not undo the effect of -Bsymbolic or protected visibility. My interpretation of the Gnu ld manual is that gold is in fact wrong here.

The fix should be a simple patch to Symbol::is_preemptible() in symtab.h. I'll try to get a patch in soon.

-cary
Comment 4 Cary Coutant 2014-02-06 01:57:55 UTC
It was a bit more complicated. The --dynamic-list option is actually mutually exclusive with -Bsymbolic and -Bsymbolic-functions. If a dynamic list is given, the Gnu linker makes only those symbols preemptible, and binds the remaining symbols within the library. I've changed gold to do the same thing.
Comment 5 Sourceware Commits 2014-02-06 02:03:21 UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gdb and binutils".

The branch, master has been updated
       via  fd834e57ffce2f5dbe3443f034e68cebd63ee89a (commit)
      from  ee1e2d4fb692736c754b42b69eb88c1f436c5f15 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=fd834e57ffce2f5dbe3443f034e68cebd63ee89a

commit fd834e57ffce2f5dbe3443f034e68cebd63ee89a
Author: Cary Coutant <ccoutant@google.com>
Date:   Wed Feb 5 14:01:52 2014 -0800

    Fix problems with the --dynamic-list option.
    
    PR gold/13577 complains that even though symbols listed in
    the --dynamic-list script are exported, they are still bound symbolically
    if -Bsymbolic is also used. There are two underlying problems here.
    First, -Bsymbolic should be overridden by --dynamic-list, since the
    dynamic list provides an explicit list of symbols that are not bound
    within the library, and if we go ahead and set DT_SYMBOLIC, then the
    dynamic loader will bind it within the library anyway. Second, gold
    did not properly identify the symbols listed in the file as preemptible.
    
    PR gold/16530 complains that symbols listed in the --dynamic-list script
    can still be garbage collected. I've fixed this by checking the symbols
    as they're added to the symbol table. (Unlike the --export-dynamic-symbol
    option, we can't iterate over the list, because the --dynamic-list script
    can have wildcards in it.)
    
    gold/
    
    2014-02-05  Cary Coutant  <ccoutant@google.com>
    
    	PR gold/13577
    	* options.cc (General_options::parse_dynamic_list):
    	Set have_dynamic_list_.
    	(General_options::General_options): Initialize have_dynamic_list_.
    	(General_options::finalize): Turn off -Bsymbolic and
    	-Bsymbolic-functions if --dynamic-list provided.
    	* options.h (General_options::have_dynamic_list): New function.
    	(General_options::have_dynamic_list_): New data member.
    	* symtab.h (Symbol::is_preemptible): Handle --dynamic-list
    	correctly.
    
    	PR gold/16530
    	* symtab.cc (Symbol_table::add_from_relobj): If symbol is named
    	in --dynamic-list, mark it.
    
    	* testsuite/Makefile.am (gc_dynamic_list_test.sh): New test case.
    	(dynamic_list_2): New test case.
    	* testsuite/Makefile.in: Regenerate.
    	* testsuite/dynamic_list_2.cc: New file.
    	* testsuite/dynamic_list_2.t: New file.
    	* testsuite/dynamic_list_lib1.cc: New file.
    	* testsuite/dynamic_list_lib2.cc: New file.
    	* testsuite/gc_dynamic_list_test.c: New file.
    	* testsuite/gc_dynamic_list_test.sh: New file.
    	* testsuite/gc_dynamic_list_test.t: New file.

-----------------------------------------------------------------------

Summary of changes:
 gold/options.cc                        |    9 ++++++
 gold/options.h                         |    7 ++++
 gold/symtab.cc                         |    3 +-
 gold/symtab.h                          |   10 +++++-
 gold/testsuite/Makefile.am             |   26 +++++++++++++++++
 gold/testsuite/Makefile.in             |   47 ++++++++++++++++++++++++++++--
 gold/testsuite/dynamic_list_2.cc       |   40 ++++++++++++++++++++++++++
 gold/testsuite/dynamic_list_2.t        |   27 +++++++++++++++++
 gold/testsuite/dynamic_list_lib1.cc    |   37 ++++++++++++++++++++++++
 gold/testsuite/dynamic_list_lib2.cc    |   49 ++++++++++++++++++++++++++++++++
 gold/testsuite/gc_dynamic_list_test.c  |   34 ++++++++++++++++++++++
 gold/testsuite/gc_dynamic_list_test.sh |   39 +++++++++++++++++++++++++
 gold/testsuite/gc_dynamic_list_test.t  |   25 ++++++++++++++++
 13 files changed, 347 insertions(+), 6 deletions(-)
 create mode 100644 gold/testsuite/dynamic_list_2.cc
 create mode 100644 gold/testsuite/dynamic_list_2.t
 create mode 100644 gold/testsuite/dynamic_list_lib1.cc
 create mode 100644 gold/testsuite/dynamic_list_lib2.cc
 create mode 100644 gold/testsuite/gc_dynamic_list_test.c
 create mode 100755 gold/testsuite/gc_dynamic_list_test.sh
 create mode 100644 gold/testsuite/gc_dynamic_list_test.t
Comment 6 Cary Coutant 2014-02-06 02:05:25 UTC
Fixed on trunk.
Comment 7 Sourceware Commits 2015-02-17 06:15:52 UTC
The master branch has been updated by Cary Coutant <ccoutant@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e9c1bdad269c0c3352eebcc9481ed65144001b0b

commit e9c1bdad269c0c3352eebcc9481ed65144001b0b
Author: Cary Coutant <ccoutant@google.com>
Date:   Mon Feb 16 22:15:12 2015 -0800

    Fix --dynamic-list so that symbols not in the list are still exported.
    
    In PR 13577, the complaint was that -Bsymbolic was overriding the binding
    behavior for symbols listed in the --dynamic-list by setting the DT_SYMBOLIC
    tag in the dynamic table. In reading the Gnu ld manual, I decided that
    --dynamic-list should be mutually exclusive of -Bsymbolic, and modified
    gold so that --dynamic-list would treat symbols listed as preemptible,
    and all other symbols as internally bound. I was wrong.
    
    PR 16992 shows that with --dynamic-list (and not -Bsymbolic), a symbol
    not listed in the dynamic list is being internally bound within the
    shared library, but because it's still in the dynamic symbol table, we
    expose it to a COPY relocation, and things go really bad from there.
    
    (I can reproduce the same failure, simply by turning on -Bsymbolic-functions
    with the Gnu linker. Even though the symbol is bound internally, it's
    still exported to the dynamic symbol table, and is exposed to a COPY
    relocation.)
    
    I've backed out part of the fix for PR 13577, and -Bsymbolic (or
    -Bsymbolic-functions) can now be used with --dynamic-list, but if the
    two are used together, we do not set DT_SYMBOLIC or DF_SYMBOLIC
    (this matches Gnu ld behavior). We now treat symbols listed in the
    dynamic list as premptible, but we do not automatically treat symbols
    not listed there as non-premptible.
    
    gold/
    	PR gold/13577
    	PR gold/16992
    	* layout.cc (Layout::finish_dynamic_section): Don't set DT_SYMBOLIC or
    	DF_SYMBOLIC if --dynamic-list option is used.
    	* options.cc (General_options::finalize): --dynamic-list is not
    	mutually exclusive with -Bsymbolic.
    	* symtab.h (Symbol::is_preemptible): Don't exclude dynamic symbols not
    	listed in --dynamic-list.
    	* testsuite/Makefile.am (dynamic_list_lib2.so): Add
    	-Bsymbolic-functions.
    	* testsuite/Makefile.in: Regenerate.