* object.cc (Sized_relobj::do_count): Test should_retain_symbol map.
authorCraig Silverstein <csilvers@google.com>
Fri, 18 Sep 2009 20:03:22 +0000 (20:03 +0000)
committerCraig Silverstein <csilvers@google.com>
Fri, 18 Sep 2009 20:03:22 +0000 (20:03 +0000)
* options.cc: Include <cerrno> and <fstream>.
(General_options::finalize): Parse -retain-symbols-file tag.
* options.h: New flag.
(General_options): New method should_retain_symbol, new
variable symbols_to_retain.
* symtab.cc (Symbol_table::sized_finalize_symbol): Test
should_retain_symbol map.
* testsuite/Makefile.am (retain_symbols_file_test): New test.
* testsuite/Makefile.in: Regenerate.
* testsuite/retain_symbols_file_test.sh: New file.

gold/ChangeLog
gold/object.cc
gold/options.cc
gold/options.h
gold/symtab.cc
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/retain_symbols_file_test.sh [new file with mode: 0755]

index da15cc62bf1c7959809968cbb8436d4453fd0f2b..b80990d1729fe0eba2cf3b345d6119a436ce98c7 100644 (file)
@@ -1,3 +1,17 @@
+2009-09-18  Craig Silverstein  <csilvers@google.com>
+
+       * object.cc (Sized_relobj::do_count): Test should_retain_symbol map.
+       * options.cc: Include <cerrno> and <fstream>.
+       (General_options::finalize): Parse -retain-symbols-file tag.
+       * options.h: New flag.
+       (General_options): New method should_retain_symbol, new
+       variable symbols_to_retain.
+       * symtab.cc (Symbol_table::sized_finalize_symbol): Test
+       should_retain_symbol map.
+       * testsuite/Makefile.am (retain_symbols_file_test): New test.
+       * testsuite/Makefile.in: Regenerate.
+       * testsuite/retain_symbols_file_test.sh: New file.
+
 2009-09-18  Nick Clifton  <nickc@redhat.com>
 
        * po/es.po: Updated Spanish translation.
        (Target_arm::Relocatable_size_for_reloc::get_size_for_reloc):
        Likewise.
 
-2009-09-08  Cary Coutant  <ccoutant@google.com>
+2009-09-16  Cary Coutant  <ccoutant@google.com>
 
        * testsuite/Makefile.am (MOSTLYCLEANFILES): Add more generated files.
        * testsuite/Makefile.in: Regenerate.
index be6294c31fd579a07c21d6cb5c40da8c45fe63ac..125628401d6ea62675a1b38741f3c7527648a605 100644 (file)
@@ -1562,6 +1562,14 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool,
          continue;
        }
 
+      // Discard the local symbol if -retain_symbols_file is specified
+      // and the local symbol is not in that file.
+      if (!parameters->options().should_retain_symbol(name))
+        {
+          lv.set_no_output_symtab_entry();
+          continue;
+        }
+
       // Add the symbol to the symbol table string pool.
       pool->add(name, true, NULL);
       ++count;
index bf420c679fdef01dec75f757659984ed5316ffb7..bf3eb55574bfbd19ef061f70268481f73ea423c7 100644 (file)
 
 #include "gold.h"
 
+#include <cerrno>
 #include <cstdlib>
 #include <cstring>
+#include <fstream>
 #include <vector>
 #include <iostream>
 #include <sys/stat.h>
@@ -938,6 +940,25 @@ General_options::finalize()
       this->add_to_library_path_with_sysroot("/usr/lib");
     }
 
+  // Parse the contents of -retain-symbols-file into a set.
+  if (this->retain_symbols_file())
+    {
+      std::ifstream in;
+      in.open(this->retain_symbols_file());
+      if (!in)
+        gold_fatal(_("unable to open -retain-symbols-file file %s: %s"),
+                   this->retain_symbols_file(), strerror(errno));
+      std::string line;
+      std::getline(in, line);   // this chops off the trailing \n, if any
+      while (in)
+        {
+          if (!line.empty() && line[line.length() - 1] == '\r')   // Windows
+            line.resize(line.length() - 1);
+          this->symbols_to_retain_.insert(line);
+          std::getline(in, line);
+        }
+    }
+
   if (this->shared() && !this->user_set_allow_shlib_undefined())
     this->set_allow_shlib_undefined(true);
 
