Correct the definition of _gp and _GLOBAL_OFFSET_TABLE_ symbols for MIPS.
authorVladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
Wed, 15 Mar 2017 22:35:15 +0000 (15:35 -0700)
committerCary Coutant <ccoutant@gmail.com>
Wed, 15 Mar 2017 23:51:35 +0000 (16:51 -0700)
gold/
        * 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.

gold/ChangeLog
gold/mips.cc

index 4e1fb95f73413c999ab46226dff61c3ab39b89ab..3102af5ea86731770f24933a3c43da2de69e568a 100644 (file)
@@ -1,3 +1,14 @@
+2017-03-15  Vladimir Radosavljevic  <Vladimir.Radosavljevic@imgtec.com>
+
+        * 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.
+
 2017-02-22  Alan Modra  <amodra@gmail.com>
 
        * powerpc.cc (Target_powerpc::make_iplt_section): Check that
index 95bf6db85f09b28872a158cef20731a7b1944686..93b432af131021b5b5d7729bbc90ab759bfb3aef 100644 (file)
@@ -2926,8 +2926,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.
@@ -8378,7 +8377,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);
     }
 
@@ -8391,53 +8390,30 @@ template<int size, bool big_endian>
 void
 Target_mips<size, big_endian>::set_gp(Layout* layout, Symbol_table* symtab)
 {
-  if (this->gp_ != NULL)
-    return;
+  gold_assert(this->gp_ == NULL);
+
+  Sized_symbol<size>* gp =
+    static_cast<Sized_symbol<size>*>(symtab->lookup("_gp"));
 
-  Output_data* section = layout->find_output_section(".got");
-  if (section == NULL)
+  // Set _gp symbol if the linker script hasn't created it.
+  if (gp == NULL || gp->source() != Symbol::IS_CONSTANT)
     {
       // 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;
-            }
-        }
-    }
+      Output_data* gp_section = (this->got_ != NULL
+                                 ? this->got_->output_section()
+                                 : layout->find_output_section(".sdata"));
 
-  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)
-    {
-      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 (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));
     }
+
+  this->gp_ = gp;
 }
 
 // Set the dynamic symbol indexes.  INDEX is the index of the first
@@ -9579,9 +9555,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())
     {
@@ -9748,6 +9721,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();
@@ -10865,13 +10841,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
This page took 0.032221 seconds and 4 git commands to generate.