aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2009-02-27 19:57:46 +0000
committerIan Lance Taylor <ian@airs.com>2009-02-27 19:57:46 +0000
commit0602e05a845a545a8b52386a4dec66b74a158bc7 (patch)
tree538c81672e2f97885ce7f8054e6726f0189ad79b
parentb5096abe11166944e2de1bb8a27a1c36d02a63ef (diff)
downloadfsf-binutils-gdb-0602e05a845a545a8b52386a4dec66b74a158bc7.zip
fsf-binutils-gdb-0602e05a845a545a8b52386a4dec66b74a158bc7.tar.gz
fsf-binutils-gdb-0602e05a845a545a8b52386a4dec66b74a158bc7.tar.bz2
PR 9836
* symtab.cc (Symbol_table::add_from_object): If the visibility is hidden or internal, force the symbol to be local. * resolve.cc (Symbol::override_visibility): Define. (Symbol::override_base): Use override_visibility. (Symbol_table::resolve): Likewise. (Symbol::override_base_with_special): Likewise. (Symbol_table::override_with_special): If the visibility is hidden or internal, force the symbol to be local. * symtab.h (class Symbol): Add set_visibility and override_visibility. * testsuite/ver_test_1.sh: New file. * testsuite/Makefile.am (check_SCRIPTS): Add ver_test_1.sh. (check_DATA): Add ver_test_1.syms. (ver_test_1.syms): New target. * testsuite/Makefile.in: Rebuild.
-rw-r--r--gold/ChangeLog19
-rw-r--r--gold/resolve.cc36
-rw-r--r--gold/symtab.cc14
-rw-r--r--gold/symtab.h14
-rw-r--r--gold/testsuite/Makefile.am5
-rw-r--r--gold/testsuite/Makefile.in16
-rwxr-xr-xgold/testsuite/ver_test_1.sh30
7 files changed, 120 insertions, 14 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 8630e50..5159255 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,22 @@
+2009-02-27 Ian Lance Taylor <iant@google.com>
+
+ PR 9836
+ * symtab.cc (Symbol_table::add_from_object): If the visibility is
+ hidden or internal, force the symbol to be local.
+ * resolve.cc (Symbol::override_visibility): Define.
+ (Symbol::override_base): Use override_visibility.
+ (Symbol_table::resolve): Likewise.
+ (Symbol::override_base_with_special): Likewise.
+ (Symbol_table::override_with_special): If the visibility is hidden
+ or internal, force the symbol to be local.
+ * symtab.h (class Symbol): Add set_visibility and
+ override_visibility.
+ * testsuite/ver_test_1.sh: New file.
+ * testsuite/Makefile.am (check_SCRIPTS): Add ver_test_1.sh.
+ (check_DATA): Add ver_test_1.syms.
+ (ver_test_1.syms): New target.
+ * testsuite/Makefile.in: Rebuild.
+
2009-02-25 Cary Coutant <ccoutant@google.com>
* layout.cc (Layout::choose_output_section): Don't rename sections
diff --git a/gold/resolve.cc b/gold/resolve.cc
index 17544f8..bd327e8 100644
--- a/gold/resolve.cc
+++ b/gold/resolve.cc
@@ -1,6 +1,6 @@
// resolve.cc -- symbol resolution for gold
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
@@ -63,6 +63,26 @@ Symbol::override_version(const char* version)
}
}
+// This symbol is being overidden by another symbol whose visibility
+// is VISIBILITY. Updated the VISIBILITY_ field accordingly.
+
+inline void
+Symbol::override_visibility(elfcpp::STV visibility)
+{
+ // The rule for combining visibility is that we always choose the
+ // most constrained visibility. In order of increasing constraint,
+ // visibility goes PROTECTED, HIDDEN, INTERNAL. This is the reverse
+ // of the numeric values, so the effect is that we always want the
+ // smallest non-zero value.
+ if (visibility != elfcpp::STV_DEFAULT)
+ {
+ if (this->visibility_ == elfcpp::STV_DEFAULT)
+ this->visibility_ = visibility;
+ else if (this->visibility_ > visibility)
+ this->visibility_ = visibility;
+ }
+}
+
// Override the fields in Symbol.
template<int size, bool big_endian>
@@ -78,7 +98,7 @@ Symbol::override_base(const elfcpp::Sym<size, big_endian>& sym,
this->is_ordinary_shndx_ = is_ordinary;
this->type_ = sym.get_st_type();
this->binding_ = sym.get_st_bind();
- this->visibility_ = sym.get_st_visibility();
+ this->override_visibility(sym.get_st_visibility());
this->nonvis_ = sym.get_st_nonvis();
if (object->is_dynamic())
this->in_dyn_ = true;
@@ -279,6 +299,9 @@ Symbol_table::resolve(Sized_symbol<size>* to,
{
if (adjust_common_sizes && sym.get_st_size() > to->symsize())
to->set_symsize(sym.get_st_size());
+ // The ELF ABI says that even for a reference to a symbol we
+ // merge the visibility.
+ to->override_visibility(sym.get_st_visibility());
}
// A new weak undefined reference, merging with an old weak
@@ -721,7 +744,7 @@ Symbol::override_base_with_special(const Symbol* from)
this->override_version(from->version_);
this->type_ = from->type_;
this->binding_ = from->binding_;
- this->visibility_ = from->visibility_;
+ this->override_visibility(from->visibility_);
this->nonvis_ = from->nonvis_;
// Special symbols are always considered to be regular symbols.
@@ -776,7 +799,12 @@ Symbol_table::override_with_special(Sized_symbol<size>* tosym,
}
while (ssym != tosym);
}
- if (tosym->binding() == elfcpp::STB_LOCAL)
+ if (tosym->binding() == elfcpp::STB_LOCAL
+ || ((tosym->visibility() == elfcpp::STV_HIDDEN
+ || tosym->visibility() == elfcpp::STV_INTERNAL)
+ && (tosym->binding() == elfcpp::STB_GLOBAL
+ || tosym->binding() == elfcpp::STB_WEAK)
+ && !parameters->options().relocatable()))
this->force_local(tosym);
}
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 5408385..dcbb46e 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -648,7 +648,8 @@ Symbol_table::resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from)
this->gc_mark_dyn_syms(to);
}
-// Record that a symbol is forced to be local by a version script.
+// Record that a symbol is forced to be local by a version script or
+// by visibility.
void
Symbol_table::force_local(Symbol* sym)
@@ -962,6 +963,15 @@ Symbol_table::add_from_object(Object* object,
this->tls_commons_.push_back(ret);
}
+ // If we're not doing a relocatable link, then any symbol with
+ // hidden or internal visibility is local.
+ if ((ret->visibility() == elfcpp::STV_HIDDEN
+ || ret->visibility() == elfcpp::STV_INTERNAL)
+ && (ret->binding() == elfcpp::STB_GLOBAL
+ || ret->binding() == elfcpp::STB_WEAK)
+ && !parameters->options().relocatable())
+ this->force_local(ret);
+
if (def)
ret->set_is_default();
return ret;
@@ -1179,7 +1189,7 @@ Symbol_table::add_from_pluginobj(
def, *sym, st_shndx, true, st_shndx);
if (local)
- this->force_local(res);
+ this->force_local(res);
return res;
}
diff --git a/gold/symtab.h b/gold/symtab.h
index 358dd32..b504d0a 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -1,6 +1,6 @@
// symtab.h -- the gold symbol table -*- C++ -*-
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
@@ -210,6 +210,15 @@ class Symbol
visibility() const
{ return this->visibility_; }
+ // Set the visibility.
+ void
+ set_visibility(elfcpp::STV visibility)
+ { this->visibility_ = visibility; }
+
+ // Override symbol visibility.
+ void
+ override_visibility(elfcpp::STV);
+
// Return the non-visibility part of the st_other field.
unsigned char
nonvis() const
@@ -1384,7 +1393,8 @@ class Symbol_table
void
resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from);
- // Record that a symbol is forced to be local by a version script.
+ // Record that a symbol is forced to be local by a version script or
+ // by visibility.
void
force_local(Symbol*);
diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
index 46c661f..1ba7c9d 100644
--- a/gold/testsuite/Makefile.am
+++ b/gold/testsuite/Makefile.am
@@ -742,6 +742,11 @@ ver_test_3.o: ver_test_3.cc
ver_test_4.o: ver_test_4.cc
$(CXXCOMPILE) -c -fpic -o $@ $<
+check_SCRIPTS += ver_test_1.sh
+check_DATA += ver_test_1.syms
+ver_test_1.syms: ver_test_1.so
+ $(TEST_READELF) -s $< >$@ 2>/dev/null
+
check_PROGRAMS += ver_test_2
ver_test_2_SOURCES = ver_test_main_2.cc
ver_test_2_DEPENDENCIES = gcctestdir/ld ver_test_4.so ver_test_2.so
diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
index 6703f6f..9f0cfcb 100644
--- a/gold/testsuite/Makefile.in
+++ b/gold/testsuite/Makefile.in
@@ -166,9 +166,10 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
# Test --dynamic-list, --dynamic-list-data, --dynamic-list-cpp-new,
# and --dynamic-list-cpp-typeinfo
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_6 = weak_plt.sh debug_msg.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ undef_symbol.sh ver_test_2.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_4.sh ver_test_5.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_7.sh ver_test_10.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ undef_symbol.sh ver_test_1.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_2.sh ver_test_4.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_5.sh ver_test_7.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_10.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_matching_test.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_3.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_4.sh \
@@ -183,9 +184,10 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_7 = weak_plt_shared.so \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg.err debug_msg_so.err \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg_ndebug.err \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ undef_symbol.err ver_test_2.syms \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_4.syms ver_test_5.syms \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_7.syms ver_test_10.syms \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ undef_symbol.err ver_test_1.syms \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_2.syms ver_test_4.syms \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_5.syms ver_test_7.syms \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_10.syms \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_matching_test.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_3.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_4.stdout \
@@ -2404,6 +2406,8 @@ uninstall-am: uninstall-info-am
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -c -fpic -o $@ $<
@GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_4.o: ver_test_4.cc
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -c -fpic -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_1.syms: ver_test_1.so
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -s $< >$@ 2>/dev/null
@GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_2.syms: ver_test_2
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -s $< >$@ 2>/dev/null
@GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_4.syms: ver_test_4.so
diff --git a/gold/testsuite/ver_test_1.sh b/gold/testsuite/ver_test_1.sh
new file mode 100755
index 0000000..edf7351
--- /dev/null
+++ b/gold/testsuite/ver_test_1.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# ver_test_1.sh -- check that protected symbols are local
+
+# Copyright 2009 Free Software Foundation, Inc.
+# Written by Ian Lance Taylor <iant@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.
+
+syms=`grep ' HIDDEN ' ver_test_1.syms | grep ' GLOBAL '`
+if test -n "$syms"; then
+ echo "Found GLOBAL HIDDEN symbols"
+ echo $syms
+ exit 1
+fi