diff options
author | Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com> | 2017-03-15 15:35:15 -0700 |
---|---|---|
committer | Cary Coutant <ccoutant@gmail.com> | 2017-03-15 16:51:35 -0700 |
commit | 453018bf4490421a995cd76b3d2a3f322359c6a5 (patch) | |
tree | 2b2944576a2b4bf4393cd8533af0adb641fa806d /gold | |
parent | b416fe873ef44b2a613c9266c6462a481926d986 (diff) | |
download | gdb-453018bf4490421a995cd76b3d2a3f322359c6a5.zip gdb-453018bf4490421a995cd76b3d2a3f322359c6a5.tar.gz gdb-453018bf4490421a995cd76b3d2a3f322359c6a5.tar.bz2 |
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')
-rw-r--r-- | gold/ChangeLog | 11 | ||||
-rw-r--r-- | gold/mips.cc | 79 |
2 files changed, 35 insertions, 55 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 4e1fb95..3102af5 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -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 diff --git a/gold/mips.cc b/gold/mips.cc index 95bf6db..93b432a 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 |