From 453018bf4490421a995cd76b3d2a3f322359c6a5 Mon Sep 17 00:00:00 2001 From: Vladimir Radosavljevic Date: Wed, 15 Mar 2017 15:35:15 -0700 Subject: [PATCH] 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. --- gold/ChangeLog | 11 +++++++ gold/mips.cc | 79 +++++++++++++++----------------------------------- 2 files changed, 35 insertions(+), 55 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 4e1fb95f734..3102af5ea86 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,14 @@ +2017-03-15 Vladimir Radosavljevic + + * 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 * powerpc.cc (Target_powerpc::make_iplt_section): Check that diff --git a/gold/mips.cc b/gold/mips.cc index 95bf6db85f0..93b432af131 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::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 void Target_mips::set_gp(Layout* layout, Symbol_table* symtab) { - if (this->gp_ != NULL) - return; + gold_assert(this->gp_ == NULL); + + Sized_symbol* gp = + static_cast*>(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* gp = - static_cast*>(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*>(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*>(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::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::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::iterator p = this->dyn_relocs_.begin(); p != this->dyn_relocs_.end(); @@ -10865,13 +10841,6 @@ Target_mips::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 -- 2.30.2