aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2023-06-23 09:38:13 +0930
committerAlan Modra <amodra@gmail.com>2023-06-23 21:02:48 +0930
commitbdad2ad579f7e7a6307f61e67ef70315506a26f6 (patch)
treeac16c422e917dfe8cde08116d7c8029c881c40a9 /gold
parent027614abf11de9e79a335df4e1f9a788b7ab0063 (diff)
downloadgdb-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.
Diffstat (limited to 'gold')
-rw-r--r--gold/aarch64.cc2
-rw-r--r--gold/arm.cc2
-rw-r--r--gold/i386.cc2
-rw-r--r--gold/layout.cc17
-rw-r--r--gold/layout.h3
-rw-r--r--gold/mips.cc2
-rw-r--r--gold/powerpc.cc18
-rw-r--r--gold/s390.cc2
-rw-r--r--gold/sparc.cc2
-rw-r--r--gold/tilegx.cc2
-rw-r--r--gold/x86_64.cc2
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();