summaryrefslogtreecommitdiff
path: root/gold/mips.cc
diff options
context:
space:
mode:
authorVladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>2017-03-15 15:35:15 -0700
committerCary Coutant <ccoutant@gmail.com>2017-03-15 16:51:35 -0700
commit453018bf4490421a995cd76b3d2a3f322359c6a5 (patch)
tree2b2944576a2b4bf4393cd8533af0adb641fa806d /gold/mips.cc
parentb416fe873ef44b2a613c9266c6462a481926d986 (diff)
Correct the definition of _gp and _GLOBAL_OFFSET_TABLE_ symbols for MIPS.
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.
Diffstat (limited to 'gold/mips.cc')
-rw-r--r--gold/mips.cc79
1 files changed, 24 insertions, 55 deletions
diff --git a/gold/mips.cc b/gold/mips.cc
index 95bf6db85f..93b432af13 100644
--- a/gold/mips.cc
+++ b/gold/mips.cc
@@ -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