This is the mail archive of the binutils@sources.redhat.com 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: ld: can not edit toc Invalid operation


On Sun, Feb 13, 2005 at 09:58:21AM +0100, Olaf Hering wrote:
>  On Sun, Feb 13, Alan Modra wrote:
> > > /home/abuild/binhead/bin/ld: can not edit toc Invalid operation
> > 
> > This is the real error.  The segfault is a consequence of
> > ppc64elf.em:ppc_before_allocation not calling the elf32.em
> > before_allocation function.  I guess I should make this a fatal
> > error..
> > 
> > Can you find out why ppc64_elf_edit_toc is returning FALSE?
> 
> _bfd_elf_link_read_relocs() returns NULL, line 7018

Silly me.  It's quite possible to have a toc section that has no
relocs.

	* elf64-ppc.c (ppc64_elf_edit_toc): Skip toc if size is zero.
	Skip toc reloc adjust if reloc_count is zero.

This tidies up the error situation.  I chose to leave most of the errors
non-fatal, which means we need to continue on with normal processing in
these functions rather than just returning.

	* emultempl/ppc64elf.em (ppc_create_output_section_statements): Make
	an error creating fake bfd fatal.
	(ppc_before_allocation): Continue on after errors.
	(gld${EMULATION_NAME}_finish): Likewise.

Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.191
diff -u -p -r1.191 elf64-ppc.c
--- bfd/elf64-ppc.c	11 Feb 2005 14:18:15 -0000	1.191
+++ bfd/elf64-ppc.c	13 Feb 2005 12:27:46 -0000
@@ -6782,13 +6782,14 @@ ppc64_elf_edit_toc (bfd *obfd ATTRIBUTE_
       Elf_Internal_Shdr *symtab_hdr;
       Elf_Internal_Sym *local_syms;
       struct elf_link_hash_entry **sym_hashes;
-      Elf_Internal_Rela *relstart, *rel, *wrel;
+      Elf_Internal_Rela *relstart, *rel;
       unsigned long *skip, *drop;
       unsigned char *used;
       unsigned char *keep, last, some_unused;
 
       toc = bfd_get_section_by_name (ibfd, ".toc");
       if (toc == NULL
+	  || toc->size == 0
 	  || toc->sec_info_type == ELF_INFO_TYPE_JUST_SYMS
 	  || elf_discarded_section (toc))
 	continue;
@@ -7033,25 +7034,32 @@ ppc64_elf_edit_toc (bfd *obfd ATTRIBUTE_
 	  toc->rawsize = toc->size;
 	  toc->size = src - contents - off;
 
-	  /* Read toc relocs.  */
-	  relstart = _bfd_elf_link_read_relocs (ibfd, toc, NULL, NULL, TRUE);
-	  if (relstart == NULL)
-	    goto error_ret;
+	  if (toc->reloc_count != 0)
+	    {
+	      Elf_Internal_Rela *wrel;
+	      bfd_size_type sz;
 
-	  /* Remove unused toc relocs, and adjust those we keep.  */
-	  wrel = relstart;
-	  for (rel = relstart; rel < relstart + toc->reloc_count; ++rel)
-	    if (skip[rel->r_offset >> 3] != (unsigned long) -1)
-	      {
-		wrel->r_offset = rel->r_offset - skip[rel->r_offset >> 3];
-		wrel->r_info = rel->r_info;
-		wrel->r_addend = rel->r_addend;
-		++wrel;
-	      }
-	  toc->reloc_count = wrel - relstart;
-	  elf_section_data (toc)->rel_hdr.sh_size
-	    = toc->reloc_count * elf_section_data (toc)->rel_hdr.sh_entsize;
-	  BFD_ASSERT (elf_section_data (toc)->rel_hdr2 == NULL);
+	      /* 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)
+		if (skip[rel->r_offset >> 3] != (unsigned long) -1)
+		  {
+		    wrel->r_offset = rel->r_offset - skip[rel->r_offset >> 3];
+		    wrel->r_info = rel->r_info;
+		    wrel->r_addend = rel->r_addend;
+		    ++wrel;
+		  }
+	      toc->reloc_count = wrel - relstart;
+	      sz = elf_section_data (toc)->rel_hdr.sh_entsize;
+	      elf_section_data (toc)->rel_hdr.sh_size = toc->reloc_count * sz;
+	      BFD_ASSERT (elf_section_data (toc)->rel_hdr2 == NULL);
+	    }
 
 	  /* Adjust addends for relocs against the toc section sym.  */
 	  for (sec = ibfd->sections; sec != NULL; sec = sec->next)
Index: ld/emultempl/ppc64elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc64elf.em,v
retrieving revision 1.37
diff -u -p -r1.37 ppc64elf.em
--- ld/emultempl/ppc64elf.em	10 Feb 2005 09:15:05 -0000	1.37
+++ ld/emultempl/ppc64elf.em	13 Feb 2005 12:27:47 -0000
@@ -88,7 +88,7 @@ ppc_create_output_section_statements (vo
 			     bfd_get_arch (output_bfd),
 			     bfd_get_mach (output_bfd)))
     {
-      einfo ("%X%P: can not create BFD %E\n");
+      einfo ("%F%P: can not create BFD %E\n");
       return;
     }
 
@@ -104,10 +104,7 @@ ppc_before_allocation (void)
     {
       if (!no_opd_opt
 	  && !ppc64_elf_edit_opd (output_bfd, &link_info, non_overlapping_opd))
-	{
-	  einfo ("%X%P: can not edit %s %E\n", "opd");
-	  return;
-	}
+	einfo ("%X%P: can not edit %s %E\n", "opd");
 
       if (ppc64_elf_tls_setup (output_bfd, &link_info) && !no_tls_opt)
 	{
@@ -117,10 +114,7 @@ ppc_before_allocation (void)
 			      &stat_ptr->head, 0, 0, NULL, TRUE);
 
 	  if (!ppc64_elf_tls_optimize (output_bfd, &link_info))
-	    {
-	      einfo ("%X%P: TLS problem %E\n");
-	      return;
-	    }
+	    einfo ("%X%P: TLS problem %E\n");
 
 	  /* We must not cache anything from the preliminary sizing.  */
 	  elf_tdata (output_bfd)->program_header_size = 0;
@@ -130,10 +124,7 @@ ppc_before_allocation (void)
       if (!no_toc_opt
 	  && !link_info.relocatable
 	  && !ppc64_elf_edit_toc (output_bfd, &link_info))
-	{
-	  einfo ("%X%P: can not edit %s %E\n", "toc");
-	  return;
-	}
+	einfo ("%X%P: can not edit %s %E\n", "toc");
     }
 
   gld${EMULATION_NAME}_before_allocation ();
@@ -343,14 +334,10 @@ gld${EMULATION_NAME}_finish (void)
     {
       int ret = ppc64_elf_setup_section_lists (output_bfd, &link_info,
 					       no_multi_toc);
-      if (ret != 0)
+      if (ret < 0)
+	einfo ("%X%P: can not size stub section: %E\n");
+      else if (ret > 0)
 	{
-	  if (ret < 0)
-	    {
-	      einfo ("%X%P: can not size stub section: %E\n");
-	      return;
-	    }
-
 	  toc_section = bfd_get_section_by_name (output_bfd, ".got");
 	  if (toc_section != NULL)
 	    lang_for_each_statement (build_toc_list);
@@ -365,10 +352,7 @@ gld${EMULATION_NAME}_finish (void)
 				     group_size,
 				     &ppc_add_stub_section,
 				     &ppc_layout_sections_again))
-	    {
-	      einfo ("%X%P: can not size stub section: %E\n");
-	      return;
-	    }
+	    einfo ("%X%P: can not size stub section: %E\n");
 	}
     }
 

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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