[binutils-gdb] PR24355, segmentation fault in function called from ppc_finish_symbols

Alan Modra amodra@sourceware.org
Mon Mar 18 12:14:00 GMT 2019


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

commit 8cd1fe1bf525b59f4d07e5790d11d49eee7e8494
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Mar 18 21:38:36 2019 +1030

    PR24355, segmentation fault in function called from ppc_finish_symbols
    
    This one looks to be a bug going back to 2009, git commit e054468f6c
    "STT_GNU_IFUNC support for PowerPC".  That bug was carried over with
    git commit 49c09209d0 "Rearrange PLT reloc output on powerpc".
    
    If the refcount for an ifunc local sym plt entry was zero,
    ppc_elf_size_dynamic_sections would correctly set plt.offset to -1 but
    leave glink_offset uninitialized.  That leads to occasional segfaults
    (which can be made solid with MALLOC_PERTURB_=1 when using glibc).
    So, guard the write_glink_stub call with plt.offset != -1.  Also,
    remove the totally ineffective attempt at writing multiple-use glink
    stubs only once.
    
    	PR 24355
    	* elf32-ppc.c (ppc_finish_symbols): Don't call write_glink_stub
    	for local iplt syms with ent->plt.offset == -1.  Remove ineffective
    	attempt at writing glink stubs only once.

Diff:
---
 bfd/ChangeLog   | 7 +++++++
 bfd/elf32-ppc.c | 8 ++------
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f92b273..9cdd4fe 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2019-03-18  Alan Modra  <amodra@gmail.com>
+
+	PR 24355
+	* elf32-ppc.c (ppc_finish_symbols): Don't call write_glink_stub
+	for local iplt syms with ent->plt.offset == -1.  Remove ineffective
+	attempt at writing glink stubs only once.
+
 2019-03-16  Alan Modra  <amodra@gmail.com>
 
 	PR 24337
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 593ef47..6991e8d 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -9704,6 +9704,7 @@ ppc_finish_symbols (struct bfd_link_info *info)
 		bfd_byte *loc;
 		bfd_vma val;
 		Elf_Internal_Rela rela;
+		unsigned char *p;
 
 		if (!get_sym_h (NULL, &sym, &sym_sec, NULL, &local_syms,
 				lplt - local_plt, ibfd))
@@ -9748,14 +9749,9 @@ ppc_finish_symbols (struct bfd_link_info *info)
 		loc = relplt->contents + (relplt->reloc_count++
 					  * sizeof (Elf32_External_Rela));
 		bfd_elf32_swap_reloca_out (info->output_bfd, &rela, loc);
-	      }
-	    if ((ent->glink_offset & 1) == 0)
-	      {
-		unsigned char *p = ((unsigned char *) htab->glink->contents
-				    + ent->glink_offset);
 
+		p = (unsigned char *) htab->glink->contents + ent->glink_offset;
 		write_glink_stub (NULL, ent, htab->elf.iplt, p, info);
-		ent->glink_offset |= 1;
 	      }
 	  }



More information about the Binutils-cvs mailing list