[GOLD] OSABI not set when STT_GNU_IFUNC or STB_GNU_UNIQUE symbols output
authorAlan Modra <amodra@gmail.com>
Wed, 2 Oct 2019 01:11:01 +0000 (10:41 +0930)
committerAlan Modra <amodra@gmail.com>
Mon, 18 Nov 2019 21:06:20 +0000 (07:36 +1030)
This patch arranges to have OSABI set to ELFOSABI_GNU (if not set to
some other non-zero value) when gold outputs an ifunc local or global
symbol, or a unique global symbol to either .dynsym or .symtab.
STT_GNU_IFUNC and STB_GNU_UNIQUE have values in the LOOS to HIOS range
and therefore require interpretation according to OSABI.

I'm not sure why parameters->target() is const Target& while
parameters->sized_target() is Sized_target*, but it's inconvenient to
use the latter in Symbol_table::finalize.  So this patch adds another
const_cast complained about in layout.cc and gold.cc.

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.

gold/ChangeLog
gold/object.cc
gold/symtab.cc
gold/symtab.h

index cc5da7d9642bd782889ca3024c1961cb5d36a332..9d71814ae313da2df09d634e702ddfdb70dec6cc 100644 (file)
@@ -1,3 +1,14 @@
+2019-11-19  Alan Modra  <amodra@gmail.com>
+
+       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.
+
 2019-11-11  Miguel Saldivar  <saldivarcher@gmail.com>
 
        PR 24996
index 2fca7eb22788257b19de00ddfa5f357957475cfb..959cbc5f2768dc65b03fe1a9d6d6273670ef7822 100644 (file)
@@ -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:
index 56d1e42b8b0b5eaaeef1f592f9d20d0b393bd84d..99e97210bda18f3ab867925bb434bd3b15fc5f0a 100644 (file)
@@ -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.
index a9e8dd3278374b920ec002642de5c0434fcaaf64..dd931f5f04164a786510f3bde24f1109e7ab972d 100644 (file)
@@ -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.
This page took 0.028947 seconds and 4 git commands to generate.