aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-09-02 04:14:21 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-09-02 04:17:43 -0700
commit358de98820c5e9caa222846ba8b646de6cc091c8 (patch)
tree5fad77fceea123768e3893418af7645f4666910e
parentd49044c7530d28894e73763c21c417a423e4297c (diff)
downloadgdb-358de98820c5e9caa222846ba8b646de6cc091c8.zip
gdb-358de98820c5e9caa222846ba8b646de6cc091c8.tar.gz
gdb-358de98820c5e9caa222846ba8b646de6cc091c8.tar.bz2
Turn IFUNC symbols from shared libraries into normal FUNC symbols
Turn IFUNC symbols from shared libraries into normal FUNC symbols when we are resolving symbol references, instead of when we are writing out the symbol table. 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.
-rw-r--r--gold/ChangeLog8
-rw-r--r--gold/resolve.cc8
-rw-r--r--gold/symtab.cc5
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));