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]

[PATCH][gold] Mips: Correct the definition of _gp and _GLOBAL_OFFSET_TABLE_


This patch corrects the definition of _gp and _GLOBAL_OFFSET_TABLE_ symbols.
With this patch, all _gp scope tests from GNU ld testsuite are passing.
Depends on https://sourceware.org/ml/binutils/2017-03/msg00146.html.

Regards,
Vladimir

ChangeLog -

	* mips.cc (symbol_refs_local): Return false if a symbol
	is from a dynamic object.
	(Target_mips::got_section): Make _GLOBAL_OFFSET_TABLE_ STV_HIDDEN.
	(Target_mips::set_gp): Refactor.  Make _gp STT_NOTYPE and
	STB_LOCAL.
	(Target_mips::do_finalize_sections): Set _gp after all the checks
	for creating .got are done.
	(Target_mips::Scan::global): Remove unused code.
diff --git a/gold/mips.cc b/gold/mips.cc
index 52edeac..75470a7 100644
--- a/gold/mips.cc
+++ b/gold/mips.cc
@@ -2959,8 +2959,7 @@ symbol_refs_local(const Symbol* sym, bool has_dynsym_entry,
 
   // If we don't have a definition in a regular file, then we can't
   // resolve locally.  The sym is either undefined or dynamic.
-  if (sym->source() != Symbol::FROM_OBJECT || sym->object()->is_dynamic()
-      || sym->is_undefined())
+  if (sym->is_from_dynobj() || sym->is_undefined())
     return false;
 
   // Forced local symbols resolve locally.
@@ -8463,7 +8462,7 @@ Target_mips<size, big_endian>::got_section(Symbol_table* symtab,
                                     this->got_,
                                     0, 0, elfcpp::STT_OBJECT,
                                     elfcpp::STB_GLOBAL,
-                                    elfcpp::STV_DEFAULT, 0,
+                                    elfcpp::STV_HIDDEN, 0,
                                     false, false);
     }
 
@@ -8476,52 +8475,27 @@ template<int size, bool big_endian>
 void
 Target_mips<size, big_endian>::set_gp(Layout* layout, Symbol_table* symtab)
 {
-  if (this->gp_ != NULL)
-    return;
-
-  Output_data* section = layout->find_output_section(".got");
-  if (section == NULL)
-    {
-      // If there is no .got section, gp should be based on .sdata.
-      // TODO(sasa): This is probably not needed.  This was needed for older
-      // MIPS architectures which accessed both GOT and .sdata section using
-      // gp-relative addressing.  Modern Mips Linux ELF architectures don't
-      // access .sdata using gp-relative addressing.
-      for (Layout::Section_list::const_iterator
-           p = layout->section_list().begin();
-           p != layout->section_list().end();
-           ++p)
-        {
-          if (strcmp((*p)->name(), ".sdata") == 0)
-            {
-              section = *p;
-              break;
-            }
-        }
-    }
+  gold_assert(this->gp_ == NULL);
 
   Sized_symbol<size>* gp =
     static_cast<Sized_symbol<size>*>(symtab->lookup("_gp"));
-  if (gp != NULL)
-    {
-      if (gp->source() != Symbol::IS_CONSTANT && section != NULL)
-        gp->init_output_data(gp->name(), NULL, section, MIPS_GP_OFFSET, 0,
-                             elfcpp::STT_OBJECT,
-                             elfcpp::STB_GLOBAL,
-                             elfcpp::STV_DEFAULT, 0,
-                             false, false);
-      this->gp_ = gp;
-    }
-  else if (section != NULL)
+
+  // Set _gp symbol if the linker script hasn't created it.
+  if (gp == NULL || gp->source() != Symbol::IS_CONSTANT)
     {
-      gp = static_cast<Sized_symbol<size>*>(symtab->define_in_output_data(
-                                      "_gp", NULL, Symbol_table::PREDEFINED,
-                                      section, MIPS_GP_OFFSET, 0,
-                                      elfcpp::STT_OBJECT,
-                                      elfcpp::STB_GLOBAL,
-                                      elfcpp::STV_DEFAULT,
-                                      0, false, false));
-      this->gp_ = gp;
+      // If there is no .got section, gp should be based on .sdata.
+      Output_data* gp_section = (this->got_ != NULL
+                                 ? this->got_->output_section()
+                                 : layout->find_output_section(".sdata"));
+
+      if (gp_section != NULL)
+        gp = static_cast<Sized_symbol<size>*>(symtab->define_in_output_data(
+                                          "_gp", NULL, Symbol_table::PREDEFINED,
+                                          gp_section, MIPS_GP_OFFSET, 0,
+                                          elfcpp::STT_NOTYPE,
+                                          elfcpp::STB_LOCAL,
+                                          elfcpp::STV_DEFAULT,
+                                          0, false, false));
     }
 
   if (parameters->options().relocatable())
@@ -8531,15 +8505,16 @@ Target_mips<size, big_endian>::set_gp(Layout* layout, Symbol_table* symtab)
         gp = static_cast<Sized_symbol<size>*>(symtab->define_as_constant(
                                       "_gp", NULL, Symbol_table::PREDEFINED,
                                       MIPS_GP_OFFSET, 0,
-                                      elfcpp::STT_OBJECT,
-                                      elfcpp::STB_GLOBAL,
+                                      elfcpp::STT_NOTYPE,
+                                      elfcpp::STB_LOCAL,
                                       elfcpp::STV_DEFAULT,
                                       0, false, false));
       // Don't add _gp to the final symtab, because the value of the _gp symbol
       // will be stored into .reginfo/.MIPS.options section.
       gp->set_symtab_index(-1U);
-      this->gp_ = gp;
     }
+
+  this->gp_ = gp;
 }
 
 // Set the dynamic symbol indexes.  INDEX is the index of the first
@@ -9680,9 +9655,6 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
   if (this->got16_addends_.size() > 0)
       gold_error("Can't find matching LO16 reloc");
 
-  // Set _gp value.
-  this->set_gp(layout, symtab);
-
   // Check for any mips16 stub sections that we can discard.
   if (!parameters->options().relocatable())
     {
@@ -9849,6 +9821,9 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
     this->copy_relocs_.emit_mips(this->rel_dyn_section(layout), symtab, layout,
                                  this);
 
+  // Set _gp value.
+  this->set_gp(layout, symtab);
+
   // Emit dynamic relocs.
   for (typename std::vector<Dyn_reloc>::iterator p = this->dyn_relocs_.begin();
        p != this->dyn_relocs_.end();
@@ -11069,13 +11044,6 @@ Target_mips<size, big_endian>::Scan::global(
     // looking for relocs that would need to refer to MIPS16 stubs.
     mips_sym->set_need_fn_stub();
 
-  // A reference to _GLOBAL_OFFSET_TABLE_ implies that we need a got
-  // section.  We check here to avoid creating a dynamic reloc against
-  // _GLOBAL_OFFSET_TABLE_.
-  if (!target->has_got_section()
-      && strcmp(gsym->name(), "_GLOBAL_OFFSET_TABLE_") == 0)
-    target->got_section(symtab, layout);
-
   // We need PLT entries if there are static-only relocations against
   // an externally-defined function.  This can technically occur for
   // shared libraries if there are branches to the symbol, although it

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