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]

Re: Objcopy (bfd) segfault


Hi David,

> In converting an elf (32-bit, linux, i386) object file (generated by 
> egcs-2.91.66) to a.out, I got a core dump using the following
> command line: 
> 
>   objcopy -R .note -R .rodata -R .comment -O a.out-i386 kernel.o
> 
> (Binutils version 2.11.  Same error if I use -O a.out-i386-linux.)
> 
> Despite the filename, there's nothing "tricky" going on in the
> object file that should of itself produce an error.

Actually there is something slightly tricky going on.  You are
removing the .rodata section and the object file contains relocs that 
reference symbols that are defined in this section.  This is what is
causing the core dump.  Objcopy is trying to emit the relocs, and the
output section for the relocs cannot be found.

What objcopy should have done, of course, is to remove these relocs
before trying to generate the output file, and the patch below does
this.

One problem though - you will end up with an object file which has
missing relocs, so it will probably not work.  But that is the price
you pay for using the -R option. 

Please let me know if this patch fixes the problem for you.  (I had a
slightly different test environment) and if it does, I will apply it
to the sources.

Cheers
        Nick

2001-06-27  Nick Clifton  <nickc@cambridge.redhat.com>

	* objcopy.c (copy_section): Strip relocs against symbols whoes
        output sections have been removed.
        (mark_symbols_used_in_relocations): Do not mark symbols whoes
        output sections have been removed.

Index: binutils/objcopy.c
===================================================================
RCS file: /cvs/src/src/binutils/objcopy.c,v
retrieving revision 1.20
diff -p -w -r1.20 objcopy.c
*** objcopy.c	2001/06/24 16:27:00	1.20
--- objcopy.c	2001/06/27 17:37:18
*************** copy_section (ibfd, isection, obfdarg)
*** 1616,1621 ****
--- 1616,1648 ----
  	  free (relpp);
  	  relpp = temp_relpp;
  	}
+       else if (sections_removed)
+ 	{
+ 	  /* Remove relocations which are against symbols
+ 	     in sections that have been removed, unless
+ 	     the symbols are going to be preserved.  */
+ 	  arelent ** temp_relpp;
+ 	  asymbol *  sym;
+ 	  long temp_relcount = 0;
+ 	  long i;
+ 
+ 	  temp_relpp = (arelent **) xmalloc (relsize);
+ 	  for (i = 0; i < relcount; i++)
+ 	    {
+ 	      sym = *relpp [i]->sym_ptr_ptr;
+ 
+ 	      /* FIXME: Should we warn about deleted relocs ?  */
+ 	      if (is_specified_symbol (bfd_asymbol_name (sym),
+ 				       keep_specific_list)
+ 		  || bfd_get_output_section (sym) != NULL)
+ 		temp_relpp [temp_relcount++] = relpp [i];
+ 	    }
+ 
+ 	  relcount = temp_relcount;
+ 	  free (relpp);
+ 	  relpp = temp_relpp;
+ 	}
+ 
        bfd_set_reloc (obfd, osection,
  		     (relcount == 0 ? (arelent **) NULL : relpp), relcount);
      }
*************** mark_symbols_used_in_relocations (ibfd, 
*** 1750,1763 ****
    if (relcount < 0)
      bfd_fatal (bfd_get_filename (ibfd));
  
!   /* Examine each symbol used in a relocation.  If it's not one of the
!      special bfd section symbols, then mark it with BSF_KEEP.  */
    for (i = 0; i < relcount; i++)
      {
!       if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
! 	  && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
! 	  && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
! 	(*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
      }
  
    if (relpp != NULL)
--- 1774,1795 ----
    if (relcount < 0)
      bfd_fatal (bfd_get_filename (ibfd));
  
!   /* Examine each symbol used in a relocation.  */
    for (i = 0; i < relcount; i++)
      {
!       asymbol * sym = * relpp[i]->sym_ptr_ptr;
!       
!       /* If the symbol's output section does not exist (because it
! 	 has been removed with -R) then do not keep the symbol.  */
!       if (bfd_get_output_section (sym) == NULL)
! 	continue;
!       
!       /* If the symbols is not one of the special bfd
! 	 section symbols, then mark it with BSF_KEEP.  */
!       if (sym != bfd_com_section_ptr->symbol
! 	  && sym != bfd_abs_section_ptr->symbol
! 	  && sym != bfd_und_section_ptr->symbol)
! 	sym->flags |= BSF_KEEP;
      }
  
    if (relpp != NULL)


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