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.
This commit is contained in:
parent
b416fe873e
commit
453018bf44
|
@ -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
|
||||
|
|
79
gold/mips.cc
79
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;
|
||||
|
||||
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)
|
||||
|
||||
// Set _gp symbol if the linker script hasn't created it.
|
||||
if (gp == NULL || gp->source() != Symbol::IS_CONSTANT)
|
||||
{
|
||||
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 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));
|
||||
}
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue