+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
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();
// 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;
}