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: PowerPC64 toc edit segfault


This fixes two segfaults in ppc64_elf_edit_toc, found when simply
running the binutils testsuite using an -mcmodel=medium ppc64
compiler.  Embarrassing.  My binutils testsuite runs weren't using a
new bleeding edge compiler as I thought, but the old 4.4.1 system
compiler.

Also fixes a number of ld tests that fail/xpass with a new ppc64 gcc.
I'm disabling the non-PIC visibility tests entirely for
powerpc*-linux.  See the comment for why.

Applied mainline and 2.21 branch.

bfd/
	* elf64-ppc.c (ppc64_elf_edit_toc): Don't free toc relocs until
	we are done.  When optimising large toc, check that a global
	symbol on a toc reloc is defined in a kept section.
ld/testsuite/
	* ld-elfvsb/elfvsb.exp: Don't run any non-PIC tests on powerpc*-linux.
	* ld-gc/gc.exp: Ensure powerpc64 test continues to fail.
	* ld-srec/srec.exp: Don't edit toc on powerpc64.

Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.341
diff -u -p -r1.341 elf64-ppc.c
--- bfd/elf64-ppc.c	8 Feb 2011 02:54:42 -0000	1.341
+++ bfd/elf64-ppc.c	9 Feb 2011 06:52:20 -0000
@@ -7907,7 +7908,7 @@ ppc64_elf_edit_toc (struct bfd_link_info
       asection *toc, *sec;
       Elf_Internal_Shdr *symtab_hdr;
       Elf_Internal_Sym *local_syms;
-      Elf_Internal_Rela *relstart, *rel;
+      Elf_Internal_Rela *relstart, *rel, *toc_relocs;
       unsigned long *skip, *drop;
       unsigned char *used;
       unsigned char *keep, last, some_unused;
@@ -7922,6 +7923,7 @@ ppc64_elf_edit_toc (struct bfd_link_info
 	  || elf_discarded_section (toc))
 	continue;
 
+      toc_relocs = NULL;
       local_syms = NULL;
       symtab_hdr = &elf_symtab_hdr (ibfd);
 
@@ -8017,12 +8019,12 @@ ppc64_elf_edit_toc (struct bfd_link_info
 	  && toc->reloc_count != 0)
 	{
 	  /* Read toc relocs.  */
-	  relstart = _bfd_elf_link_read_relocs (ibfd, toc, NULL, NULL,
-						info->keep_memory);
-	  if (relstart == NULL)
+	  toc_relocs = _bfd_elf_link_read_relocs (ibfd, toc, NULL, NULL,
+						  info->keep_memory);
+	  if (toc_relocs == NULL)
 	    goto error_ret;
 
-	  for (rel = relstart; rel < relstart + toc->reloc_count; ++rel)
+	  for (rel = toc_relocs; rel < toc_relocs + toc->reloc_count; ++rel)
 	    {
 	      enum elf_ppc64_reloc_type r_type;
 	      unsigned long r_symndx;
@@ -8040,6 +8042,10 @@ ppc64_elf_edit_toc (struct bfd_link_info
 			      r_symndx, ibfd))
 		goto error_ret;
 
+	      if (sym_sec == NULL
+		  || elf_discarded_section (sym_sec))
+		continue;
+
 	      if (!SYMBOL_CALLS_LOCAL (info, h))
 		continue;
 
@@ -8078,11 +8084,8 @@ ppc64_elf_edit_toc (struct bfd_link_info
 		}
 
 	      skip[rel->r_offset >> 3]
-		|= can_optimize | ((rel - relstart) << 2);
+		|= can_optimize | ((rel - toc_relocs) << 2);
 	    }
-
-	  if (elf_section_data (toc)->relocs != relstart)
-	    free (relstart);
 	}
 
       if (skip == NULL)
@@ -8099,6 +8102,9 @@ ppc64_elf_edit_toc (struct bfd_link_info
 	      && relstart != NULL
 	      && elf_section_data (sec)->relocs != relstart)
 	    free (relstart);
+	  if (toc_relocs != NULL
+	      && elf_section_data (toc)->relocs != toc_relocs)
+	    free (toc_relocs);
 	  if (skip != NULL)
 	    free (skip);
 	  return FALSE;
