aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2021-01-02 21:45:02 +1030
committerAndreas K. Hüttel <dilfridge@gentoo.org>2021-01-23 20:26:28 +0200
commit9102f34ed025f964b8f2349ec1eb464a96cd9ce4 (patch)
treec6778777022c2424fb66de041b37179d9a3ecee9
parentPR27128, nm -P portable output format regression (diff)
downloadbinutils-gdb-9102f34ed025f964b8f2349ec1eb464a96cd9ce4.tar.gz
binutils-gdb-9102f34ed025f964b8f2349ec1eb464a96cd9ce4.tar.bz2
binutils-gdb-9102f34ed025f964b8f2349ec1eb464a96cd9ce4.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) (cherry picked from commit f8db4612c51d9980131268a1be06654846d9c8de)
-rw-r--r--gold/ChangeLog7
-rw-r--r--gold/powerpc.cc10
2 files changed, 13 insertions, 4 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 8b274ddd04..ea4927330e 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 fd4371efa4..1cc2478941 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_))