aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2023-08-25 09:12:18 +0930
committerAlan Modra <amodra@gmail.com>2023-08-25 11:21:47 +0930
commitd537f77ef3b18a5fbfd598643aaad957652e9608 (patch)
tree30a33367fd373bc80e31fd590ee38de89101df05 /gold
parentAutomatic date update in version.in (diff)
downloadbinutils-gdb-d537f77ef3b18a5fbfd598643aaad957652e9608.tar.gz
binutils-gdb-d537f77ef3b18a5fbfd598643aaad957652e9608.tar.bz2
binutils-gdb-d537f77ef3b18a5fbfd598643aaad957652e9608.zip
PR30794, PowerPC gold: internal error in add_output_section_to_load
Caused by commit 5a97377e5513, specifically this code added to Target_powerpc::do_relax + if (parameters->options().output_is_position_independent()) + this->rela_dyn_size_ + = this->rela_dyn_section(layout)->current_data_size(); The problem here is that if .rela.dyn isn't already created then the call to rela_dyn_section creates it, and as this comment in Target_powerpc::do_finalize_sections says: // Annoyingly, we need to make these sections now whether or // not we need them. If we delay until do_relax then we // need to mess with the relaxation machinery checkpointing. We can't be creating sections in do_relax. PR 30794 * powerpc.cc (Target_powerpc::do_relax): Only set rela_dyn_size_ for size == 64, and assert that rela_dyn_ already exists. Tidy code setting plt_thread_safe, which also only needs to be set when size == 64 for ELFv1.
Diffstat (limited to 'gold')
-rw-r--r--gold/powerpc.cc47
1 files changed, 25 insertions, 22 deletions
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index e66d9cbb900..a4fecaae55a 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -3714,12 +3714,7 @@ Target_powerpc<size, big_endian>::do_relax(int pass,
unsigned int prev_brlt_size = 0;
if (pass == 1)
{
- bool thread_safe
- = this->abiversion() < 2 && parameters->options().plt_thread_safe();
- if (size == 64
- && this->abiversion() < 2
- && !thread_safe
- && !parameters->options().user_set_plt_thread_safe())
+ if (size == 64 && this->abiversion() < 2)
{
static const char* const thread_starter[] =
{
@@ -3747,29 +3742,37 @@ Target_powerpc<size, big_endian>::do_relax(int pass,
/* libgo */
"__go_go",
};
+ bool thread_safe = parameters->options().plt_thread_safe();
- if (parameters->options().shared())
- thread_safe = true;
- else
+ if (!thread_safe
+ && !parameters->options().user_set_plt_thread_safe())
{
- for (unsigned int i = 0;
- i < sizeof(thread_starter) / sizeof(thread_starter[0]);
- i++)
+ if (parameters->options().shared())
+ thread_safe = true;
+ else
{
- Symbol* sym = symtab->lookup(thread_starter[i], NULL);
- thread_safe = (sym != NULL
- && sym->in_reg()
- && sym->in_real_elf());
- if (thread_safe)
- break;
+ for (unsigned int i = 0;
+ i < sizeof(thread_starter) / sizeof(thread_starter[0]);
+ i++)
+ {
+ Symbol* sym = symtab->lookup(thread_starter[i], NULL);
+ thread_safe = (sym != NULL
+ && sym->in_reg()
+ && sym->in_real_elf());
+ if (thread_safe)
+ break;
+ }
}
}
+ this->plt_thread_safe_ = thread_safe;
}
- this->plt_thread_safe_ = thread_safe;
- if (parameters->options().output_is_position_independent())
- this->rela_dyn_size_
- = this->rela_dyn_section(layout)->current_data_size();
+ if (size == 64
+ && parameters->options().output_is_position_independent())
+ {
+ gold_assert (this->rela_dyn_);
+ this->rela_dyn_size_ = this->rela_dyn_->current_data_size();
+ }
this->stub_group_size_ = parameters->options().stub_group_size();
bool no_size_errors = true;