From 4053c84c47273ce096e0ce45865418038a15e33c Mon Sep 17 00:00:00 2001 From: csilvers Date: Fri, 18 Sep 2009 20:02:21 +0000 Subject: [PATCH] * object.cc (Sized_relobj::do_count): Test should_retain_symbol map. * options.cc: Include and . (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/object.cc | 8 +++++ gold/options.cc | 25 ++++++++++++++ gold/options.h | 16 ++++++++- gold/symtab.cc | 3 +- gold/testsuite/Makefile.am | 17 +++++++++ gold/testsuite/Makefile.in | 23 +++++++++++-- gold/testsuite/retain_symbols_file_test.sh | 55 ++++++++++++++++++++++++++++++ 7 files changed, 142 insertions(+), 5 deletions(-) create mode 100755 gold/testsuite/retain_symbols_file_test.sh diff --git a/gold/object.cc b/gold/object.cc index be6294c31f..125628401d 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -1562,6 +1562,14 @@ Sized_relobj::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; diff --git a/gold/options.cc b/gold/options.cc index bf420c679f..bf3eb55574 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -22,8 +22,10 @@ #include "gold.h" +#include #include #include +#include #include #include #include @@ -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")); diff --git a/gold/options.h b/gold/options.h index 3f145293df..258d628139 100644 --- a/gold/options.h +++ b/gold/options.h @@ -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 excluded_libs_; + // List of symbol-names to keep, via -retain-symbol-info. + Unordered_set symbols_to_retain_; }; // The position-dependent options. We use this to store the state of diff --git a/gold/symtab.cc b/gold/symtab.cc index 292a26275d..d5f699bf94 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -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; diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index af16f901b8..25740b8328 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -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 diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 13cb340c20..36334ef0c1 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -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 index 0000000000..ba0afd6203 --- /dev/null +++ b/gold/testsuite/retain_symbols_file_test.sh @@ -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 . + +# 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 -- 2.11.0