This is the mail archive of the binutils@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]

Re: [GOLD] PR24853, OSABI not set when STT_GNU_IFUNC or STB_GNU_UNIQUE symbols output


On Wed, Oct 02, 2019 at 10:59:38PM +0930, Alan Modra wrote:
> @@ -2711,6 +2730,10 @@ void
>  Symbol_table::add_to_final_symtab(Symbol* sym, Stringpool* pool,
>  				  unsigned int* pindex, off_t* poff)
>  {
> +  if (sym->type() == elfcpp::STT_GNU_IFUNC
> +      || (sym->binding() == elfcpp::STB_GNU_UNIQUE
> +	  && parameters->options().gnu_unique()))
> +    this->set_has_gnu_output();
>    sym->set_symtab_index(*pindex);
>    if (sym->version() == NULL || !parameters->options().relocatable())
>      pool->add(sym->name(), false, NULL);

This part wasn't correct, sorry.  Unique symbols that have been forced
local for some reason will still have STB_GNU_UNIQUE binding at this
stage.  The following revision moves the add_to_final_symtab changes
into that function's caller, where we just look for ifunc symbols on
the forced_locals_ list.

	PR 24853
	* symtab.h (set_has_gnu_output, has_gnu_output_): New.
	* symtab.cc (Symbol_table::Symbol_table): Init has_gnu_output_.
	(Symbol_table::finalize): Set ELFOSABI_GNU when has_gnu_output_.
	(Symbol_table::set_dynsym_indexes, Symbol_table::sized_finalize):
	Call set_has_gnu_output for STT_GNU_IFUNC and STB_GNU_UNIQUE globals.
	* object.cc (Sized_relobj_file::do_finalize_local_symbols): Call
	set_has_gnu_output when STT_GNU_IFUNC locals will be output.

diff --git a/gold/object.cc b/gold/object.cc
index 2fca7eb227..959cbc5f27 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -2646,6 +2646,10 @@ Sized_relobj_file<size, big_endian>::do_finalize_local_symbols(
 	      lv->set_output_symtab_index(index);
 	      ++index;
 	    }
+	  if (lv->is_ifunc_symbol()
+	      && (lv->has_output_symtab_entry()
+		  || lv->needs_output_dynsym_entry()))
+	    symtab->set_has_gnu_output();
 	  break;
 	case CFLV_DISCARDED:
 	case CFLV_ERROR:
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 56d1e42b8b..99e97210bd 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -565,8 +565,8 @@ Symbol::set_undefined()
 
 Symbol_table::Symbol_table(unsigned int count,
                            const Version_script_info& version_script)
-  : saw_undefined_(0), offset_(0), table_(count), namepool_(),
-    forwarders_(), commons_(), tls_commons_(), small_commons_(),
+  : saw_undefined_(0), offset_(0), has_gnu_output_(false), table_(count),
+    namepool_(), forwarders_(), commons_(), tls_commons_(), small_commons_(),
     large_commons_(), forced_locals_(), warnings_(),
     version_script_(version_script), gc_(NULL), icf_(NULL),
     target_symbols_()
@@ -2565,6 +2565,8 @@ Symbol_table::set_dynsym_indexes(unsigned int index,
           ++index;
           ++forced_local_count;
 	  dynpool->add(sym->name(), false, NULL);
+	  if (sym->type() == elfcpp::STT_GNU_IFUNC)
+	    this->set_has_gnu_output();
         }
     }
   *pforced_local_count = forced_local_count;
@@ -2583,7 +2585,13 @@ Symbol_table::set_dynsym_indexes(unsigned int index,
           if (!sym->should_add_dynsym_entry(this))
             sym->set_dynsym_index(-1U);
           else
-            dyn_symbols.push_back(sym);
+	    {
+	      dyn_symbols.push_back(sym);
+	      if (sym->type() == elfcpp::STT_GNU_IFUNC
+		  || (sym->binding() == elfcpp::STB_GNU_UNIQUE
+		      && parameters->options().gnu_unique()))
+		this->set_has_gnu_output();
+	    }
         }
 
       return parameters->target().set_dynsym_indexes(&dyn_symbols, index, syms,
@@ -2611,6 +2619,10 @@ Symbol_table::set_dynsym_indexes(unsigned int index,
 	  ++index;
 	  syms->push_back(sym);
 	  dynpool->add(sym->name(), false, NULL);
+	  if (sym->type() == elfcpp::STT_GNU_IFUNC
+	      || (sym->binding() == elfcpp::STB_GNU_UNIQUE
+		  && parameters->options().gnu_unique()))
+	    this->set_has_gnu_output();
 
 	  // Record any version information, except those from
 	  // as-needed libraries not seen to be needed.  Note that the
@@ -2696,6 +2708,13 @@ Symbol_table::finalize(off_t off, off_t dynoff, size_t dyn_global_index,
   else
     gold_unreachable();
 
+  if (this->has_gnu_output_)
+    {
+      Target* target = const_cast<Target*>(&parameters->target());
+      if (target->osabi() == elfcpp::ELFOSABI_NONE)
+	target->set_osabi(elfcpp::ELFOSABI_GNU);
+    }
+
   // Now that we have the final symbol table, we can reliably note
   // which symbols should get warnings.
   this->warnings_.note_warnings(this);
@@ -2747,6 +2766,8 @@ Symbol_table::sized_finalize(off_t off, Stringpool* pool,
 	{
 	  this->add_to_final_symtab<size>(sym, pool, &index, &off);
 	  ++*plocal_symcount;
+	  if (sym->type() == elfcpp::STT_GNU_IFUNC)
+	    this->set_has_gnu_output();
 	}
     }
 
@@ -2757,7 +2778,13 @@ Symbol_table::sized_finalize(off_t off, Stringpool* pool,
     {
       Symbol* sym = p->second;
       if (this->sized_finalize_symbol<size>(sym))
-	this->add_to_final_symtab<size>(sym, pool, &index, &off);
+	{
+	  this->add_to_final_symtab<size>(sym, pool, &index, &off);
+	  if (sym->type() == elfcpp::STT_GNU_IFUNC
+	      || (sym->binding() == elfcpp::STB_GNU_UNIQUE
+		  && parameters->options().gnu_unique()))
+	    this->set_has_gnu_output();
+	}
     }
 
   // Now do target-specific symbols.
diff --git a/gold/symtab.h b/gold/symtab.h
index a9e8dd3278..dd931f5f04 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -1580,6 +1580,10 @@ class Symbol_table
   saw_undefined() const
   { return this->saw_undefined_; }
 
+  void
+  set_has_gnu_output()
+  { this->has_gnu_output_ = true; }
+
   // Allocate the common symbols
   void
   allocate_commons(Layout*, Mapfile*);
@@ -1981,6 +1985,8 @@ class Symbol_table
   // The number of global dynamic symbols (including forced-local symbols),
   // or 0 if none.
   unsigned int dynamic_count_;
+  // Set if a STT_GNU_IFUNC or STB_GNU_UNIQUE symbol will be output.
+  bool has_gnu_output_;
   // The symbol hash table.
   Symbol_table_type table_;
   // A pool of symbol names.  This is used for all global symbols.


-- 
Alan Modra
Australia Development Lab, IBM


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