Fix problems with the --dynamic-list option.
authorCary Coutant <ccoutant@google.com>
Wed, 5 Feb 2014 22:01:52 +0000 (14:01 -0800)
committerCary Coutant <ccoutant@google.com>
Thu, 6 Feb 2014 02:01:47 +0000 (18:01 -0800)
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.

13 files changed:
gold/options.cc
gold/options.h
gold/symtab.cc
gold/symtab.h
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/dynamic_list_2.cc [new file with mode: 0644]
gold/testsuite/dynamic_list_2.t [new file with mode: 0644]
gold/testsuite/dynamic_list_lib1.cc [new file with mode: 0644]
gold/testsuite/dynamic_list_lib2.cc [new file with mode: 0644]
gold/testsuite/gc_dynamic_list_test.c [new file with mode: 0644]
gold/testsuite/gc_dynamic_list_test.sh [new file with mode: 0755]
gold/testsuite/gc_dynamic_list_test.t [new file with mode: 0644]

index 000e6d07a32c79eb6236f10d052dca6646da5d7f..6b49459e44329d4727517ab99b99b1419ed6d7af 100644 (file)
@@ -549,6 +549,7 @@ General_options::parse_dynamic_list(const char*, const char* arg,
 {
   if (!read_dynamic_list(arg, cmdline, &this->dynamic_list_))
     gold::gold_fatal(_("unable to parse dynamic-list script file %s"), arg);
+  this->have_dynamic_list_ = true;
 }
 
 void
@@ -918,6 +919,7 @@ General_options::General_options()
     do_demangle_(false),
     plugins_(NULL),
     dynamic_list_(),
+    have_dynamic_list_(false),
     incremental_mode_(INCREMENTAL_OFF),
     incremental_disposition_(INCREMENTAL_STARTUP),
     incremental_startup_disposition_(INCREMENTAL_CHECK),
@@ -1199,6 +1201,13 @@ General_options::finalize()
   // in the path, as appropriate.
   this->add_sysroot();
 
+  // --dynamic-list overrides -Bsymbolic and -Bsymbolic-functions.
+  if (this->have_dynamic_list())
+    {
+      this->set_Bsymbolic(false);
+      this->set_Bsymbolic_functions(false);
+    }
+
   // Now that we've normalized the options, check for contradictory ones.
   if (this->shared() && this->is_static())
     gold_fatal(_("-shared and -static are incompatible"));
index a2f5a8864e3399f15f374ac512c1b6e842ec384b..da1ade9ca17bc86a5acf3f364998f6a438907659 100644 (file)
@@ -1438,6 +1438,11 @@ class General_options
   in_dynamic_list(const char* symbol) const
   { return this->dynamic_list_.version_script_info()->symbol_is_local(symbol); }
 
+  // True if a --dynamic-list script was provided.
+  bool
+  have_dynamic_list() const
+  { return this->have_dynamic_list_; }
+
   // Finalize the dynamic list.
   void
   finalize_dynamic_list()
@@ -1591,6 +1596,8 @@ class General_options
   // script.cc, we store this as a Script_options object, even though
   // we only use a single Version_tree from it.
   Script_options dynamic_list_;
+  // Whether a --dynamic-list file was provided.
+  bool have_dynamic_list_;
   // The incremental linking mode.
   Incremental_mode incremental_mode_;
   // The disposition given by the --incremental-changed,
index 2e17529b455cee8c8a06df1aba1a3f7cf7696e3d..225856a1938f85476ac88200a3ba25c368ed94d2 100644 (file)
@@ -1258,7 +1258,8 @@ Symbol_table::add_from_relobj(
          && res->is_externally_visible()
          && !res->is_from_dynobj()
           && (parameters->options().shared()
-             || parameters->options().export_dynamic()))
+             || parameters->options().export_dynamic()
+             || parameters->options().in_dynamic_list(res->name())))
         this->gc_mark_symbol(res);
 
       if (is_defined_in_discarded_section)
index 1232c97747ef6d92f52524405bdc698ccc431d2a..9aff274cb3f7885175b826520c939b6bbd90eb79 100644 (file)
@@ -576,8 +576,14 @@ class Symbol
     if (!parameters->options().shared())
       return false;
 