@@ -952,6 +973,10 @@ General_options::finalize()
   if (this->shared() && this->relocatable())
     gold_fatal(_("-shared and -r are incompatible"));
 
+  // TODO: implement support for -retain-symbols-file with -r, if needed.
+  if (this->relocatable() && this->retain_symbols_file())
+    gold_fatal(_("-retain-symbols-file does not yet work with -r"));
+
   if (this->oformat_enum() != General_options::OBJECT_FORMAT_ELF
       && (this->shared() || this->relocatable()))
     gold_fatal(_("binary output format not compatible with -shared or -r"));
index 3f145293df2f9bbd05e112f25957dfe33a98eee3..258d62813983418850339fe0314b1733f36bcec7 100644 (file)
@@ -774,6 +774,9 @@ class General_options
   DEFINE_bool(relax, options::TWO_DASHES, '\0', false,
              N_("Relax branches on certain targets"), NULL);
 
+  DEFINE_string(retain_symbols_file, options::EXACTLY_ONE_DASH, '\0', NULL,
+                N_("keep only symbols listed in this file"), N_("[file]"));
+
   // -R really means -rpath, but can mean --just-symbols for
   // compatibility with GNU ld.  -rpath is always -rpath, so we list
   // it separately.
@@ -1021,6 +1024,15 @@ class General_options
   bool
   is_in_system_directory(const std::string& name) const;
 
+  // RETURN whether SYMBOL_NAME should be kept, according to symbols_to_retain_.
+  bool
+  should_retain_symbol(const char* symbol_name) const
+    {
+      if (symbols_to_retain_.empty())    // means flag wasn't specified
+        return true;
+      return symbols_to_retain_.find(symbol_name) != symbols_to_retain_.end();
+    }
+
   // These are the best way to get access to the execstack state,
   // not execstack() and noexecstack() which are hard to use properly.
   bool
@@ -1132,8 +1144,10 @@ class General_options
   // build (--incremental-changed, --incremental-unchanged or
   // --incremental-unknown)
   bool implicit_incremental_;
-  // Libraries excluded from automatic export via --exclude-libs
+  // Libraries excluded from automatic export, via --exclude-libs.
   Unordered_set<std::string> excluded_libs_;
+  // List of symbol-names to keep, via -retain-symbol-info.
+  Unordered_set<std::string> symbols_to_retain_;
 };
 
 // The position-dependent options.  We use this to store the state of
index 292a26275dec2b3e224fe778019b2bbf256d678a..d5f699bf942e76cc16152656a0ce1d60e106ca1c 100644 (file)
@@ -2521,7 +2521,8 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
 
   sym->set_value(value);
 
