This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
RFC: Stop objcopy --only-keep-debug from producing bogus output
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sources dot redhat dot com
- Cc: jakub at redhat dot com, drepper at redhat dot com
- Date: Thu, 08 Jan 2004 17:35:19 +0000
- Subject: RFC: Stop objcopy --only-keep-debug from producing bogus output
- References: <m3r7zbmr3b.fsf@redhat.com><20040108123934.GC6413@sunsite.ms.mff.cuni.cz><m3hdz6xy3c.fsf@redhat.com><20040108155340.GE24876@devserv.devel.redhat.com>
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
{