diff options
-rw-r--r-- | gold/ChangeLog | 8 | ||||
-rw-r--r-- | gold/resolve.cc | 8 | ||||
-rw-r--r-- | gold/symtab.cc | 5 |
3 files changed, 16 insertions, 5 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 5194fd5..cd24883 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,11 @@ +2015-09-02 H.J. Lu <hongjiu.lu@intel.com> + + PR gold/18886 + * resolve.cc (Symbol::override_base): Turn IFUNC symbols from + shared libraries into normal FUNC symbols. + * symtab.cc (Symbol_table::sized_write_symbol): Assert IFUNC + symbols aren't from shared libraries. + 2015-09-02 Alan Modra <amodra@gmail.com> PR 18878 diff --git a/gold/resolve.cc b/gold/resolve.cc index 2dcf7b5..dd5b6b6 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -98,7 +98,13 @@ 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) - this->type_ = sym.get_st_type(); + { + // 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->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 c6b47b0..c0d21d6 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -3130,10 +3130,7 @@ Symbol_table::sized_write_symbol( else osym.put_st_size(sym->symsize()); elfcpp::STT type = sym->type(); - // Turn IFUNC symbols from shared libraries into normal FUNC symbols. - if (type == elfcpp::STT_GNU_IFUNC - && sym->is_from_dynobj()) - type = elfcpp::STT_FUNC; + gold_assert(type != elfcpp::STT_GNU_IFUNC || !sym->is_from_dynobj()); // A version script may have overridden the default binding. if (sym->is_forced_local()) osym.put_st_info(elfcpp::elf_st_info(elfcpp::STB_LOCAL, type)); |