Turn IFUNC symbols from shared libraries into normal FUNC symbols
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 2 Sep 2015 11:14:21 +0000 (04:14 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 2 Sep 2015 11:17:43 +0000 (04:17 -0700)
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.

gold/ChangeLog
gold/resolve.cc
gold/symtab.cc

index 5194fd5db1826a816b87bdf32941ed7a7c9bb790..cd24883b3a41146bc8ca40c9ac3c2a0842fc4255 100644 (file)
@@ -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
index 2dcf7b5b1e8c6431029fe3f53f4b43d41d841bc2..dd5b6b6afa619600bbbd1bb694671613f5bcfc9b 100644 (file)
@@ -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();
index c6b47b05ca050399d1f6ab92f0618c8f726c3fa8..c0d21d6ff6ca63c3222fca3b9a9ca331507eba53 100644 (file)
@@ -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));