-    // If the user used -Bsymbolic, then nothing is preemptible.
-    if (parameters->options().Bsymbolic())
+    // If the symbol was named in a --dynamic-list script, it is preemptible.
+    if (parameters->options().in_dynamic_list(this->name()))
+      return true;
+
+    // If the user used -Bsymbolic or provided a --dynamic-list script,
+    // then nothing (else) is preemptible.
+    if (parameters->options().Bsymbolic()
+        || parameters->options().have_dynamic_list())
       return false;
 
     // If the user used -Bsymbolic-functions, then functions are not
index aca9df8469557617ced3d28cf3ac40b099ef4fa7..0b22c1378b7309a8b19aa045d01bd9c59023f49e 100644 (file)
@@ -203,6 +203,16 @@ pr14265: pr14265.o
 pr14265.stdout: pr14265
        $(TEST_NM) --format=bsd --numeric-sort $< > $@
 
+check_SCRIPTS += gc_dynamic_list_test.sh
+check_DATA += gc_dynamic_list_test.stdout
+MOSTLYCLEANFILES += gc_dynamic_list_test
+gc_dynamic_list_test.o: gc_dynamic_list_test.c
+       $(COMPILE) -c -ffunction-sections -o $@ $<
+gc_dynamic_list_test: gc_dynamic_list_test.o gcctestdir/ld $(srcdir)/gc_dynamic_list_test.t
+       $(LINK) -Bgcctestdir/ -Wl,--gc-sections -Wl,--dynamic-list,$(srcdir)/gc_dynamic_list_test.t gc_dynamic_list_test.o
+gc_dynamic_list_test.stdout: gc_dynamic_list_test
+       $(TEST_NM) gc_dynamic_list_test > $@
+
 check_SCRIPTS += icf_test.sh
 check_DATA += icf_test.map
 MOSTLYCLEANFILES += icf_test icf_test.map
@@ -1465,6 +1475,22 @@ dynamic_list: basic_test.o gcctestdir/ld $(srcdir)/dynamic_list.t
 dynamic_list.stdout: dynamic_list
        $(TEST_READELF) -W --dyn-syms dynamic_list > dynamic_list.stdout
 
+check_PROGRAMS += dynamic_list_2
+dynamic_list_2_SOURCES = dynamic_list_2.cc
+dynamic_list_2_DEPENDENCIES = gcctestdir/ld dynamic_list_lib1.so dynamic_list_lib2.so
+dynamic_list_2_LDFLAGS = -Bgcctestdir/ -L. -Wl,-R,. -Wl,--no-as-needed
+dynamic_list_2_LDADD = dynamic_list_lib1.so dynamic_list_lib2.so
+
+dynamic_list_lib1.so: gcctestdir/ld dynamic_list_lib1.o
+       $(CXXLINK) -Bgcctestdir/ -shared dynamic_list_lib1.o
+dynamic_list_lib1.o: dynamic_list_lib1.cc
+       $(CXXCOMPILE) -c -fpic -o $@ $<
+
+dynamic_list_lib2.so: gcctestdir/ld dynamic_list_lib2.o $(srcdir)/dynamic_list_2.t
+       $(CXXLINK) -Bgcctestdir/ -shared -Wl,--dynamic-list,$(srcdir)/dynamic_list_2.t dynamic_list_lib2.o
+dynamic_list_lib2.o: dynamic_list_lib2.cc
+       $(CXXCOMPILE) -c -fpic -o $@ $<
+
 check_PROGRAMS += thin_archive_test_1
 MOSTLYCLEANFILES += libthin1.a libthin3.a libthinall.a \
        alt/thin_archive_test_2.o alt/thin_archive_test_4.o \
index b86bea930b021bfc041c1ebc542b52fa3d5e0e6b..6a9228f1e07bd61aeea619490a8a05b96d2078e0 100644 (file)
@@ -78,7 +78,9 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_2 = incremental_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_comdat_test.sh gc_tls_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ pr14265.sh icf_test.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ pr14265.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_dynamic_list_test.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test.sh \
@@ -109,7 +111,9 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_comdat_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_tls_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test.stdout \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ pr14265.stdout icf_test.map \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ pr14265.stdout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_dynamic_list_test.stdout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test.map \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test_1.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test_2.stdout \
@@ -132,7 +136,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test.cmdline \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_comdat_test gc_tls_test \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test pr14265 \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test icf_test.map \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_dynamic_list_test icf_test \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test.map \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test icf_safe_test.map \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test \
@@ -318,6 +323,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_3 \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ tls_phdrs_script_test \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ tls_script_test script_test_11 \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list_2 \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ thin_archive_test_1 \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ thin_archive_test_2
 @GCC_FALSE@script_test_1_DEPENDENCIES =
