PR 9836
authorIan Lance Taylor <ian@airs.com>
Fri, 27 Feb 2009 19:57:46 +0000 (19:57 +0000)
committerIan Lance Taylor <ian@airs.com>
Fri, 27 Feb 2009 19:57:46 +0000 (19:57 +0000)
* 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.

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

index 8630e5016bd63455b76e57ddc5d1bf56c4655fad..515925533124df2843d49b2bed2bc9023c3c8198 100644 (file)
@@ -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
index 17544f82a5c2d7b135d2970f18d4fb6894de7047..bd327e88a58466f8d8b53fdd0cbd470eae937640 100644 (file)
@@ -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);
 }
 
index 540838509253066e38688eec8881bb6814e8dd04..dcbb46e20dab25920c611a4a7898132846845fd3 100644 (file)
@@ -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;
 }
index 358dd32f7945a442e5dd61d1ae573be2bd833fce..b504d0a833a379017579964f8f7d5752e6054e7a 100644 (file)
@@ -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*);
 
index 46c661f05a8da20e8455185ac8e6ceae5ff2c0cd..1ba7c9dd393ec1e4893695dcbe2dc6db0e6209d9 100644 (file)
@@ -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
index 6703f6f66981ab08d65ba3f59f24f008c39e574a..9f0cfcbbfb01ecb8d310e9d3baed14f41f1f9c63 100644 (file)
@@ -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 (executable)
index 0000000..edf7351
--- /dev/null
@@ -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
This page took 0.035359 seconds and 4 git commands to generate.