mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
Fix internal error caused by IFUNC patch.
The previous commit to fix PR gold/18886 converted STT_IFUNC to STT_FUNC when resolving to a symbol defined in a shared library. This leads to an internal error if the shared library symbol is seen first, as we do not convert the symbol at all. We need to override the STT_IFUNC in add_from_dynobj() instead of in override_base(). gold/ 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.
This commit is contained in:
parent
b31103ae77
commit
3d4fde6974
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user