@@ -823,6 +829,7 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest_a_OBJECTS)
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ tls_phdrs_script_test$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ tls_script_test$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_11$(EXEEXT) \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list_2$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ thin_archive_test_1$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ thin_archive_test_2$(EXEEXT)
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__EXEEXT_23 = plugin_test_1$(EXEEXT) \
@@ -967,6 +974,11 @@ discard_locals_test_DEPENDENCIES = libgoldtest.a ../libgold.a \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 discard_locals_test_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(discard_locals_test_LDFLAGS) $(LDFLAGS) -o $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@am_dynamic_list_2_OBJECTS =  \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list_2.$(OBJEXT)
+dynamic_list_2_OBJECTS = $(am_dynamic_list_2_OBJECTS)
+dynamic_list_2_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
+       $(dynamic_list_2_LDFLAGS) $(LDFLAGS) -o $@
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am_exception_same_shared_test_OBJECTS =  \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ exception_test_main.$(OBJEXT)
 exception_same_shared_test_OBJECTS =  \
@@ -1773,6 +1785,7 @@ SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c basic_pie_test.c \
        $(common_test_1_SOURCES) $(common_test_2_SOURCES) \
        $(constructor_static_test_SOURCES) $(constructor_test_SOURCES) \
        $(copy_test_SOURCES) $(discard_locals_test_SOURCES) \
+       $(dynamic_list_2_SOURCES) \
        $(exception_same_shared_test_SOURCES) \
        $(exception_separate_shared_12_test_SOURCES) \
        $(exception_separate_shared_21_test_SOURCES) \
@@ -2516,6 +2529,10 @@ LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@tls_script_test_DEPENDENCIES = $(tls_test_DEPENDENCIES) $(srcdir)/script_test_4.t
 @GCC_TRUE@@NATIVE_LINKER_TRUE@tls_script_test_LDFLAGS = $(tls_test_LDFLAGS) -Wl,-T,$(srcdir)/script_test_4.t
 @GCC_TRUE@@NATIVE_LINKER_TRUE@tls_script_test_LDADD = $(tls_test_LDADD)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@dynamic_list_2_SOURCES = dynamic_list_2.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@dynamic_list_2_DEPENDENCIES = gcctestdir/ld dynamic_list_lib1.so dynamic_list_lib2.so
+@GCC_TRUE@@NATIVE_LINKER_TRUE@dynamic_list_2_LDFLAGS = -Bgcctestdir/ -L. -Wl,-R,. -Wl,--no-as-needed
+@GCC_TRUE@@NATIVE_LINKER_TRUE@dynamic_list_2_LDADD = dynamic_list_lib1.so dynamic_list_lib2.so
 @GCC_TRUE@@NATIVE_LINKER_TRUE@thin_archive_test_1_SOURCES = thin_archive_main.cc
 @GCC_TRUE@@NATIVE_LINKER_TRUE@thin_archive_test_1_DEPENDENCIES = gcctestdir/ld libthin1.a alt/libthin2.a
 @GCC_TRUE@@NATIVE_LINKER_TRUE@thin_archive_test_1_LDFLAGS = -Bgcctestdir/ -Lalt
@@ -2711,6 +2728,9 @@ copy_test$(EXEEXT): $(copy_test_OBJECTS) $(copy_test_DEPENDENCIES)
 discard_locals_test$(EXEEXT): $(discard_locals_test_OBJECTS) $(discard_locals_test_DEPENDENCIES) 
        @rm -f discard_locals_test$(EXEEXT)
        $(discard_locals_test_LINK) $(discard_locals_test_OBJECTS) $(discard_locals_test_LDADD) $(LIBS)
+dynamic_list_2$(EXEEXT): $(dynamic_list_2_OBJECTS) $(dynamic_list_2_DEPENDENCIES) 
+       @rm -f dynamic_list_2$(EXEEXT)
+       $(dynamic_list_2_LINK) $(dynamic_list_2_OBJECTS) $(dynamic_list_2_LDADD) $(LIBS)
 exception_same_shared_test$(EXEEXT): $(exception_same_shared_test_OBJECTS) $(exception_same_shared_test_DEPENDENCIES) 
        @rm -f exception_same_shared_test$(EXEEXT)
        $(exception_same_shared_test_LINK) $(exception_same_shared_test_OBJECTS) $(exception_same_shared_test_LDADD) $(LIBS)
