[binutils-gdb] PR27140, ppc32 segmentation fault in make_stub

Alan Modra amodra@sourceware.org
Sun Jan 3 02:21:47 GMT 2021


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e3b53295d59d2e78292eaae4500243dd9e007ae4

commit e3b53295d59d2e78292eaae4500243dd9e007ae4
Author: Alan Modra <amodra@gmail.com>
Date:   Sat Jan 2 21:45:02 2021 +1030

    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.

Diff:
---
 gold/ChangeLog  |  7 +++++++
 gold/powerpc.cc | 10 ++++++----
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index 4b7b481f367..11771664395 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.
+
 2021-01-01  Nicolas Boulenguez  <nicolas@debian.org>
 
 	* tilegx.cc: Correct comment spelling.
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index eca9741a90d..e2966ef096b 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_))


More information about the Binutils-cvs mailing list