diff options
author | Ian Lance Taylor <ian@airs.com> | 2009-02-27 19:57:46 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2009-02-27 19:57:46 +0000 |
commit | 0602e05a845a545a8b52386a4dec66b74a158bc7 (patch) | |
tree | 538c81672e2f97885ce7f8054e6726f0189ad79b /gold/resolve.cc | |
parent | b5096abe11166944e2de1bb8a27a1c36d02a63ef (diff) | |
download | gdb-0602e05a845a545a8b52386a4dec66b74a158bc7.zip gdb-0602e05a845a545a8b52386a4dec66b74a158bc7.tar.gz 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.
Diffstat (limited to 'gold/resolve.cc')
-rw-r--r-- | gold/resolve.cc | 36 |
1 files changed, 32 insertions, 4 deletions
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); } |