@@ -3449,6 +3469,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constructor_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copy_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/discard_locals_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynamic_list_2.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exception_test_1.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exception_test_2.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exception_test_main.Po@am__quote@
@@ -3808,6 +3829,8 @@ gc_orphan_section_test.sh.log: gc_orphan_section_test.sh
        @p='gc_orphan_section_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 pr14265.sh.log: pr14265.sh
        @p='pr14265.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+gc_dynamic_list_test.sh.log: gc_dynamic_list_test.sh
+       @p='gc_dynamic_list_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 icf_test.sh.log: icf_test.sh
        @p='icf_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 icf_keep_unique_test.sh.log: icf_keep_unique_test.sh
@@ -4134,6 +4157,8 @@ tls_script_test.log: tls_script_test$(EXEEXT)
        @p='tls_script_test$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 script_test_11.log: script_test_11$(EXEEXT)
        @p='script_test_11$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+dynamic_list_2.log: dynamic_list_2$(EXEEXT)
+       @p='dynamic_list_2$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 thin_archive_test_1.log: thin_archive_test_1$(EXEEXT)
        @p='thin_archive_test_1$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 thin_archive_test_2.log: thin_archive_test_2$(EXEEXT)
@@ -4451,6 +4476,12 @@ uninstall-am:
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(LINK) -Bgcctestdir/ -Wl,--gc-sections -Wl,-T,$(srcdir)/pr14265.t -o $@ $<
 @GCC_TRUE@@NATIVE_LINKER_TRUE@pr14265.stdout: pr14265
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) --format=bsd --numeric-sort $< > $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_dynamic_list_test.o: gc_dynamic_list_test.c
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(COMPILE) -c -ffunction-sections -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_dynamic_list_test: gc_dynamic_list_test.o gcctestdir/ld $(srcdir)/gc_dynamic_list_test.t
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(LINK) -Bgcctestdir/ -Wl,--gc-sections -Wl,--dynamic-list,$(srcdir)/gc_dynamic_list_test.t gc_dynamic_list_test.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_dynamic_list_test.stdout: gc_dynamic_list_test
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) gc_dynamic_list_test > $@
 @GCC_TRUE@@NATIVE_LINKER_TRUE@icf_test.o: icf_test.cc
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $<
 @GCC_TRUE@@NATIVE_LINKER_TRUE@icf_test: icf_test.o gcctestdir/ld
@@ -4980,6 +5011,16 @@ uninstall-am:
 @GCC_TRUE@@NATIVE_LINKER_TRUE@dynamic_list.stdout: dynamic_list
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -W --dyn-syms dynamic_list > dynamic_list.stdout
 
