[GOLD] Support setting DT_RELACOUNT late
PowerPC gold adds relative dynamic relocs in do_relax. These aren't accounted for in the value set in add_target_dynamic_tags, which is called before do_relax. Provide a way of setting DT_RELCOUNT and DT_RELACOUNT at the point where .dynamic is written. * layout.cc (Layout::add_target_dynamic_tags): Add custom_relcount parameter. Emit DT_RELCOUNT/RELACOUNT as a custom target handled dynamic tag if set. * layout.h(Layout::add_target_dynamic_tags): Update prototype. * aarch64.cc (Target_aarch64::do_finalize_sections): Adjust add_target_dynamic_tags call. * arm.cc (Target_arm::do_finalize_sections): Likewise. * i386.cc (Target_i386::do_finalize_sections): Likewise. * mips.cc (Target_mips::do_finalize_sections): Likewise. * s390.cc (Target_s390::do_finalize_sections): Likewise. * sparc.cc (Target_sparc::do_finalize_sections): Likewise. * tilegx.cc (Target_tilegx::do_finalize_sections): Likewise. * x86_64.cc (Target_x86_64::do_finalize_sections): Likewise. * powerpc.cc (Target_powerpc::do_finalize_sections): Likewise. (Target_powerpc::do_dynamic_tag_custom_value): New function.
This commit is contained in:
+1
-1
@@ -6951,7 +6951,7 @@ Target_aarch64<size, big_endian>::do_finalize_sections(
|
||||
? NULL
|
||||
: this->plt_->rela_plt());
|
||||
layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
|
||||
this->rela_dyn_, true, false);
|
||||
this->rela_dyn_, true, false, false);
|
||||
|
||||
// Emit any relocs we saved in an attempt to avoid generating COPY
|
||||
// relocs.
|
||||
|
||||
+1
-1
@@ -9484,7 +9484,7 @@ Target_arm<big_endian>::do_finalize_sections(
|
||||
? NULL
|
||||
: this->plt_->rel_plt());
|
||||
layout->add_target_dynamic_tags(true, this->got_plt_, rel_plt,
|
||||
this->rel_dyn_, true, false);
|
||||
this->rel_dyn_, true, false, false);
|
||||
|
||||
// Emit any relocs we saved in an attempt to avoid generating COPY
|
||||
// relocs.
|
||||
|
||||
+1
-1
@@ -2672,7 +2672,7 @@ Target_i386::do_finalize_sections(
|
||||
? NULL
|
||||
: this->plt_->rel_plt());
|
||||
layout->add_target_dynamic_tags(true, this->got_plt_, rel_plt,
|
||||
this->rel_dyn_, true, false);
|
||||
this->rel_dyn_, true, false, false);
|
||||
|
||||
// Emit any relocs we saved in an attempt to avoid generating COPY
|
||||
// relocs.
|
||||
|
||||
+11
-6
@@ -5138,7 +5138,8 @@ void
|
||||
Layout::add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
|
||||
const Output_data* plt_rel,
|
||||
const Output_data_reloc_generic* dyn_rel,
|
||||
bool add_debug, bool dynrel_includes_plt)
|
||||
bool add_debug, bool dynrel_includes_plt,
|
||||
bool custom_relcount)
|
||||
{
|
||||
Output_data_dynamic* odyn = this->dynamic_data_;
|
||||
if (odyn == NULL)
|
||||
@@ -5203,11 +5204,15 @@ Layout::add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
|
||||
if (parameters->options().combreloc() && have_dyn_rel)
|
||||
{
|
||||
size_t c = dyn_rel->relative_reloc_count();
|
||||
if (c > 0)
|
||||
odyn->add_constant((use_rel
|
||||
? elfcpp::DT_RELCOUNT
|
||||
: elfcpp::DT_RELACOUNT),
|
||||
c);
|
||||
if (c != 0)
|
||||
{
|
||||
elfcpp::DT tag
|
||||
= use_rel ? elfcpp::DT_RELCOUNT : elfcpp::DT_RELACOUNT;
|
||||
if (custom_relcount)
|
||||
odyn->add_custom(tag);
|
||||
else
|
||||
odyn->add_constant(tag, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -950,7 +950,8 @@ class Layout
|
||||
add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
|
||||
const Output_data* plt_rel,
|
||||
const Output_data_reloc_generic* dyn_rel,
|
||||
bool add_debug, bool dynrel_includes_plt);
|
||||
bool add_debug, bool dynrel_includes_plt,
|
||||
bool custom_relcount);
|
||||
|
||||
// Add a target-specific dynamic tag with constant value.
|
||||
void
|
||||
|
||||
+1
-1
@@ -9826,7 +9826,7 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
|
||||
const Reloc_section* rel_plt = (this->plt_ == NULL
|
||||
? NULL : this->plt_->rel_plt());
|
||||
layout->add_target_dynamic_tags(true, this->got_, rel_plt,
|
||||
this->rel_dyn_, true, false);
|
||||
this->rel_dyn_, true, false, false);
|
||||
|
||||
Output_data_dynamic* const odyn = layout->dynamic_data();
|
||||
if (odyn != NULL
|
||||
|
||||
+17
-1
@@ -796,6 +796,10 @@ class Target_powerpc : public Sized_target<size, big_endian>
|
||||
void
|
||||
do_finalize_sections(Layout*, const Input_objects*, Symbol_table*);
|
||||
|
||||
// Get the custom dynamic tag value.
|
||||
unsigned int
|
||||
do_dynamic_tag_custom_value(elfcpp::DT) const;
|
||||
|
||||
// Return the value to use for a dynamic which requires special
|
||||
// treatment.
|
||||
uint64_t
|
||||
@@ -10135,7 +10139,7 @@ Target_powerpc<size, big_endian>::do_finalize_sections(
|
||||
? NULL
|
||||
: this->plt_->rel_plt());
|
||||
layout->add_target_dynamic_tags(false, this->plt_, rel_plt,
|
||||
this->rela_dyn_, true, size == 32);
|
||||
this->rela_dyn_, true, size == 32, true);
|
||||
|
||||
if (size == 32)
|
||||
{
|
||||
@@ -10206,6 +10210,18 @@ Target_powerpc<size, big_endian>::do_finalize_sections(
|
||||
}
|
||||
}
|
||||
|
||||
// Get the custom dynamic tag value.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
unsigned int
|
||||
Target_powerpc<size, big_endian>::do_dynamic_tag_custom_value(
|
||||
elfcpp::DT tag) const
|
||||
{
|
||||
if (tag != elfcpp::DT_RELACOUNT)
|
||||
gold_unreachable();
|
||||
return this->rela_dyn_->relative_reloc_count();
|
||||
}
|
||||
|
||||
// Merge object attributes from input file called NAME with those of the
|
||||
// output. The input object attributes are in the object pointed by PASD.
|
||||
|
||||
|
||||
+1
-1
@@ -4043,7 +4043,7 @@ Target_s390<size>::do_finalize_sections(
|
||||
? NULL
|
||||
: this->plt_->rela_plt());
|
||||
layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
|
||||
this->rela_dyn_, true, size == 32);
|
||||
this->rela_dyn_, true, size == 32, false);
|
||||
|
||||
this->layout_ = layout;
|
||||
|
||||
|
||||
+1
-1
@@ -3197,7 +3197,7 @@ Target_sparc<size, big_endian>::do_finalize_sections(
|
||||
? NULL
|
||||
: this->plt_->rel_plt());
|
||||
layout->add_target_dynamic_tags(false, this->plt_, rel_plt,
|
||||
this->rela_dyn_, true, true);
|
||||
this->rela_dyn_, true, true, false);
|
||||
|
||||
// Emit any relocs we saved in an attempt to avoid generating COPY
|
||||
// relocs.
|
||||
|
||||
+1
-1
@@ -4265,7 +4265,7 @@ Target_tilegx<size, big_endian>::do_finalize_sections(
|
||||
? NULL
|
||||
: this->plt_->rela_plt());
|
||||
layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
|
||||
this->rela_dyn_, true, true);
|
||||
this->rela_dyn_, true, true, false);
|
||||
|
||||
// Emit any relocs we saved in an attempt to avoid generating COPY
|
||||
// relocs.
|
||||
|
||||
+1
-1
@@ -4073,7 +4073,7 @@ Target_x86_64<size>::do_finalize_sections(
|
||||
? NULL
|
||||
: this->plt_->rela_plt());
|
||||
layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
|
||||
this->rela_dyn_, true, false);
|
||||
this->rela_dyn_, true, false, false);
|
||||
|
||||
// Fill in some more dynamic tags.
|
||||
Output_data_dynamic* const odyn = layout->dynamic_data();
|
||||
|
||||
Reference in New Issue
Block a user