-  if (parameters->options().strip_all())
+  if (parameters->options().strip_all()
+      || !parameters->options().should_retain_symbol(sym->name()))
     {
       sym->set_symtab_index(-1U);
       return false;
index af16f901b89f327ab4efb953378733e061952451..25740b83289a9d3889994c981b253139b509ac0d 100644 (file)
@@ -1153,6 +1153,23 @@ hidden_test: hidden_test_main.o libhidden.so gcctestdir/ld
 hidden_test.err: hidden_test
        @touch hidden_test.err
 
+# Test -retain-symbols-file.
+check_SCRIPTS += retain_symbols_file_test.sh
+check_DATA += retain_symbols_file_test.stdout
+MOSTLYCLEANFILES += retain_symbols_file_test retain_symbols_file_test.in \
+                    retain_symbols_file_test.stdout
+retain_symbols_file_test.so: basic_pic_test.o gcctestdir/ld
+       echo 'main' > retain_symbols_file_test.in
+       echo 't1' >> retain_symbols_file_test.in
+       echo '_ZN4t16bC1Ev' >> retain_symbols_file_test.in
+       echo '_ZNK4t20a3getEv' >> retain_symbols_file_test.in
+       echo '_Z3t18v' >> retain_symbols_file_test.in
+       echo '__tcf_0' >> retain_symbols_file_test.in   
+       $(CXXLINK) -Bgcctestdir/ -shared -Wl,-retain-symbols-file,retain_symbols_file_test.in basic_pic_test.o
+retain_symbols_file_test.stdout: retain_symbols_file_test.so
+       $(TEST_NM) -C retain_symbols_file_test.so > $@
+
+
 # Test that if the output file already exists and is empty,
 # it will get execute permission.
 check_PROGRAMS += permission_test
index 13cb340c206ac2218affcfa2337529e85bc25b0e..36334ef0c1e08aa5e521b6de1afa256a8e7aff10 100644 (file)
@@ -341,18 +341,25 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
 
 # Test that hidden and internal symbols in the main program cannot be
 # referenced by a shared library.
+
+# Test -retain-symbols-file.
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_27 = exclude_libs_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_test.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ hidden_test.sh
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ hidden_test.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ retain_symbols_file_test.sh
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_28 = exclude_libs_test.syms \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_test.syms \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ hidden_test.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ hidden_test.err \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ retain_symbols_file_test.stdout
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_29 = exclude_libs_test.syms \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ libexclude_libs_test_1.a \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ libexclude_libs_test_2.a \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/libexclude_libs_test_3.a \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_test.syms \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ hidden_test hidden_test.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ hidden_test hidden_test.err \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ retain_symbols_file_test \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ retain_symbols_file_test.in \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ retain_symbols_file_test.stdout
 @GCC_TRUE@@MCMODEL_MEDIUM_TRUE@@NATIVE_LINKER_TRUE@am__append_30 = large
 @GCC_FALSE@large_DEPENDENCIES = libgoldtest.a ../libgold.a \
 @GCC_FALSE@    ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
@@ -2956,6 +2963,16 @@ uninstall-am:
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(LINK) -Bgcctestdir/ -Wl,-R,. hidden_test_main.o libhidden.so 2>hidden_test.err
 @GCC_TRUE@@NATIVE_LINKER_TRUE@hidden_test.err: hidden_test
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ @touch hidden_test.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@retain_symbols_file_test.so: basic_pic_test.o gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo 'main' > retain_symbols_file_test.in
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo 't1' >> retain_symbols_file_test.in
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo '_ZN4t16bC1Ev' >> retain_symbols_file_test.in
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo '_ZNK4t20a3getEv' >> retain_symbols_file_test.in
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo '_Z3t18v' >> retain_symbols_file_test.in
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo '__tcf_0' >> retain_symbols_file_test.in   
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared -Wl,-retain-symbols-file,retain_symbols_file_test.in basic_pic_test.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@retain_symbols_file_test.stdout: retain_symbols_file_test.so
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) -C retain_symbols_file_test.so > $@
 @GCC_TRUE@@NATIVE_LINKER_TRUE@permission_test: basic_test.o gcctestdir/ld
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ umask 022; \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ rm -f $@; \
diff --git a/gold/testsuite/retain_symbols_file_test.sh b/gold/testsuite/retain_symbols_file_test.sh
new file mode 100755 (executable)
index 0000000..ba0afd6
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+# retain_symbols_file_test.sh -- a test case for -retain-symbols-file
+
+# Copyright 2009 Free Software Foundation, Inc.
+# Written by Craig Silverstein <csilvers@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 Makefile tries linking simple_test.o with -retain-symbols-file.
+# It then runs nm over the results.  We check that the output is right.
+
+check_present()
+{
+    if ! grep -q "$1" retain_symbols_file_test.out
+    then
+        echo "Did not find expected symbol $1 in retain_symbols_file_test.out"
+        exit 1
+    fi
+}
+
+check_absent()
+{
+    if grep -q "$1" retain_symbols_file_test.out
+    then
+        echo "Found unexpected symbol $1 in retain_symbols_file_test.out"
+        exit 1
+    fi
+}
+
+check_present 't1'
+check_present 't16b::t16b()'
+check_present 't20a::get()'
+check_present 't18()'
+check_present '__tcf_0'
+check_absent 't10'
+check_absent 't1()'
+check_absent 't16b::t()'
+
+exit 0