diff options
author | Alan Modra <amodra@gmail.com> | 2023-06-23 09:38:13 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2023-06-23 21:02:48 +0930 |
commit | bdad2ad579f7e7a6307f61e67ef70315506a26f6 (patch) | |
tree | ac16c422e917dfe8cde08116d7c8029c881c40a9 | |
parent | 027614abf11de9e79a335df4e1f9a788b7ab0063 (diff) | |
download | gdb-bdad2ad579f7e7a6307f61e67ef70315506a26f6.zip gdb-bdad2ad579f7e7a6307f61e67ef70315506a26f6.tar.gz gdb-bdad2ad579f7e7a6307f61e67ef70315506a26f6.tar.bz2 |
[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.
-rw-r--r-- | gold/aarch64.cc | 2 | ||||
-rw-r--r-- | gold/arm.cc | 2 | ||||
-rw-r--r-- | gold/i386.cc | 2 | ||||
-rw-r--r-- | gold/layout.cc | 17 | ||||
-rw-r--r-- | gold/layout.h | 3 | ||||
-rw-r--r-- | gold/mips.cc | 2 | ||||
-rw-r--r-- | gold/powerpc.cc | 18 | ||||
-rw-r--r-- | gold/s390.cc | 2 | ||||
-rw-r--r-- | gold/sparc.cc | 2 | ||||
-rw-r--r-- | gold/tilegx.cc | 2 | ||||
-rw-r--r-- | gold/x86_64.cc | 2 |
11 files changed, 38 insertions, 16 deletions
diff --git a/gold/aarch64.cc b/gold/aarch64.cc index 46a278b..7f95c0c 100644 --- a/gold/aarch64.cc +++ b/gold/aarch64.cc @@ -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. diff --git a/gold/arm.cc b/gold/arm.cc index 1ab8eb5..f787c28 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -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. diff --git a/gold/i386.cc b/gold/i386.cc index d97e818..c4ea879 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -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. diff --git a/gold/layout.cc b/gold/layout.cc index a500868..b94855f 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -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); + } } } diff --git a/gold/layout.h b/gold/layout.h index 5bb9aff..040c98c 100644 --- a/gold/layout.h +++ b/gold/layout.h @@ -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 diff --git a/gold/mips.cc b/gold/mips.cc index bd7353b..a6a41d7 100644 --- a/gold/mips.cc +++ b/gold/mips.cc @@ -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 diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 0c15e1b..5838b49 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -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. diff --git a/gold/s390.cc b/gold/s390.cc index 9e555c9..6e53735 100644 --- a/gold/s390.cc +++ b/gold/s390.cc @@ -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; diff --git a/gold/sparc.cc b/gold/sparc.cc index 61904f9..42c4a32 100644 --- a/gold/sparc.cc +++ b/gold/sparc.cc @@ -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. diff --git a/gold/tilegx.cc b/gold/tilegx.cc index 69d4e64..a054b67 100644 --- a/gold/tilegx.cc +++ b/gold/tilegx.cc @@ -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. diff --git a/gold/x86_64.cc b/gold/x86_64.cc index 6cace04..928dfa8 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -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(); |