Add support for MIPS .rld_map section.
Includes DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL dynamic tags and __RLD_MAP symbol. 2016-06-20 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com> elfcpp/ * elfcpp.h (DT_MIPS_RLD_MAP_REL): New enum constant. gold/ * mips.cc (Target_mips::Target_mips): Initialize rld_map_. (Target_mips::rld_map_): New data member. (Target_mips::do_finalize_sections): Add support for DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL dynamic tags, .rld_map section, and __RLD_MAP symbol. (Target_mips::do_dynamic_tag_custom_value): Add support for DT_MIPS_RLD_MAP_REL dynamic tag. * output.cc (Output_data_dynamic::get_entry_offset): New method definition. * output.h (Output_data_dynamic::get_entry_offset): New method declaration.
This commit is contained in:
parent
beceef5043
commit
a8ecc9fe61
6 changed files with 91 additions and 5 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
2016-06-20 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
|
||||||
|
|
||||||
|
* elfcpp.h (DT_MIPS_RLD_MAP_REL): New enum constant.
|
||||||
|
|
||||||
2016-06-20 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
|
2016-06-20 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
|
||||||
|
|
||||||
* mips.h (R_MIPS_PC21_S2, R_MIPS_PC26_S2, R_MIPS_PC18_S3,
|
* mips.h (R_MIPS_PC21_S2, R_MIPS_PC26_S2, R_MIPS_PC18_S3,
|
||||||
|
|
|
@ -868,6 +868,8 @@ enum DT
|
||||||
DT_MIPS_PLTGOT = 0x70000032,
|
DT_MIPS_PLTGOT = 0x70000032,
|
||||||
// Points to the base of a writable PLT.
|
// Points to the base of a writable PLT.
|
||||||
DT_MIPS_RWPLT = 0x70000034,
|
DT_MIPS_RWPLT = 0x70000034,
|
||||||
|
// Relative offset of run time loader map, used for debugging.
|
||||||
|
DT_MIPS_RLD_MAP_REL = 0x70000035,
|
||||||
|
|
||||||
DT_AUXILIARY = 0x7ffffffd,
|
DT_AUXILIARY = 0x7ffffffd,
|
||||||
DT_USED = 0x7ffffffe,
|
DT_USED = 0x7ffffffe,
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
2016-06-20 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
|
||||||
|
|
||||||
|
* mips.cc (Target_mips::Target_mips): Initialize rld_map_.
|
||||||
|
(Target_mips::rld_map_): New data member.
|
||||||
|
(Target_mips::do_finalize_sections): Add support for
|
||||||
|
DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL dynamic tags,
|
||||||
|
.rld_map section, and __RLD_MAP symbol.
|
||||||
|
(Target_mips::do_dynamic_tag_custom_value): Add support for
|
||||||
|
DT_MIPS_RLD_MAP_REL dynamic tag.
|
||||||
|
* output.cc (Output_data_dynamic::get_entry_offset): New method
|
||||||
|
definition.
|
||||||
|
* output.h (Output_data_dynamic::get_entry_offset): New method
|
||||||
|
declaration.
|
||||||
|
|
||||||
2016-06-20 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
|
2016-06-20 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
|
||||||
|
|
||||||
* mips.cc (Mips_relocate_functions::relpc16): Add unaligned check.
|
* mips.cc (Mips_relocate_functions::relpc16): Add unaligned check.
|
||||||
|
|
51
gold/mips.cc
51
gold/mips.cc
|
@ -3292,10 +3292,10 @@ class Target_mips : public Sized_target<size, big_endian>
|
||||||
public:
|
public:
|
||||||
Target_mips(const Target::Target_info* info = &mips_info)
|
Target_mips(const Target::Target_info* info = &mips_info)
|
||||||
: Sized_target<size, big_endian>(info), got_(NULL), gp_(NULL), plt_(NULL),
|
: Sized_target<size, big_endian>(info), got_(NULL), gp_(NULL), plt_(NULL),
|
||||||
got_plt_(NULL), rel_dyn_(NULL), copy_relocs_(), dyn_relocs_(),
|
got_plt_(NULL), rel_dyn_(NULL), rld_map_(NULL), copy_relocs_(),
|
||||||
la25_stub_(NULL), mips_mach_extensions_(), mips_stubs_(NULL),
|
dyn_relocs_(), la25_stub_(NULL), mips_mach_extensions_(),
|
||||||
attributes_section_data_(NULL), abiflags_(NULL), mach_(0), layout_(NULL),
|
mips_stubs_(NULL), attributes_section_data_(NULL), abiflags_(NULL),
|
||||||
got16_addends_(), has_abiflags_section_(false),
|
mach_(0), layout_(NULL), got16_addends_(), has_abiflags_section_(false),
|
||||||
entry_symbol_is_compressed_(false), insn32_(false)
|
entry_symbol_is_compressed_(false), insn32_(false)
|
||||||
{
|
{
|
||||||
this->add_machine_extensions();
|
this->add_machine_extensions();
|
||||||
|
@ -4181,6 +4181,8 @@ class Target_mips : public Sized_target<size, big_endian>
|
||||||
Output_data_space* got_plt_;
|
Output_data_space* got_plt_;
|
||||||
// The dynamic reloc section.
|
// The dynamic reloc section.
|
||||||
Reloc_section* rel_dyn_;
|
Reloc_section* rel_dyn_;
|
||||||
|
// The .rld_map section.
|
||||||
|
Output_data_zero_fill* rld_map_;
|
||||||
// Relocs saved to avoid a COPY reloc.
|
// Relocs saved to avoid a COPY reloc.
|
||||||
Mips_copy_relocs<elfcpp::SHT_REL, size, big_endian> copy_relocs_;
|
Mips_copy_relocs<elfcpp::SHT_REL, size, big_endian> copy_relocs_;
|
||||||
|
|
||||||
|
@ -9760,8 +9762,37 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
|
||||||
if (this->plt_ != NULL)
|
if (this->plt_ != NULL)
|
||||||
// DT_MIPS_PLTGOT dynamic tag
|
// DT_MIPS_PLTGOT dynamic tag
|
||||||
odyn->add_section_address(elfcpp::DT_MIPS_PLTGOT, this->got_plt_);
|
odyn->add_section_address(elfcpp::DT_MIPS_PLTGOT, this->got_plt_);
|
||||||
|
|
||||||
|
if (!parameters->options().shared())
|
||||||
|
{
|
||||||
|
this->rld_map_ = new Output_data_zero_fill(size / 8, size / 8);
|
||||||
|
|
||||||
|
layout->add_output_section_data(".rld_map", elfcpp::SHT_PROGBITS,
|
||||||
|
(elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
|
||||||
|
this->rld_map_, ORDER_INVALID, false);
|
||||||
|
|
||||||
|
// __RLD_MAP will be filled in by the runtime loader to contain
|
||||||
|
// a pointer to the _r_debug structure.
|
||||||
|
Symbol* rld_map = symtab->define_in_output_data("__RLD_MAP", NULL,
|
||||||
|
Symbol_table::PREDEFINED,
|
||||||
|
this->rld_map_,
|
||||||
|
0, 0, elfcpp::STT_OBJECT,
|
||||||
|
elfcpp::STB_GLOBAL,
|
||||||
|
elfcpp::STV_DEFAULT, 0,
|
||||||
|
false, false);
|
||||||
|
|
||||||
|
rld_map->set_needs_dynsym_entry();
|
||||||
|
|
||||||
|
if (!parameters->options().pie())
|
||||||
|
// This member holds the absolute address of the debug pointer.
|
||||||
|
odyn->add_section_address(elfcpp::DT_MIPS_RLD_MAP, this->rld_map_);
|
||||||
|
else
|
||||||
|
// This member holds the offset to the debug pointer,
|
||||||
|
// relative to the address of the tag.
|
||||||
|
odyn->add_custom(elfcpp::DT_MIPS_RLD_MAP_REL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the custom dynamic tag value.
|
// Get the custom dynamic tag value.
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
|
@ -9797,6 +9828,16 @@ Target_mips<size, big_endian>::do_dynamic_tag_custom_value(elfcpp::DT tag) const
|
||||||
return this->get_dt_mips_symtabno();
|
return this->get_dt_mips_symtabno();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case elfcpp::DT_MIPS_RLD_MAP_REL:
|
||||||
|
{
|
||||||
|
// The MIPS_RLD_MAP_REL tag stores the offset to the debug pointer,
|
||||||
|
// relative to the address of the tag.
|
||||||
|
Output_data_dynamic* const odyn = this->layout_->dynamic_data();
|
||||||
|
unsigned int entry_offset =
|
||||||
|
odyn->get_entry_offset(elfcpp::DT_MIPS_RLD_MAP_REL);
|
||||||
|
gold_assert(entry_offset != -1U);
|
||||||
|
return this->rld_map_->address() - (odyn->address() + entry_offset);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
gold_error(_("Unknown dynamic tag 0x%x"), (unsigned int)tag);
|
gold_error(_("Unknown dynamic tag 0x%x"), (unsigned int)tag);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1882,6 +1882,27 @@ Output_data_dynamic::do_adjust_output_section(Output_section* os)
|
||||||
gold_unreachable();
|
gold_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get a dynamic entry offset.
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
Output_data_dynamic::get_entry_offset(elfcpp::DT tag) const
|
||||||
|
{
|
||||||
|
int dyn_size;
|
||||||
|
|
||||||
|
if (parameters->target().get_size() == 32)
|
||||||
|
dyn_size = elfcpp::Elf_sizes<32>::dyn_size;
|
||||||
|
else if (parameters->target().get_size() == 64)
|
||||||
|
dyn_size = elfcpp::Elf_sizes<64>::dyn_size;
|
||||||
|
else
|
||||||
|
gold_unreachable();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < entries_.size(); ++i)
|
||||||
|
if (entries_[i].tag() == tag)
|
||||||
|
return i * dyn_size;
|
||||||
|
|
||||||
|
return -1U;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the final data size.
|
// Set the final data size.
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -2781,6 +2781,10 @@ class Output_data_dynamic : public Output_section_data
|
||||||
add_custom(elfcpp::DT tag)
|
add_custom(elfcpp::DT tag)
|
||||||
{ this->add_entry(Dynamic_entry(tag)); }
|
{ this->add_entry(Dynamic_entry(tag)); }
|
||||||
|
|
||||||
|
// Get a dynamic entry offset.
|
||||||
|
unsigned int
|
||||||
|
get_entry_offset(elfcpp::DT tag) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Adjust the output section to set the entry size.
|
// Adjust the output section to set the entry size.
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue