This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
\f
+#include "sysdep.h"
#include "bfd.h"
#include "progress.h"
-#include "bucomm.h"
#include "getopt.h"
#include "libiberty.h"
+#include "bucomm.h"
#include "budbg.h"
#include "filenames.h"
#include "fnmatch.h"
/* List of sections to be renamed. */
static section_rename *section_rename_list;
-#define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
+#define RETURN_NONFATAL(bfd) \
+ do { \
+ status = 1; bfd_nonfatal_message (NULL, bfd, NULL, NULL); return; \
+ } while (0)
static asymbol **isympp = NULL; /* Input symbols. */
static asymbol **osympp = NULL; /* Output symbols that survive stripping. */
/* True if --extract-symbol was passed on the command line. */
static bfd_boolean extract_symbol = FALSE;
+/* If `reverse_bytes' is nonzero, then reverse the order of every chunk
+ of <reverse_bytes> bytes within each output section. */
+static int reverse_bytes = 0;
+
+
/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
enum command_line_switch
{
OPTION_WRITABLE_TEXT,
OPTION_PURE,
OPTION_IMPURE,
- OPTION_EXTRACT_SYMBOL
+ OPTION_EXTRACT_SYMBOL,
+ OPTION_REVERSE_BYTES
};
/* Options to handle if running as "strip". */
{"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
{"remove-section", required_argument, 0, 'R'},
{"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
+ {"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES},
{"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
{"set-start", required_argument, 0, OPTION_SET_START},
{"srec-len", required_argument, 0, OPTION_SREC_LEN},
--rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
--change-leading-char Force output format's leading character style\n\
--remove-leading-char Remove leading character from global symbols\n\
+ --reverse-bytes=<num> Reverse <num> bytes at a time, in output sections with content\n\
--redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
--redefine-syms <file> --redefine-sym for all symbol pairs \n\
listed in <file>\n\
{
asymbol **from = isyms, **to = osyms;
long src_count = 0, dst_count = 0;
- int relocatable = (abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC))
- == HAS_RELOC;
+ int relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
for (; src_count < symcount; src_count++)
{
asymbol *sym = from[src_count];
flagword flags = sym->flags;
char *name = (char *) bfd_asymbol_name (sym);
- int keep;
+ bfd_boolean keep;
+ bfd_boolean used_in_reloc = FALSE;
bfd_boolean undefined;
bfd_boolean rem_leading_char;
bfd_boolean add_leading_char;
}
if (strip_symbols == STRIP_ALL)
- keep = 0;
+ keep = FALSE;
else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
|| ((flags & BSF_SECTION_SYM) != 0
&& ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
& BSF_KEEP) != 0))
- keep = 1;
+ {
+ keep = TRUE;
+ used_in_reloc = TRUE;
+ }
else if (relocatable /* Relocatable file. */
&& (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
- keep = 1;
+ keep = TRUE;
else if (bfd_decode_symclass (sym) == 'I')
/* Global symbols in $idata sections need to be retained
even if relocatable is FALSE. External users of the
library containing the $idata section may reference these
symbols. */
- keep = 1;
+ keep = TRUE;
else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
|| (flags & BSF_WEAK) != 0
|| undefined
else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym)))
/* COMDAT sections store special information in local
symbols, so we cannot risk stripping any of them. */
- keep = 1;
+ keep = TRUE;
else /* Local symbol. */
keep = (strip_symbols != STRIP_UNNEEDED
&& (discard_locals != LOCALS_ALL
|| ! bfd_is_local_label (abfd, sym))));
if (keep && is_specified_symbol (name, strip_specific_list))
- keep = 0;
+ {
+ /* There are multiple ways to set 'keep' above, but if it
+ was the relocatable symbol case, then that's an error. */
+ if (used_in_reloc)
+ {
+ non_fatal (_("not stripping symbol `%s' because it is named in a relocation"), name);
+ status = 1;
+ }
+ else
+ keep = FALSE;
+ }
+
if (keep
&& !(flags & BSF_KEEP)
&& is_specified_symbol (name, strip_unneeded_list))
- keep = 0;
+ keep = FALSE;
+
if (!keep
&& ((keep_file_symbols && (flags & BSF_FILE))
|| is_specified_symbol (name, keep_specific_list)))
- keep = 1;
+ keep = TRUE;
+
if (keep && is_strip_section (abfd, bfd_get_section (sym)))
- keep = 0;
+ keep = FALSE;
if (keep)
{
}
if (!undefined
- && (flags & BSF_LOCAL)
+ && (flags & BSF_LOCAL)
&& is_specified_symbol (name, globalize_specific_list))
{
sym->flags &= ~ BSF_LOCAL;
if (buf[0] != '\0')
redefine_list_append (filename, &buf[0], &buf[outsym_off]);
- lineno++;
+ lineno++;
len = 0;
outsym_off = 0;
if (c == EOF)
if (bfd_stat_arch_elt (ibfd, &buf) != 0)
{
- bfd_nonfatal (bfd_get_archive_filename (ibfd));
+ bfd_nonfatal_message (bfd_get_archive_filename (ibfd), NULL, NULL, NULL);
return FALSE;
}
if (bfd_bread (cbuf, (bfd_size_type) tocopy, ibfd)
!= (bfd_size_type) tocopy)
{
- bfd_nonfatal (bfd_get_archive_filename (ibfd));
+ bfd_nonfatal_message (bfd_get_archive_filename (ibfd),
+ NULL, NULL, NULL);
free (cbuf);
return FALSE;
}
if (bfd_bwrite (cbuf, (bfd_size_type) tocopy, obfd)
!= (bfd_size_type) tocopy)
{
- bfd_nonfatal (bfd_get_filename (obfd));
+ bfd_nonfatal_message (NULL, obfd, NULL, NULL);
free (cbuf);
return FALSE;
}
if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
{
- bfd_nonfatal (bfd_get_filename (obfd));
+ bfd_nonfatal_message (NULL, obfd, NULL, NULL);
return FALSE;
}
if (!bfd_set_start_address (obfd, start)
|| !bfd_set_file_flags (obfd, flags))
{
- bfd_nonfatal (bfd_get_archive_filename (ibfd));
+ bfd_nonfatal_message (bfd_get_archive_filename (ibfd),
+ NULL, NULL, NULL);
return FALSE;
}
}
if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
{
- bfd_nonfatal (bfd_get_archive_filename (ibfd));
+ bfd_nonfatal_message (bfd_get_archive_filename (ibfd), NULL, NULL, NULL);
return FALSE;
}
symsize = bfd_get_symtab_upper_bound (ibfd);
if (symsize < 0)
{
- bfd_nonfatal (bfd_get_archive_filename (ibfd));
+ bfd_nonfatal_message (bfd_get_archive_filename (ibfd), NULL, NULL, NULL);
return FALSE;
}
symcount = bfd_canonicalize_symtab (ibfd, isympp);
if (symcount < 0)
{
- bfd_nonfatal (bfd_get_filename (ibfd));
+ bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
return FALSE;
}
error codes, so check for the most likely user error first. */
if (bfd_get_section_by_name (obfd, padd->name))
{
- non_fatal (_("can't add section '%s' - it already exists!"), padd->name);
+ bfd_nonfatal_message (NULL, obfd, NULL,
+ _("can't add section '%s'"), padd->name);
return FALSE;
}
else
padd->section = bfd_make_section_with_flags (obfd, padd->name, flags);
if (padd->section == NULL)
{
- non_fatal (_("can't create section `%s': %s"),
- padd->name, bfd_errmsg (bfd_get_error ()));
+ bfd_nonfatal_message (NULL, obfd, NULL,
+ _("can't create section `%s'"),
+ padd->name);
return FALSE;
}
}
if (! bfd_set_section_size (obfd, padd->section, padd->size))
{
- bfd_nonfatal (bfd_get_filename (obfd));
+ bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
return FALSE;
}
if (! bfd_set_section_vma (obfd, padd->section,
pset->vma_val))
{
- bfd_nonfatal (bfd_get_filename (obfd));
+ bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
return FALSE;
}
(obfd, padd->section,
bfd_section_alignment (obfd, padd->section)))
{
- bfd_nonfatal (bfd_get_filename (obfd));
+ bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
return FALSE;
}
}
if (gnu_debuglink_section == NULL)
{
- bfd_nonfatal (gnu_debuglink_filename);
+ bfd_nonfatal_message (NULL, obfd, NULL,
+ _("cannot create debug link section `%s'"),
+ 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)
+ if (bfd_count_sections (obfd) != 0
+ && (gap_fill_set || pad_to_set))
{
asection **set;
unsigned int c, i;
if (! bfd_set_section_size (obfd, osections[i],
size + (gap_stop - gap_start)))
{
- non_fatal (_("Can't fill gap after %s: %s"),
- bfd_get_section_name (obfd, osections[i]),
- bfd_errmsg (bfd_get_error ()));
+ bfd_nonfatal_message (NULL, obfd, osections[i],
+ _("Can't fill gap after section"));
status = 1;
break;
}
if (! bfd_set_section_size (obfd, osections[c - 1],
pad_to - lma))
{
- non_fatal (_("Can't add padding to %s: %s"),
- bfd_get_section_name (obfd, osections[c - 1]),
- bfd_errmsg (bfd_get_error ()));
+ bfd_nonfatal_message (NULL, obfd, osections[c - 1],
+ _("can't add padding"));
status = 1;
}
else
if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
0, padd->size))
{
- bfd_nonfatal (bfd_get_filename (obfd));
+ bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
return FALSE;
}
}
if (! bfd_fill_in_gnu_debuglink_section
(obfd, gnu_debuglink_section, gnu_debuglink_filename))
{
- bfd_nonfatal (gnu_debuglink_filename);
+ bfd_nonfatal_message (NULL, obfd, NULL,
+ _("cannot fill debug link section `%s'"),
+ gnu_debuglink_filename);
return FALSE;
}
}
if (! bfd_set_section_contents (obfd, osections[i], buf,
off, now))
{
- bfd_nonfatal (bfd_get_filename (obfd));
+ bfd_nonfatal_message (NULL, obfd, osections[i], NULL);
return FALSE;
}
from the input BFD to the output BFD. This is done last to
permit the routine to look at the filtered symbol table, which is
important for the ECOFF code at least. */
- if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
- && strip_symbols == STRIP_NONDEBUG)
- /* Do not copy the private data when creating an ELF format
- debug info file. We do not want the program headers. */
- ;
- else if (! bfd_copy_private_bfd_data (ibfd, obfd))
- {
- non_fatal (_("%s: error copying private BFD data: %s"),
- bfd_get_filename (obfd),
- bfd_errmsg (bfd_get_error ()));
+ if (! bfd_copy_private_bfd_data (ibfd, obfd))
+ {
+ bfd_nonfatal_message (NULL, obfd, NULL,
+ _("error copying private BFD data"));
return FALSE;
}
this_element = bfd_openr_next_archived_file (ibfd, NULL);
if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
- RETURN_NONFATAL (bfd_get_filename (obfd));
+ RETURN_NONFATAL (obfd);
while (!status && this_element != NULL)
{
output_bfd = bfd_openw (output_name, bfd_get_target (this_element));
if (output_bfd == NULL)
- RETURN_NONFATAL (output_name);
+ {
+ bfd_nonfatal_message (output_name, NULL, NULL, NULL);
+ status = 1;
+ return;
+ }
delete = ! copy_object (this_element, output_bfd);
{
if (!bfd_close (output_bfd))
{
- bfd_nonfatal (bfd_get_filename (output_bfd));
+ bfd_nonfatal_message (NULL, output_bfd, NULL, NULL);
/* Error in new object file. Don't change archive. */
status = 1;
}
}
else
{
- non_fatal (_("Unable to recognise the format of the input file `%s'"),
- bfd_get_archive_filename (this_element));
+ bfd_nonfatal_message (bfd_get_archive_filename (this_element),
+ NULL, NULL,
+ _("Unable to recognise the format of file"));
output_bfd = bfd_openw (output_name, output_target);
copy_unknown_element:
delete = !copy_unknown_object (this_element, output_bfd);
if (!bfd_close_all_done (output_bfd))
{
- bfd_nonfatal (bfd_get_filename (output_bfd));
+ bfd_nonfatal_message (NULL, output_bfd, NULL, NULL);
/* Error in new object file. Don't change archive. */
status = 1;
}
l->obfd = output_bfd;
*ptr = output_bfd;
- ptr = &output_bfd->next;
+ ptr = &output_bfd->archive_next;
last_element = this_element;
*ptr = NULL;
if (!bfd_close (obfd))
- RETURN_NONFATAL (bfd_get_filename (obfd));
+ RETURN_NONFATAL (obfd);
if (!bfd_close (ibfd))
- RETURN_NONFATAL (bfd_get_filename (ibfd));
+ RETURN_NONFATAL (obfd);
/* Delete all the files that we opened. */
for (l = list; l != NULL; l = l->next)
non-object file, failures are nonfatal. */
ibfd = bfd_openr (input_filename, input_target);
if (ibfd == NULL)
- RETURN_NONFATAL (input_filename);
+ {
+ bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
+ status = 1;
+ return;
+ }
if (bfd_check_format (ibfd, bfd_archive))
{
obfd = bfd_openw (output_filename, output_target);
if (obfd == NULL)
- RETURN_NONFATAL (output_filename);
+ {
+ bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
+ status = 1;
+ return;
+ }
copy_archive (ibfd, obfd, output_target, force_output_target);
}
obfd = bfd_openw (output_filename, output_target);
if (obfd == NULL)
- RETURN_NONFATAL (output_filename);
+ {
+ bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
+ status = 1;
+ return;
+ }
if (! copy_object (ibfd, obfd))
status = 1;
if (!bfd_close (obfd))
- RETURN_NONFATAL (output_filename);
+ RETURN_NONFATAL (obfd);
if (!bfd_close (ibfd))
- RETURN_NONFATAL (input_filename);
-
+ RETURN_NONFATAL (ibfd);
}
else
{
if (obj_error != core_error)
bfd_set_error (obj_error);
- bfd_nonfatal (input_filename);
+ bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
if (obj_error == bfd_error_file_ambiguously_recognized)
{
static void
setup_bfd_headers (bfd *ibfd, bfd *obfd)
{
- const char *err;
-
/* Allow the BFD backend to copy any private data it understands
from the input section to the output section. */
if (! bfd_copy_private_header_data (ibfd, obfd))
{
- err = _("private header data");
- goto loser;
+ status = 1;
+ bfd_nonfatal_message (NULL, ibfd, NULL,
+ _("error in private h eader data"));
+ return;
}
/* All went well. */
return;
-
-loser:
- non_fatal (_("%s: error in %s: %s"),
- bfd_get_filename (ibfd),
- err, bfd_errmsg (bfd_get_error ()));
- status = 1;
}
/* Create a section in OBFD with the same
const char *err;
const char * name;
char *prefix = NULL;
+ bfd_boolean make_nobits;
if (is_strip_section (ibfd, isection))
return;
name = n;
}
+ make_nobits = FALSE;
if (p != NULL && p->set_flags)
flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
- else if (strip_symbols == STRIP_NONDEBUG && (flags & SEC_ALLOC) != 0)
- flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD);
+ else if (strip_symbols == STRIP_NONDEBUG
+ && (flags & SEC_ALLOC) != 0
+ && (ibfd->xvec->flavour != bfd_target_elf_flavour
+ || elf_section_type (isection) != SHT_NOTE))
+ {
+ flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD);
+ if (obfd->xvec->flavour == bfd_target_elf_flavour)
+ {
+ make_nobits = TRUE;
+
+ /* Twiddle the input section flags so that it seems to
+ elf.c:copy_private_bfd_data that section flags have not
+ changed between input and output sections. This hack
+ prevents wholesale rewriting of the program headers. */
+ isection->flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD);
+ }
+ }
osection = bfd_make_section_anyway_with_flags (obfd, name, flags);
if (osection == NULL)
{
- err = _("making");
+ err = _("failed to create output section");
goto loser;
}
- if (strip_symbols == STRIP_NONDEBUG
- && obfd->xvec->flavour == bfd_target_elf_flavour
- && (flags & SEC_ALLOC) != 0
- && (p == NULL || !p->set_flags))
+ if (make_nobits)
elf_section_type (osection) = SHT_NOBITS;
size = bfd_section_size (ibfd, isection);
size = 0;
if (! bfd_set_section_size (obfd, osection, size))
{
- err = _("size");
+ err = _("failed to set size");
goto loser;
}
if (! bfd_set_section_vma (obfd, osection, extract_symbol ? 0 : vma))
{
- err = _("vma");
+ err = _("failed to set vma");
goto loser;
}
osection,
bfd_section_alignment (ibfd, isection)))
{
- err = _("alignment");
+ err = _("failed to set alignment");
goto loser;
}
/* Allow the BFD backend to copy any private data it understands
from the input section to the output section. */
- if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
- && strip_symbols == STRIP_NONDEBUG)
- /* Do not copy the private data when creating an ELF format
- debug info file. We do not want the program headers. */
- ;
- else if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
- {
- err = _("private data");
+ if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
+ {
+ err = _("failed to copy private data");
goto loser;
}
else if ((isection->flags & SEC_GROUP) != 0)
return;
loser:
- non_fatal (_("%s: section `%s': error in %s: %s"),
- bfd_get_filename (ibfd),
- bfd_section_name (ibfd, isection),
- err, bfd_errmsg (bfd_get_error ()));
status = 1;
+ bfd_nonfatal_message (NULL, obfd, osection, err);
}
/* Copy the data of input section ISECTION of IBFD
if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
relsize = 0;
else
- RETURN_NONFATAL (bfd_get_filename (ibfd));
+ {
+ status = 1;
+ bfd_nonfatal_message (NULL, ibfd, isection, NULL);
+ return;
+ }
}
}
relpp = xmalloc (relsize);
relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
if (relcount < 0)
- RETURN_NONFATAL (bfd_get_filename (ibfd));
+ {
+ status = 1;
+ bfd_nonfatal_message (NULL, ibfd, isection,
+ _("relocation count is negative"));
+ return;
+ }
if (strip_symbols == STRIP_ALL)
{
void *memhunk = xmalloc (size);
if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
- RETURN_NONFATAL (bfd_get_filename (ibfd));
+ {
+ status = 1;
+ bfd_nonfatal_message (NULL, ibfd, isection, NULL);
+ return;
+ }
+
+ if (reverse_bytes)
+ {
+ /* We don't handle leftover bytes (too many possible behaviors,
+ and we don't know what the user wants). The section length
+ must be a multiple of the number of bytes to swap. */
+ if ((size % reverse_bytes) == 0)
+ {
+ unsigned long i, j;
+ bfd_byte b;
+
+ for (i = 0; i < size; i += reverse_bytes)
+ for (j = 0; j < (unsigned long)(reverse_bytes / 2); j++)
+ {
+ bfd_byte *m = (bfd_byte *) memhunk;
+
+ b = m[i + j];
+ m[i + j] = m[(i + reverse_bytes) - (j + 1)];
+ m[(i + reverse_bytes) - (j + 1)] = b;
+ }
+ }
+ else
+ /* User must pad the section up in order to do this. */
+ fatal (_("cannot reverse bytes: length of section %s must be evenly divisible by %d"),
+ bfd_section_name (ibfd, isection), reverse_bytes);
+ }
if (copy_byte >= 0)
{
}
if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
- RETURN_NONFATAL (bfd_get_filename (obfd));
-
+ {
+ status = 1;
+ bfd_nonfatal_message (NULL, obfd, osection, NULL);
+ return;
+ }
free (memhunk);
}
else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
memset (memhunk, 0, size);
if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
- RETURN_NONFATAL (bfd_get_filename (obfd));
+ {
+ status = 1;
+ bfd_nonfatal_message (NULL, obfd, osection, NULL);
+ return;
+ }
free (memhunk);
}
}
|| ! bfd_set_section_alignment (obfd, stabsec, 2)
|| ! bfd_set_section_alignment (obfd, stabstrsec, 0))
{
- non_fatal (_("%s: can't create debugging section: %s"),
- bfd_get_filename (obfd),
- bfd_errmsg (bfd_get_error ()));
+ bfd_nonfatal_message (NULL, obfd, NULL,
+ _("can't create debugging section"));
return FALSE;
}
|| ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
stringsize))
{
- non_fatal (_("%s: can't set debugging section contents: %s"),
- bfd_get_filename (obfd),
- bfd_errmsg (bfd_get_error ()));
+ bfd_nonfatal_message (NULL, obfd, NULL,
+ _("can't set debugging section contents"));
return FALSE;
}
return TRUE;
}
- non_fatal (_("%s: don't know how to write debugging information for %s"),
- bfd_get_filename (obfd), bfd_get_target (obfd));
+ bfd_nonfatal_message (NULL, obfd, NULL,
+ _("don't know how to write debugging information for %s"),
+ bfd_get_target (obfd));
return FALSE;
}
display_info ();
return 0;
}
-
+
if (show_version)
print_version ("strip");
It has already been checked in get_file_size(). */
stat (argv[i], &statbuf);
- if (output_file != NULL)
- tmpname = output_file;
- else
+ if (output_file == NULL || strcmp (argv[i], output_file) == 0)
tmpname = make_tempname (argv[i]);
+ else
+ tmpname = output_file;
if (tmpname == NULL)
{
- non_fatal (_("could not create temporary file to hold stripped copy of '%s'"),
- argv[i]);
+ bfd_nonfatal_message (argv[i], NULL, NULL,
+ _("could not create temporary file to hold stripped copy"));
status = 1;
continue;
}
{
if (preserve_dates)
set_times (tmpname, &statbuf);
- if (output_file == NULL)
- smart_rename (tmpname, argv[i], preserve_dates);
+ if (output_file != tmpname)
+ smart_rename (tmpname, output_file ? output_file : argv[i],
+ preserve_dates);
status = hold_status;
}
else
unlink_if_ordinary (tmpname);
- if (output_file == NULL)
+ if (output_file != tmpname)
free (tmpname);
}
char * binary_architecture = NULL;
char *input_filename = NULL;
char *output_filename = NULL;
+ char *tmpname;
char *input_target = NULL;
char *output_target = NULL;
bfd_boolean show_version = FALSE;
extract_symbol = TRUE;
break;
+ case OPTION_REVERSE_BYTES:
+ {
+ int prev = reverse_bytes;
+
+ reverse_bytes = atoi (optarg);
+ if ((reverse_bytes <= 0) || ((reverse_bytes % 2) != 0))
+ fatal (_("number of bytes to reverse must be positive and even"));
+
+ if (prev && prev != reverse_bytes)
+ non_fatal (_("Warning: ignoring previous --reverse-bytes value of %d"),
+ prev);
+ break;
+ }
+
case 0:
/* We've been given a long option. */
break;
display_info ();
return 0;
}
-
+
if (show_version)
print_version ("objcopy");
/* If there is no destination file, or the source and destination files
are the same, then create a temp and rename the result into the input. */
if (output_filename == NULL || strcmp (input_filename, output_filename) == 0)
- {
- char *tmpname = make_tempname (input_filename);
+ tmpname = make_tempname (input_filename);
+ else
+ tmpname = output_filename;
- if (tmpname == NULL)
- fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
- input_filename, strerror (errno));
+ if (tmpname == NULL)
+ fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
+ input_filename, strerror (errno));
- copy_file (input_filename, tmpname, input_target, output_target);
- if (status == 0)
- {
- if (preserve_dates)
- set_times (tmpname, &statbuf);
- smart_rename (tmpname, input_filename, preserve_dates);
- }
- else
- unlink (tmpname);
- }
- else
+ copy_file (input_filename, tmpname, input_target, output_target);
+ if (status == 0)
{
- copy_file (input_filename, output_filename, input_target, output_target);
-
- if (status == 0 && preserve_dates)
- set_times (output_filename, &statbuf);
- else if (status != 0)
- unlink_if_ordinary (output_filename);
+ if (preserve_dates)
+ set_times (tmpname, &statbuf);
+ if (tmpname != output_filename)
+ smart_rename (tmpname, input_filename, preserve_dates);
}
+ else
+ unlink_if_ordinary (tmpname);
if (change_warn)
{