[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:
Alan Modra
2023-06-23 09:38:13 +09:30
parent 027614abf1
commit bdad2ad579
11 changed files with 38 additions and 16 deletions
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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();