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]

RFC: Stop objcopy --only-keep-debug from producing bogus output


Hi Guys,

  I am looking for comments on the following patch.  It fixes a
  problem with the --only-keep-debug switch for objcopy, in that if
  the input file did not contain any debug information a bogus,
  basically empty ELF output file would be created.

  In fixing this, I came up with a patch that changes the behaviour of
  objcopy and strip slightly, which is why I am looking for comments.
  With the patch applied, if there is some kind of problem copying the
  input to the output, no output file will be produced.  This is
  different from before, where the output file would still be created,
  even if there were (non-fatal) problems.

Cheers
        Nick

binutils/ChangeLog        
2004-01-08  Nick Clifton  <nickc@redhat.com>

	* objcopy.c (copy_object): Make the function boolean, returning
	FALSE upon failure.
        (copy_archive): Handle the return value from copy_object.
        (copy_file): Likewise.

Index: binutils/objcopy.c
===================================================================
RCS file: /cvs/src/src/binutils/objcopy.c,v
retrieving revision 1.62
diff -c -3 -p -r1.62 objcopy.c
*** binutils/objcopy.c	2 Jan 2004 22:54:47 -0000	1.62
--- binutils/objcopy.c	8 Jan 2004 17:33:13 -0000
*************** add_redefine_syms_file (const char *file
*** 1084,1092 ****
    free (buf);
  }
  
! /* Copy object file IBFD onto OBFD.  */
  
! static void
  copy_object (bfd *ibfd, bfd *obfd)
  {
    bfd_vma start;
--- 1084,1093 ----
    free (buf);
  }
  
! /* Copy object file IBFD onto OBFD.
!    Trues TRUE upon success, FALSE otherwise.  */
  
! static bfd_boolean
  copy_object (bfd *ibfd, bfd *obfd)
  {
    bfd_vma start;
*************** copy_object (bfd *ibfd, bfd *obfd)
*** 1103,1115 ****
    if (ibfd->xvec->byteorder != obfd->xvec->byteorder
        && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
        && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
!     {
!       fatal (_("Unable to change endianness of input file(s)"));
!       return;
!     }
  
    if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
!     RETURN_NONFATAL (bfd_get_filename (obfd));
  
    if (verbose)
      printf (_("copy from %s(%s) to %s(%s)\n"),
--- 1104,1116 ----
    if (ibfd->xvec->byteorder != obfd->xvec->byteorder
        && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
        && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
!     fatal (_("Unable to change endianness of input file(s)"));
  
    if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
!     {
!       bfd_nonfatal (bfd_get_filename (obfd));
!       return FALSE;
!     }
  
    if (verbose)
      printf (_("copy from %s(%s) to %s(%s)\n"),
*************** copy_object (bfd *ibfd, bfd *obfd)
*** 1135,1141 ****
  
        if (!bfd_set_start_address (obfd, start)
  	  || !bfd_set_file_flags (obfd, flags))
! 	RETURN_NONFATAL (bfd_get_filename (ibfd));
      }
  
    /* Copy architecture of input file to output file.  */
--- 1136,1145 ----
  
        if (!bfd_set_start_address (obfd, start)
  	  || !bfd_set_file_flags (obfd, flags))
! 	{
! 	  bfd_nonfatal (bfd_get_filename (ibfd));
! 	  return FALSE;
! 	}
      }
  
    /* Copy architecture of input file to output file.  */
*************** copy_object (bfd *ibfd, bfd *obfd)
*** 1153,1165 ****
  	  non_fatal (_("Warning: Output file cannot represent architecture %s"),
  		     bfd_printable_arch_mach (bfd_get_arch (ibfd),
  					      bfd_get_mach (ibfd)));
! 	  status = 1;
! 	  return;
  	}
      }
  
    if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
!     RETURN_NONFATAL (bfd_get_filename (ibfd));
  
    if (isympp)
      free (isympp);
--- 1157,1171 ----
  	  non_fatal (_("Warning: Output file cannot represent architecture %s"),
  		     bfd_printable_arch_mach (bfd_get_arch (ibfd),
  					      bfd_get_mach (ibfd)));
! 	  return FALSE;
  	}
      }
  
    if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
!     {
!       bfd_nonfatal (bfd_get_filename (ibfd));
!       return FALSE;
!     }
  
    if (isympp)
      free (isympp);
*************** copy_object (bfd *ibfd, bfd *obfd)
*** 1185,1196 ****
  	    {
  	      non_fatal (_("can't create section `%s': %s"),
  		       padd->name, bfd_errmsg (bfd_get_error ()));
! 	      status = 1;
! 	      return;
  	    }
  
  	  if (! bfd_set_section_size (obfd, padd->section, padd->size))
! 	    RETURN_NONFATAL (bfd_get_filename (obfd));
  
  	  pset = find_section_list (padd->name, FALSE);
  	  if (pset != NULL)
--- 1191,1204 ----
  	    {
  	      non_fatal (_("can't create section `%s': %s"),
  		       padd->name, bfd_errmsg (bfd_get_error ()));
! 	      return FALSE;
  	    }
  
  	  if (! bfd_set_section_size (obfd, padd->section, padd->size))
! 	    {
! 	      bfd_nonfatal (bfd_get_filename (obfd));
! 	      return FALSE;
! 	    }
  
  	  pset = find_section_list (padd->name, FALSE);
  	  if (pset != NULL)
*************** copy_object (bfd *ibfd, bfd *obfd)
*** 1202,1224 ****
  	    flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
  
  	  if (! bfd_set_section_flags (obfd, padd->section, flags))
! 	    RETURN_NONFATAL (bfd_get_filename (obfd));
  
  	  if (pset != NULL)
  	    {
  	      if (pset->change_vma != CHANGE_IGNORE)
  		if (! bfd_set_section_vma (obfd, padd->section,
  					   pset->vma_val))
! 		  RETURN_NONFATAL (bfd_get_filename (obfd));
  
  	      if (pset->change_lma != CHANGE_IGNORE)
  		{
  		  padd->section->lma = pset->lma_val;
! 		  
  		  if (! bfd_set_section_alignment
  		      (obfd, padd->section,
  		       bfd_section_alignment (obfd, padd->section)))
! 		    RETURN_NONFATAL (bfd_get_filename (obfd));
  		}
  	    }
  	}
--- 1210,1241 ----
  	    flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
  
  	  if (! bfd_set_section_flags (obfd, padd->section, flags))
! 	    {
! 	      bfd_nonfatal (bfd_get_filename (obfd));
! 	      return FALSE;
! 	    }
  
  	  if (pset != NULL)
  	    {
  	      if (pset->change_vma != CHANGE_IGNORE)
  		if (! bfd_set_section_vma (obfd, padd->section,
  					   pset->vma_val))
! 		  {
! 		    bfd_nonfatal (bfd_get_filename (obfd));
! 		    return FALSE;
! 		  }
  
  	      if (pset->change_lma != CHANGE_IGNORE)
  		{
  		  padd->section->lma = pset->lma_val;
! 
  		  if (! bfd_set_section_alignment
  		      (obfd, padd->section,
  		       bfd_section_alignment (obfd, padd->section)))
! 		    {
! 		      bfd_nonfatal (bfd_get_filename (obfd));
! 		      return FALSE;
! 		    }
  		}
  	    }
  	}
*************** copy_object (bfd *ibfd, bfd *obfd)
*** 1230,1236 ****
  	(obfd, gnu_debuglink_filename);
  
        if (gnu_debuglink_section == NULL)
! 	RETURN_NONFATAL (gnu_debuglink_filename);
      }
  
    if (gap_fill_set || pad_to_set)
--- 1247,1262 ----
  	(obfd, gnu_debuglink_filename);
  
        if (gnu_debuglink_section == NULL)
! 	{
! 	  bfd_nonfatal (gnu_debuglink_filename);
! 	  return FALSE;
! 	}
!     }
! 
!   if (bfd_count_sections (obfd) == 0)
!     {
!       non_fatal (_("there are no sections to be copied!"));
!       return FALSE;
      }
  
    if (gap_fill_set || pad_to_set)
