diff options
-rw-r--r-- | gold/ChangeLog | 7 | ||||
-rw-r--r-- | gold/resolve.cc | 8 | ||||
-rw-r--r-- | gold/symtab.cc | 10 |
3 files changed, 16 insertions, 9 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index cd24883..49ce2fe 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,10 @@ +2015-09-07 Cary Coutant <ccoutant@gmail.com> + + PR gold/18930 + PR gold/18886 + * resolve.cc (Symbol::override_base): Don't convert IFUNC symbols here. + * symtab.cc (Symbol_table::add_from_dynobj): Convert them here instead. + 2015-09-02 H.J. Lu <hongjiu.lu@intel.com> PR gold/18886 diff --git a/gold/resolve.cc b/gold/resolve.cc index dd5b6b6..2dcf7b5 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -98,13 +98,7 @@ Symbol::override_base(const elfcpp::Sym<size, big_endian>& sym, this->is_ordinary_shndx_ = is_ordinary; // Don't override st_type from plugin placeholder symbols. if (object->pluginobj() == NULL) - { - // Turn IFUNC symbols from shared libraries into normal FUNC symbols. - elfcpp::STT type = sym.get_st_type(); - if (object->is_dynamic() && type == elfcpp::STT_GNU_IFUNC) - type = elfcpp::STT_FUNC; - this->type_ = type; - } + this->type_ = sym.get_st_type(); this->binding_ = sym.get_st_bind(); this->override_visibility(sym.get_st_visibility()); this->nonvis_ = sym.get_st_nonvis(); diff --git a/gold/symtab.cc b/gold/symtab.cc index c0d21d6..6d107a8 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -1468,14 +1468,20 @@ Symbol_table::add_from_dynobj( // A protected symbol in a shared library must be treated as a // normal symbol when viewed from outside the shared library. // Implement this by overriding the visibility here. + // Likewise, an IFUNC symbol in a shared library must be treated + // as a normal FUNC symbol. elfcpp::Sym<size, big_endian>* psym = &sym; unsigned char symbuf[sym_size]; elfcpp::Sym<size, big_endian> sym2(symbuf); - if (sym.get_st_visibility() == elfcpp::STV_PROTECTED) + if (sym.get_st_visibility() == elfcpp::STV_PROTECTED + || sym.get_st_type() == elfcpp::STT_GNU_IFUNC) { memcpy(symbuf, p, sym_size); elfcpp::Sym_write<size, big_endian> sw(symbuf); - sw.put_st_other(elfcpp::STV_DEFAULT, sym.get_st_nonvis()); + if (sym.get_st_visibility() == elfcpp::STV_PROTECTED) + sw.put_st_other(elfcpp::STV_DEFAULT, sym.get_st_nonvis()); + if (sym.get_st_type() == elfcpp::STT_GNU_IFUNC) + sw.put_st_info(sym.get_st_bind(), elfcpp::STT_FUNC); psym = &sym2; } |