diff options
author | Alan Modra <amodra@gmail.com> | 2021-01-02 21:45:02 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-01-03 12:52:14 +1030 |
commit | f8db4612c51d9980131268a1be06654846d9c8de (patch) | |
tree | e97f79636e3162635f9823fe8710bb8104f0c68f | |
parent | Automatic date update in version.in (diff) | |
download | binutils-gdb-f8db4612c51d9980131268a1be06654846d9c8de.tar.gz binutils-gdb-f8db4612c51d9980131268a1be06654846d9c8de.tar.bz2 binutils-gdb-f8db4612c51d9980131268a1be06654846d9c8de.zip |
PR27140, ppc32 segmentation fault in make_stub
This fixes a thinko in commit fa40fbe4849. st_other global entry bits
are relevant only for 64-bit ELFv2. PowerPC gold leaves local sym
vector of st_other bits as NULL for 32-bit, hence the segfault.
PR 27140
* powerpc.cc (Target_powerpc::Branch_info::make_stub): Only access
object->st_other() when 64-bit.
(Stub_table::add_long_branch_entry): Ignore "other" when 32-bit.
(cherry picked from commit e3b53295d59d2e78292eaae4500243dd9e007ae4)
-rw-r--r-- | gold/ChangeLog | 7 | ||||
-rw-r--r-- | gold/powerpc.cc | 10 |
2 files changed, 13 insertions, 4 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 8b274ddd040..ea4927330e2 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,10 @@ +2021-01-03 Alan Modra <amodra@gmail.com> + + PR 27140 + * powerpc.cc (Target_powerpc::Branch_info::make_stub): Only access + object->st_other() when 64-bit. + (Stub_table::add_long_branch_entry): Ignore "other" when 32-bit. + 2020-11-17 Alan Modra <amodra@gmail.com> * powerpc.cc (Target_powerpc::no_tprel_opt_): Rename from tprel_opt_. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index fd4371efa47..1cc2478941f 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -3536,7 +3536,7 @@ Target_powerpc<size, big_endian>::Branch_info::make_stub( from += (this->object_->output_section(this->shndx_)->address() + this->offset_); Address to; - unsigned int other; + unsigned int other = 0; if (gsym != NULL) { switch (gsym->source()) @@ -3564,7 +3564,8 @@ Target_powerpc<size, big_endian>::Branch_info::make_stub( to = symtab->compute_final_value<size>(gsym, &status); if (status != Symbol_table::CFVS_OK) return true; - other = gsym->nonvis() >> 3; + if (size == 64) + other = gsym->nonvis() >> 3; } else { @@ -3581,7 +3582,8 @@ Target_powerpc<size, big_endian>::Branch_info::make_stub( || !symval.has_output_value()) return true; to = symval.value(this->object_, 0); - other = this->object_->st_other(this->r_sym_) >> 5; + if (size == 64) + other = this->object_->st_other(this->r_sym_) >> 5; } if (!(size == 32 && this->r_type_ == elfcpp::R_PPC_PLTREL24)) to += this->addend_; @@ -5303,7 +5305,7 @@ Stub_table<size, big_endian>::add_long_branch_entry( this->need_resize_ = true; p.first->second.toc_ = true; } - if (p.first->second.other_ == 0) + if (size == 64 && p.first->second.other_ == 0) p.first->second.other_ = other; gold_assert(save_res == p.first->second.save_res_); if (p.second || (this->resizing_ && !p.first->second.iter_)) |