+@GCC_TRUE@@NATIVE_LINKER_TRUE@dynamic_list_lib1.so: gcctestdir/ld dynamic_list_lib1.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared dynamic_list_lib1.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@dynamic_list_lib1.o: dynamic_list_lib1.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -c -fpic -o $@ $<
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@dynamic_list_lib2.so: gcctestdir/ld dynamic_list_lib2.o $(srcdir)/dynamic_list_2.t
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared -Wl,--dynamic-list,$(srcdir)/dynamic_list_2.t dynamic_list_lib2.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@dynamic_list_lib2.o: dynamic_list_lib2.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -c -fpic -o $@ $<
+
 @GCC_TRUE@@NATIVE_LINKER_TRUE@libthin1.a: thin_archive_test_1.o alt/thin_archive_test_2.o
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ rm -f $@
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AR) crT $@ $^
diff --git a/gold/testsuite/dynamic_list_2.cc b/gold/testsuite/dynamic_list_2.cc
new file mode 100644 (file)
index 0000000..34194b8
--- /dev/null
@@ -0,0 +1,40 @@
+// dynamic_list_test_2.cc -- Test --dynamic-list with shared libraries.
+
+// Copyright 2014 Free Software Foundation, Inc.
+// Written by Cary Coutant <ccoutant@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// The goal of this program is to verify that the --dynamic-list option
+// allows overrides for symbols listed in the file, and does symbolic
+// binding for symbols not listed.
+
+#include <cstring>
+
+extern const char* test_foo();
+extern const char* test_bar();
+
+int
+main(void)
+{
+  if (strcmp(test_foo(), "override") != 0)
+    return 1;
+  if (strcmp(test_bar(), "original") != 0)
+    return 2;
+  return 0;
+}
diff --git a/gold/testsuite/dynamic_list_2.t b/gold/testsuite/dynamic_list_2.t
new file mode 100644 (file)
index 0000000..a4e4381
--- /dev/null
@@ -0,0 +1,27 @@
+/* dynamic_list_2.t -- script file for building dynamic_list_lib2.so.
+
+   Copyright 2014 Free Software Foundation, Inc.
+   Written by Cary Coutant <ccoutant@google.com>.
+
+   This file is part of gold.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+{
+    extern "C" {
+        "foo";
+    };
+};
diff --git a/gold/testsuite/dynamic_list_lib1.cc b/gold/testsuite/dynamic_list_lib1.cc
new file mode 100644 (file)
index 0000000..9bc0717
--- /dev/null
@@ -0,0 +1,37 @@
+// dynamic_list_test_lib1.cc -- Test --dynamic-list with shared libraries.
+
+// Copyright 2014 Free Software Foundation, Inc.
+// Written by Cary Coutant <ccoutant@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// The goal of this program is to verify that the --dynamic-list option
+// allows overrides for symbols listed in the file, and does symbolic
+// binding for symbols not listed.
+
+extern "C" const char*
+foo()
+{
+    return "override";
+}
+
+extern "C" const char*
+bar()
+{
+    return "override";
+}
diff --git a/gold/testsuite/dynamic_list_lib2.cc b/gold/testsuite/dynamic_list_lib2.cc
new file mode 100644 (file)
index 0000000..2532a42
--- /dev/null
@@ -0,0 +1,49 @@
+// dynamic_list_test_lib2.cc -- Test --dynamic-list with shared libraries.
+
+// Copyright 2014 Free Software Foundation, Inc.
+// Written by Cary Coutant <ccoutant@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// The goal of this program is to verify that the --dynamic-list option
+// allows overrides for symbols listed in the file, and does symbolic
+// binding for symbols not listed.
+
+extern "C" const char*
+foo()
+{
+  return "original";
+}
+
+const char*
+test_foo()
+{
+  return foo();
+}
+
+extern "C" const char*
+bar()
+{
+  return "original";
+}
+
+const char*
+test_bar()
+{
+  return bar();
+}
diff --git a/gold/testsuite/gc_dynamic_list_test.c b/gold/testsuite/gc_dynamic_list_test.c
new file mode 100644 (file)
index 0000000..3b84e98
--- /dev/null
@@ -0,0 +1,34 @@
+// gc_dynamic_list_test.cc -- Check that --gc-sections honors --dynamic-list.
+
+// Copyright 2014 Free Software Foundation, Inc.
+// Written by Cary Coutant <ccoutant@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// The goal of this program is to verify that the symbol "keep" is not
+// garbage-collected when it is named in a --dynamic-list script.
+
+extern void keep(void);
+
+void
+keep(void)
+{}
+
+int
+main(void)
+{ return 0; }
diff --git a/gold/testsuite/gc_dynamic_list_test.sh b/gold/testsuite/gc_dynamic_list_test.sh
new file mode 100755 (executable)
index 0000000..b1723dd
--- /dev/null
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# gc_comdat_test.sh -- test --gc-sections
+
+# Copyright 2014 Free Software Foundation, Inc.
+# Written by Cary Coutant <ccoutant@google.com>.
+
+# This file is part of gold.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# The goal of this program is to verify if comdat's and garbage 
+# collection work together.  Files gc_comdat_test_1.cc and 
+# gc_comdat_test_2.cc are used in this test.  This program checks
+# if the kept comdat section is garbage collected.
+
+check()
+{
+    if ! grep -q "$2" "$1"
+    then
+        echo "Garbage collection should not have collected '$2'"
+       exit 1
+    fi
+}
+
+check gc_dynamic_list_test.stdout "keep"
diff --git a/gold/testsuite/gc_dynamic_list_test.t b/gold/testsuite/gc_dynamic_list_test.t
new file mode 100644 (file)
index 0000000..8905541
--- /dev/null
@@ -0,0 +1,25 @@
+/* gc_dynamic_list_test.t -- script file for gc_dynamic_list_test.cc
+
+   Copyright 2014 Free Software Foundation, Inc.
+   Written by Cary Coutant <ccoutant@google.com>.
+
+   This file is part of gold.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+{
+  keep;
+};