This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PR11375, powerpc64 segfault in call_gmon_start


On Thu, Mar 18, 2010 at 01:08:48PM +1030, Alan Modra wrote:
> Sigh.  powerpc64-linux-ld is still not generating all the toc
> adjusting stubs for multiple toc binaries, even with new-style
> objects.  Investigating.

The bug was in using stub_group[sec->id] rather than finding code_sec
a little earlier and looking at stub_group[code_sec->id].  Since
finding code_sec can be expensive I decided we were better off just
looking up the stub hash entry.

	* elf64-ppc.c (ppc64_elf_relocate_section): Always look up a
	possible stub on branches.

Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.323
diff -u -p -r1.323 elf64-ppc.c
--- bfd/elf64-ppc.c	16 Mar 2010 00:40:36 -0000	1.323
+++ bfd/elf64-ppc.c	25 Mar 2010 09:16:06 -0000
@@ -11914,23 +11914,13 @@ ppc64_elf_relocate_section (bfd *output_
 	     linkage stubs needs to be followed by a nop, as the nop
 	     will be replaced with an instruction to restore the TOC
 	     base pointer.  */
-	  stub_entry = NULL;
 	  fdh = h;
 	  if (h != NULL
 	      && h->oh != NULL
 	      && h->oh->is_func_descriptor)
 	    fdh = ppc_follow_link (h->oh);
-	  if (((fdh != NULL
-		&& fdh->elf.plt.plist != NULL)
-	       || (sec != NULL
-		   && sec->output_section != NULL
-		   && sec->id <= htab->top_id
-		   && (htab->stub_group[sec->id].toc_off
-		       != htab->stub_group[input_section->id].toc_off))
-	       || (h == NULL
-		   && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC))
-	      && (stub_entry = ppc_get_stub_entry (input_section, sec, fdh,
-						   rel, htab)) != NULL
+	  stub_entry = ppc_get_stub_entry (input_section, sec, fdh, rel, htab);
+	  if (stub_entry != NULL
 	      && (stub_entry->stub_type == ppc_stub_plt_call
 		  || stub_entry->stub_type == ppc_stub_plt_branch_r2off
 		  || stub_entry->stub_type == ppc_stub_long_branch_r2off))
@@ -12015,7 +12005,9 @@ ppc64_elf_relocate_section (bfd *output_
 		unresolved_reloc = FALSE;
 	    }
 
-	  if (stub_entry == NULL
+	  if ((stub_entry == NULL
+	       || stub_entry->stub_type == ppc_stub_long_branch
+	       || stub_entry->stub_type == ppc_stub_plt_branch)
 	      && get_opd_info (sec) != NULL)
 	    {
 	      /* The branch destination is the value of the opd entry. */
@@ -12036,13 +12028,15 @@ ppc64_elf_relocate_section (bfd *output_
 		  + input_section->output_offset
 		  + input_section->output_section->vma);
 
-	  if (stub_entry == NULL
-	      && (relocation + addend - from + max_br_offset
-		  >= 2 * max_br_offset)
-	      && r_type != R_PPC64_ADDR14_BRTAKEN
-	      && r_type != R_PPC64_ADDR14_BRNTAKEN)
-	    stub_entry = ppc_get_stub_entry (input_section, sec, fdh, rel,
-					     htab);
+	  if (stub_entry != NULL
+	      && (stub_entry->stub_type == ppc_stub_long_branch
+		  || stub_entry->stub_type == ppc_stub_plt_branch)
+	      && (r_type == R_PPC64_ADDR14_BRTAKEN
+		  || r_type == R_PPC64_ADDR14_BRNTAKEN
+		  || (relocation + addend - from + max_br_offset
+		      < 2 * max_br_offset)))
+	    /* Don't use the stub if this branch is in range.  */
+	    stub_entry = NULL;
 
 	  if (stub_entry != NULL)
 	    {

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]