@@ -8338,7 +8344,7 @@ ppc64_elf_edit_toc (struct bfd_link_info
 		  else if ((skip[val >> 3] & can_optimize) != 0)
 		    {
 		      Elf_Internal_Rela *tocrel
-			= elf_section_data (toc)->relocs + (skip[val >> 3] >> 2);
+			= toc_relocs + (skip[val >> 3] >> 2);
 		      unsigned long tsym = ELF64_R_SYM (tocrel->r_info);
 
 		      switch (r_type)
@@ -8418,15 +8424,9 @@ ppc64_elf_edit_toc (struct bfd_link_info
 	      Elf_Internal_Rela *wrel;
 	      bfd_size_type sz;
 
-	      /* Read toc relocs.  */
-	      relstart = _bfd_elf_link_read_relocs (ibfd, toc, NULL, NULL,
-						    TRUE);
-	      if (relstart == NULL)
-		goto error_ret;
-
 	      /* Remove unused toc relocs, and adjust those we keep.  */
-	      wrel = relstart;
-	      for (rel = relstart; rel < relstart + toc->reloc_count; ++rel)
+	      wrel = toc_relocs;
+	      for (rel = toc_relocs; rel < toc_relocs + toc->reloc_count; ++rel)
 		if ((skip[rel->r_offset >> 3]
 		     & (ref_from_discarded | can_optimize)) == 0)
 		  {
@@ -8439,12 +8439,15 @@ ppc64_elf_edit_toc (struct bfd_link_info
 					    &local_syms, NULL, NULL))
 		  goto error_ret;
 
-	      toc->reloc_count = wrel - relstart;
+	      elf_section_data (toc)->relocs = toc_relocs;
+	      toc->reloc_count = wrel - toc_relocs;
 	      rel_hdr = _bfd_elf_single_rel_hdr (toc);
 	      sz = rel_hdr->sh_entsize;
 	      rel_hdr->sh_size = toc->reloc_count * sz;
 	    }
 	}
+      else if (elf_section_data (toc)->relocs != toc_relocs)
+	free (toc_relocs);
 
       if (local_syms != NULL
 	  && symtab_hdr->contents != (unsigned char *) local_syms)
Index: ld/testsuite/ld-elfvsb/elfvsb.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-elfvsb/elfvsb.exp,v
retrieving revision 1.34
diff -u -p -r1.34 elfvsb.exp
--- ld/testsuite/ld-elfvsb/elfvsb.exp	8 Nov 2010 06:43:37 -0000	1.34
+++ ld/testsuite/ld-elfvsb/elfvsb.exp	9 Feb 2011 07:54:30 -0000
@@ -249,6 +249,14 @@ proc visibility_run {visibility} {
 	set VSBCFLAG ""
     }}}}}}}}}
 
+    if { [istarget powerpc*-*-linux*] } {
+	# Testing non-PIC libraries is a waste of effort on any target.
+	# If you don't pass -fpic or -fPIC to gcc, gcc will assume quite
+	# reasonably that you are not compiling for a shared library.
+	# It can then make optimisations that result in shared library
+	# functions and variables not being overridable.  Newer versions
+	# of gcc are more likely to do this.
+    } else {
     # Compile the main program.
     if ![ld_compile "$CC -g $CFLAGS $SHCFLAG $VSBCFLAG" $srcdir/$subdir/main.c $tmpdir/mainnp.o] {
 	unresolved "visibility ($visibility) (non PIC)"
@@ -369,8 +377,11 @@ proc visibility_run {visibility} {
 		visibility_test $visibility vp "visibility ($visibility)" mainnp.o sh1p.o sh2p.o elfvsb
 	    } }
 	}
-    }
+    }}
 
+    if { [istarget powerpc*-*-linux*] } {
+	# Don't bother.
+    } else {
     # Now do the same tests again, but this time compile main.c PIC.
     if ![ld_compile "$CC -g $CFLAGS $SHCFLAG $VSBCFLAG -DSHARED $picflag" $srcdir/$subdir/main.c $tmpdir/mainp.o] {
 	unresolved "visibility ($visibility) (PIC main, non PIC so)"
@@ -433,7 +444,7 @@ proc visibility_run {visibility} {
 	} else {
 	    unresolved "visibility ($visibility) (PIC main)"
 	}
-    }
+    }}
 }
 
 if [istarget mips*-*-*] {
Index: ld/testsuite/ld-gc/gc.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-gc/gc.exp,v
retrieving revision 1.10
diff -u -p -r1.10 gc.exp
--- ld/testsuite/ld-gc/gc.exp	8 Nov 2010 06:43:37 -0000	1.10
+++ ld/testsuite/ld-gc/gc.exp	9 Feb 2011 07:54:30 -0000
@@ -27,6 +27,11 @@ if ![check_gc_sections_available] {
 set cflags "-ffunction-sections -fdata-sections"
 set objfile "tmpdir/gc.o"
 
+if [istarget powerpc64*-*-*] {
+    # otherwise with -mcmodel=medium gcc we get XPASSes.
+    set cflags "$cflags -mminimal-toc"
+}
+
 if { [is_remote host] || [which $CC] != 0 } {
     ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/gc.c $objfile
 }
Index: ld/testsuite/ld-srec/srec.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-srec/srec.exp,v
retrieving revision 1.33
diff -u -p -r1.33 srec.exp
--- ld/testsuite/ld-srec/srec.exp	1 Oct 2009 23:29:28 -0000	1.33
+++ ld/testsuite/ld-srec/srec.exp	9 Feb 2011 07:54:31 -0000
@@ -271,6 +271,10 @@ proc run_srec_test { test objs } {
 	set flags "$flags -no-relax"
     }
 
+    if [istarget powerpc64*-*-*] {
+	set flags "$flags --no-toc-optimize"
+    }
+
     if { ![ld_simple_link $ld tmpdir/sr1 "$flags $objs"] \
 	 || ![ld_simple_link $ld tmpdir/sr2.sr "$flags --oformat srec $objs"] } {
 	fail $test

-- 
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]