*************** copy_object (bfd *ibfd, bfd *obfd)
*** 1320,1331 ****
    dhandle = NULL;
    symsize = bfd_get_symtab_upper_bound (ibfd);
    if (symsize < 0)
!     RETURN_NONFATAL (bfd_get_filename (ibfd));
  
    osympp = isympp = xmalloc (symsize);
    symcount = bfd_canonicalize_symtab (ibfd, isympp);
    if (symcount < 0)
!     RETURN_NONFATAL (bfd_get_filename (ibfd));
  
    if (convert_debugging)
      dhandle = read_debugging_info (ibfd, isympp, symcount);
--- 1346,1363 ----
    dhandle = NULL;
    symsize = bfd_get_symtab_upper_bound (ibfd);
    if (symsize < 0)
!     {
!       bfd_nonfatal (bfd_get_filename (ibfd));
!       return FALSE;
!     }
  
    osympp = isympp = xmalloc (symsize);
    symcount = bfd_canonicalize_symtab (ibfd, isympp);
    if (symcount < 0)
!     {
!       bfd_nonfatal (bfd_get_filename (ibfd));
!       return FALSE;
!     }
  
    if (convert_debugging)
      dhandle = read_debugging_info (ibfd, isympp, symcount);
*************** copy_object (bfd *ibfd, bfd *obfd)
*** 1370,1376 ****
        if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
  	{
  	  status = 1;
! 	  return;
  	}
      }
  
--- 1402,1408 ----
        if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
  	{
  	  status = 1;
! 	  return FALSE;
  	}
      }
  
*************** copy_object (bfd *ibfd, bfd *obfd)
*** 1387,1393 ****
  	{
  	  if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
  					  0, padd->size))
! 	    RETURN_NONFATAL (bfd_get_filename (obfd));
  	}
      }
  
--- 1419,1428 ----
  	{
  	  if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
  					  0, padd->size))
! 	    {
! 	      bfd_nonfatal (bfd_get_filename (obfd));
! 	      return FALSE;
! 	    }
  	}
      }
  
*************** copy_object (bfd *ibfd, bfd *obfd)
*** 1395,1401 ****
      {
        if (! bfd_fill_in_gnu_debuglink_section
  	  (obfd, gnu_debuglink_section, gnu_debuglink_filename))
! 	RETURN_NONFATAL (gnu_debuglink_filename);
      }
  
    if (gap_fill_set || pad_to_set)
--- 1430,1439 ----
      {
        if (! bfd_fill_in_gnu_debuglink_section
  	  (obfd, gnu_debuglink_section, gnu_debuglink_filename))
! 	{
! 	  bfd_nonfatal (gnu_debuglink_filename);
! 	  return FALSE;
! 	}
      }
  
    if (gap_fill_set || pad_to_set)
*************** copy_object (bfd *ibfd, bfd *obfd)
*** 1431,1437 ****
  
  		  if (! bfd_set_section_contents (obfd, osections[i], buf,
  						  off, now))
! 		    RETURN_NONFATAL (bfd_get_filename (obfd));
  
  		  left -= now;
  		  off += now;
--- 1469,1478 ----
  
  		  if (! bfd_set_section_contents (obfd, osections[i], buf,
  						  off, now))
! 		    {
! 		      bfd_nonfatal (bfd_get_filename (obfd));
! 		      return FALSE;
! 		    }
  
  		  left -= now;
  		  off += now;
*************** copy_object (bfd *ibfd, bfd *obfd)
*** 1454,1471 ****
        non_fatal (_("%s: error copying private BFD data: %s"),
  		 bfd_get_filename (obfd),
  		 bfd_errmsg (bfd_get_error ()));
!       status = 1;
!       return;
      }
  
    /* Switch to the alternate machine code.  We have to do this at the
       very end, because we only initialize the header when we create
       the first section.  */
!   if (use_alt_mach_code != 0)
!     {
!       if (!bfd_alt_mach_code (obfd, use_alt_mach_code))
! 	non_fatal (_("unknown alternate machine code, ignored"));
!     }
  }
  
  #undef MKDIR
