This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Fix internal error caused by IFUNC patch.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3d4fde6974a1237d79055ee734d99cc49c6fd3f9

commit 3d4fde6974a1237d79055ee734d99cc49c6fd3f9
Author: Cary Coutant <ccoutant@gmail.com>
Date:   Mon Sep 7 09:44:11 2015 -0700

    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.

Diff:
---
 gold/ChangeLog  |  7 +++++++
 gold/resolve.cc |  8 +-------
 gold/symtab.cc  | 10 ++++++++--
 3 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index cd24883..49ce2fe 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -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
diff --git a/gold/resolve.cc b/gold/resolve.cc
index dd5b6b6..2dcf7b5 100644
--- a/gold/resolve.cc
+++ b/gold/resolve.cc
@@ -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();
diff --git a/gold/symtab.cc b/gold/symtab.cc
index c0d21d6..6d107a8 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -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;
 	}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]