--- 1495,1511 ----
        non_fatal (_("%s: error copying private BFD data: %s"),
  		 bfd_get_filename (obfd),
  		 bfd_errmsg (bfd_get_error ()));
!       return FALSE;
      }
  
    /* Switch to the alternate machine code.  We have to do this at the
       very end, because we only initialize the header when we create
       the first section.  */
!   if (use_alt_mach_code != 0
!       && ! bfd_alt_mach_code (obfd, use_alt_mach_code))
!     non_fatal (_("unknown alternate machine code, ignored"));
! 
!   return TRUE;
  }
  
  #undef MKDIR
*************** copy_archive (bfd *ibfd, bfd *obfd, cons
*** 1512,1517 ****
--- 1552,1558 ----
        bfd *last_element;
        struct stat buf;
        int stat_status = 0;
+       bfd_boolean delete = TRUE;
  
        /* Create an output file for this member.  */
        output_name = concat (dir, "/",
*************** copy_archive (bfd *ibfd, bfd *obfd, cons
*** 1553,1559 ****
  	RETURN_NONFATAL (output_name);
  
        if (bfd_check_format (this_element, bfd_object))
! 	copy_object (this_element, output_bfd);
  
        if (!bfd_close (output_bfd))
  	{
--- 1594,1600 ----
  	RETURN_NONFATAL (output_name);
  
        if (bfd_check_format (this_element, bfd_object))
! 	delete = ! copy_object (this_element, output_bfd);
  
        if (!bfd_close (output_bfd))
  	{
*************** copy_archive (bfd *ibfd, bfd *obfd, cons
*** 1562,1583 ****
  	  status = 1;
  	}
  
!       if (preserve_dates && stat_status == 0)
! 	set_times (output_name, &buf);
  
!       /* Open the newly output file and attach to our list.  */
!       output_bfd = bfd_openr (output_name, output_target);
  
!       l->obfd = output_bfd;
  
!       *ptr = output_bfd;
!       ptr = &output_bfd->next;
  
!       last_element = this_element;
  
!       this_element = bfd_openr_next_archived_file (ibfd, last_element);
  
!       bfd_close (last_element);
      }
    *ptr = NULL;
  
--- 1603,1632 ----
  	  status = 1;
  	}
  
!       if (delete)
! 	{
! 	  unlink (output_name);
! 	  status = 1;
! 	}
!       else
! 	{
! 	  if (preserve_dates && stat_status == 0)
! 	    set_times (output_name, &buf);
  
! 	  /* Open the newly output file and attach to our list.  */
! 	  output_bfd = bfd_openr (output_name, output_target);
  
! 	  l->obfd = output_bfd;
  
! 	  *ptr = output_bfd;
! 	  ptr = &output_bfd->next;
  
! 	  last_element = this_element;
  
! 	  this_element = bfd_openr_next_archived_file (ibfd, last_element);
  
! 	  bfd_close (last_element);
! 	}
      }
    *ptr = NULL;
  
*************** copy_file (const char *input_filename, c
*** 1641,1647 ****
--- 1690,1698 ----
    else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
      {
        bfd *obfd;
+       bfd_boolean delete;
      do_copy:
+ 
        /* bfd_get_target does not return the correct value until
           bfd_check_format succeeds.  */
        if (output_target == NULL)
*************** copy_file (const char *input_filename, c
*** 1651,1663 ****
        if (obfd == NULL)
  	RETURN_NONFATAL (output_filename);
  
!       copy_object (ibfd, obfd);
  
        if (!bfd_close (obfd))
  	RETURN_NONFATAL (output_filename);
  
        if (!bfd_close (ibfd))
  	RETURN_NONFATAL (input_filename);
      }
    else
      {
--- 1702,1720 ----
        if (obfd == NULL)
  	RETURN_NONFATAL (output_filename);
  
!       delete = ! copy_object (ibfd, obfd);
  
        if (!bfd_close (obfd))
  	RETURN_NONFATAL (output_filename);
  
        if (!bfd_close (ibfd))
  	RETURN_NONFATAL (input_filename);
+ 
+       if (delete)
+ 	{
+ 	  unlink (output_filename);
+ 	  status = 1;
+ 	}
      }
    else
      {
        


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