/* objcopy.c -- copy object file from input to output, optionally massaging it.
- Copyright (C) 1991-2020 Free Software Foundation, Inc.
+ Copyright (C) 1991-2021 Free Software Foundation, Inc.
This file is part of GNU Binutils.
\f
#include "sysdep.h"
#include "bfd.h"
-#include "libbfd.h"
#include "progress.h"
#include "getopt.h"
#include "libiberty.h"
struct is_specified_symbol_predicate_data
{
- const char * name;
- bfd_boolean found;
+ const char *name;
+ bool found;
};
/* A node includes symbol name mapping to support redefine_sym. */
static int interleave = 0; /* Initialised to 4 in copy_main(). */
static int copy_width = 1;
-static bfd_boolean verbose; /* Print file and target names. */
-static bfd_boolean preserve_dates; /* Preserve input file timestamp. */
+static bool keep_section_symbols = false ;/* True if section symbols should be retained. */
+static bool verbose; /* Print file and target names. */
+static bool preserve_dates; /* Preserve input file timestamp. */
static int deterministic = -1; /* Enable deterministic archives. */
static int status = 0; /* Exit status. */
-static bfd_boolean merge_notes = FALSE; /* Merge note sections. */
+static bool merge_notes = false; /* Merge note sections. */
typedef struct merged_note_section
{
/* Structure used to hold lists of sections and actions to take. */
struct section_list
{
- struct section_list * next; /* Next section to change. */
- const char * pattern; /* Section name pattern. */
- bfd_boolean used; /* Whether this entry was used. */
+ struct section_list *next; /* Next section to change. */
+ const char *pattern; /* Section name pattern. */
+ bool used; /* Whether this entry was used. */
- unsigned int context; /* What to do with matching sections. */
+ unsigned int context; /* What to do with matching sections. */
/* Flag bits used in the context field.
- COPY and REMOVE are mutually exlusive. SET and ALTER are mutually exclusive. */
+ COPY and REMOVE are mutually exlusive.
+ SET and ALTER are mutually exclusive. */
#define SECTION_CONTEXT_REMOVE (1 << 0) /* Remove this section. */
#define SECTION_CONTEXT_COPY (1 << 1) /* Copy this section, delete all non-copied section. */
#define SECTION_CONTEXT_KEEP (1 << 2) /* Keep this section. */
#define SECTION_CONTEXT_REMOVE_RELOCS (1 << 8) /* Remove relocations for this section. */
#define SECTION_CONTEXT_SET_ALIGNMENT (1 << 9) /* Set alignment for section. */
- bfd_vma vma_val; /* Amount to change by or set to. */
- bfd_vma lma_val; /* Amount to change by or set to. */
- flagword flags; /* What to set the section flags to. */
- unsigned int alignment; /* Alignment of output section. */
+ bfd_vma vma_val; /* Amount to change by or set to. */
+ bfd_vma lma_val; /* Amount to change by or set to. */
+ flagword flags; /* What to set the section flags to. */
+ unsigned int alignment; /* Alignment of output section. */
};
static struct section_list *change_sections;
/* TRUE if some sections are to be removed. */
-static bfd_boolean sections_removed;
+static bool sections_removed;
/* TRUE if only some sections are to be copied. */
-static bfd_boolean sections_copied;
+static bool sections_copied;
/* Changes to the start address. */
static bfd_vma change_start = 0;
-static bfd_boolean set_start_set = FALSE;
+static bool set_start_set = false;
static bfd_vma set_start;
/* Changes to section addresses. */
static bfd_vma change_section_address = 0;
/* Filling gaps between sections. */
-static bfd_boolean gap_fill_set = FALSE;
+static bool gap_fill_set = false;
static bfd_byte gap_fill = 0;
/* Pad to a given address. */
-static bfd_boolean pad_to_set = FALSE;
+static bool pad_to_set = false;
static bfd_vma pad_to;
/* Use alternative machine code? */
static const char * gnu_debuglink_filename = NULL;
/* Whether to convert debugging information. */
-static bfd_boolean convert_debugging = FALSE;
+static bool convert_debugging = false;
/* Whether to compress/decompress DWARF debug sections. */
static enum
static enum bfd_link_elf_stt_common do_elf_stt_common = unchanged;
/* Whether to change the leading character in symbol names. */
-static bfd_boolean change_leading_char = FALSE;
+static bool change_leading_char = false;
/* Whether to remove the leading character from global symbol names. */
-static bfd_boolean remove_leading_char = FALSE;
+static bool remove_leading_char = false;
/* Whether to permit wildcard in symbol comparison. */
-static bfd_boolean wildcard = FALSE;
+static bool wildcard = false;
/* True if --localize-hidden is in effect. */
-static bfd_boolean localize_hidden = FALSE;
+static bool localize_hidden = false;
/* List of symbols to strip, keep, localize, keep-global, weaken,
or redefine. */
static char *weaken_specific_buffer = NULL;
/* If this is TRUE, we weaken global symbols (set BSF_WEAK). */
-static bfd_boolean weaken = FALSE;
+static bool weaken = false;
/* If this is TRUE, we retain BSF_FILE symbols. */
-static bfd_boolean keep_file_symbols = FALSE;
+static bool keep_file_symbols = false;
/* Prefix symbols/sections. */
static char *prefix_symbols_string = 0;
static char *prefix_alloc_sections_string = 0;
/* True if --extract-symbol was passed on the command line. */
-static bfd_boolean extract_symbol = FALSE;
+static bool extract_symbol = false;
/* If `reverse_bytes' is nonzero, then reverse the order of every chunk
of <reverse_bytes> bytes within each output section. */
OPTION_KEEP_FILE_SYMBOLS,
OPTION_KEEP_SECTION,
OPTION_KEEP_SYMBOLS,
+ OPTION_KEEP_SECTION_SYMBOLS,
OPTION_LOCALIZE_HIDDEN,
OPTION_LOCALIZE_SYMBOLS,
OPTION_LONG_SECTION_NAMES,
{"info", no_argument, 0, OPTION_FORMATS_INFO},
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
{"input-target", required_argument, 0, 'I'},
+ {"keep-section-symbols", no_argument, 0, OPTION_KEEP_SECTION_SYMBOLS},
{"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
{"keep-section", required_argument, 0, OPTION_KEEP_SECTION},
{"keep-symbol", required_argument, 0, 'K'},
{"keep-section", required_argument, 0, OPTION_KEEP_SECTION},
{"keep-symbol", required_argument, 0, 'K'},
{"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
+ {"keep-section-symbols", required_argument, 0, OPTION_KEEP_SECTION_SYMBOLS},
{"localize-hidden", no_argument, 0, OPTION_LOCALIZE_HIDDEN},
{"localize-symbol", required_argument, 0, 'L'},
{"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
/* Restrict the generation of Srecords to type S3 only.
This variable is defined in bfd/srec.c and can be toggled
on by the --srec-forceS3 command line switch. */
-extern bfd_boolean _bfd_srec_forceS3;
+extern bool _bfd_srec_forceS3;
/* Width of data in bytes for verilog output.
This variable is declared in bfd/verilog.c and can be modified by
static void get_sections (bfd *, asection *, void *);
static int compare_section_lma (const void *, const void *);
static void mark_symbols_used_in_relocations (bfd *, asection *, void *);
-static bfd_boolean write_debugging_info (bfd *, void *, long *, asymbol ***);
+static bool write_debugging_info (bfd *, void *, long *, asymbol ***);
static const char *lookup_sym_redefinition (const char *);
static const char *find_section_rename (const char *, flagword *);
\f
--extract-symbol Remove section contents but keep symbols\n\
--keep-section <name> Do not strip section <name>\n\
-K --keep-symbol <name> Do not strip symbol <name>\n\
+ --keep-section-symbols Do not strip section symbols\n\
--keep-file-symbols Do not strip file symbol(s)\n\
--localize-hidden Turn all ELF hidden symbols into locals\n\
-L --localize-symbol <name> Force symbol <name> to be marked as a local\n\
-N --strip-symbol=<name> Do not copy symbol <name>\n\
--keep-section=<name> Do not strip section <name>\n\
-K --keep-symbol=<name> Do not strip symbol <name>\n\
+ --keep-section-symbols Do not strip section symbols\n\
--keep-file-symbols Do not strip file symbol(s)\n\
-w --wildcard Permit wildcard in symbol comparison\n\
-x --discard-all Remove all non-global symbols\n\
entry as used. */
static struct section_list *
-find_section_list (const char *name, bfd_boolean add, unsigned int context)
+find_section_list (const char *name, bool add, unsigned int context)
{
struct section_list *p, *match = NULL;
{
if (fnmatch (p->pattern + 1, name, 0) == 0)
{
- p->used = TRUE;
+ p->used = true;
return NULL;
}
}
if (! add)
{
if (match != NULL)
- match->used = TRUE;
+ match->used = true;
return match;
}
p = (struct section_list *) xmalloc (sizeof (struct section_list));
p->pattern = name;
- p->used = FALSE;
+ p->used = false;
p->context = context;
p->vma_val = 0;
p->lma_val = 0;
xcalloc, free);
}
-/* There is htab_hash_string but no htab_eq_string. Makes sense. */
-
-static int
-eq_string (const void *s1, const void *s2)
-{
- return strcmp ((const char *) s1, (const char *) s2) == 0;
-}
-
static htab_t
create_symbol_htab (void)
{
- return htab_create_alloc (16, htab_hash_string, eq_string, NULL, xcalloc, free);
+ return htab_create_alloc (16, htab_hash_string, htab_eq_string, NULL,
+ xcalloc, free);
}
static void
char * eol;
char * name;
char * name_end;
- int finished = FALSE;
+ int finished = false;
for (eol = line;; eol ++)
{
/* Cope with \n\r. */
if (eol[1] == '\r')
++ eol;
- finished = TRUE;
+ finished = true;
break;
case '\r':
/* Cope with \r\n. */
if (eol[1] == '\n')
++ eol;
- finished = TRUE;
+ finished = true;
break;
case 0:
- finished = TRUE;
+ finished = true;
break;
case '#':
{
if (! fnmatch (slot_name, d->name, 0))
{
- d->found = TRUE;
+ d->found = true;
/* Continue traversal, there might be a non-match rule. */
return 1;
}
{
if (! fnmatch (slot_name + 1, d->name, 0))
{
- d->found = FALSE;
+ d->found = false;
/* Stop traversal. */
return 0;
}
return 1;
}
-static bfd_boolean
+static bool
is_specified_symbol (const char *name, htab_t htab)
{
if (wildcard)
struct is_specified_symbol_predicate_data data;
data.name = name;
- data.found = FALSE;
+ data.found = false;
htab_traverse (htab, is_specified_symbol_predicate, &data);
/* Return TRUE if the section is a DWO section. */
-static bfd_boolean
+static bool
is_dwo_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
{
const char *name;
int len;
if (sec == NULL || (name = bfd_section_name (sec)) == NULL)
- return FALSE;
+ return false;
len = strlen (name);
if (len < 5)
- return FALSE;
+ return false;
- return strncmp (name + len - 4, ".dwo", 4) == 0;
+ return startswith (name + len - 4, ".dwo");
}
/* Return TRUE if section SEC is in the update list. */
-static bfd_boolean
+static bool
is_update_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
{
if (update_sections != NULL)
pupdate = pupdate->next)
{
if (strcmp (sec->name, pupdate->name) == 0)
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
-static bfd_boolean
+static bool
is_mergeable_note_section (bfd * abfd, asection * sec)
{
if (merge_notes
&& elf_section_data (sec)->this_hdr.sh_type == SHT_NOTE
/* FIXME: We currently only support merging GNU_BUILD_NOTEs.
We should add support for more note types. */
- && ((elf_section_data (sec)->this_hdr.sh_flags & SHF_GNU_BUILD_NOTE) != 0
- /* Old versions of GAS (prior to 2.27) could not set the section
- flags to OS-specific values, so we also accept sections that
- start with the expected name. */
- || (CONST_STRNEQ (sec->name, GNU_BUILD_ATTRS_SECTION_NAME))))
- return TRUE;
-
- return FALSE;
+ && (startswith (sec->name, GNU_BUILD_ATTRS_SECTION_NAME)))
+ return true;
+
+ return false;
}
/* See if a non-group section is being removed. */
-static bfd_boolean
+static bool
is_strip_section_1 (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
{
- if (find_section_list (bfd_section_name (sec), FALSE, SECTION_CONTEXT_KEEP)
+ if (find_section_list (bfd_section_name (sec), false, SECTION_CONTEXT_KEEP)
!= NULL)
- return FALSE;
+ return false;
if (sections_removed || sections_copied)
{
struct section_list *p;
struct section_list *q;
- p = find_section_list (bfd_section_name (sec), FALSE,
+ p = find_section_list (bfd_section_name (sec), false,
SECTION_CONTEXT_REMOVE);
- q = find_section_list (bfd_section_name (sec), FALSE,
+ q = find_section_list (bfd_section_name (sec), false,
SECTION_CONTEXT_COPY);
if (p && q)
bfd_section_name (sec));
if (p != NULL)
- return TRUE;
+ return true;
if (sections_copied && q == NULL)
- return TRUE;
+ return true;
}
if ((bfd_section_flags (sec) & SEC_DEBUGGING) != 0)
This section has for pe-coff special meaning. See
pe-dll.c file in ld, and peXXigen.c in bfd for details. */
if (strcmp (bfd_section_name (sec), ".reloc") != 0)
- return TRUE;
+ return true;
}
if (strip_symbols == STRIP_DWO)
return is_dwo_section (abfd, sec);
if (strip_symbols == STRIP_NONDEBUG)
- return FALSE;
+ return false;
}
if (strip_symbols == STRIP_NONDWO)
return !is_dwo_section (abfd, sec);
- return FALSE;
+ return false;
}
/* See if a section is being removed. */
-static bfd_boolean
+static bool
is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
{
if (is_strip_section_1 (abfd, sec))
- return TRUE;
+ return true;
if ((bfd_section_flags (sec) & SEC_GROUP) != 0)
{
gsym = group_signature (sec);
/* Strip groups without a valid signature. */
if (gsym == NULL)
- return TRUE;
+ return true;
/* PR binutils/3181
If we are going to strip the group signature symbol, then
if ((strip_symbols == STRIP_ALL
&& !is_specified_symbol (gname, keep_specific_htab))
|| is_specified_symbol (gname, strip_specific_htab))
- return TRUE;
+ return true;
/* Remove the group section if all members are removed. */
first = elt = elf_next_in_group (sec);
while (elt != NULL)
{
if (!is_strip_section_1 (abfd, elt))
- return FALSE;
+ return false;
elt = elf_next_in_group (elt);
if (elt == first)
break;
}
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-static bfd_boolean
+static bool
is_nondebug_keep_contents_section (bfd *ibfd, asection *isection)
{
/* Always keep ELF note sections. */
if (bfd_get_flavour (ibfd) == bfd_target_coff_flavour)
return strcmp (bfd_section_name (isection), ".buildid") == 0;
- return FALSE;
+ return false;
}
/* Return true if SYM is a hidden symbol. */
-static bfd_boolean
+static bool
is_hidden_symbol (asymbol *sym)
{
elf_symbol_type *elf_sym;
{
case STV_HIDDEN:
case STV_INTERNAL:
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/* Empty name is hopefully never a valid symbol name. */
static const char * empty_name = "";
-static bfd_boolean
+static bool
need_sym_before (struct addsym_node **node, const char *sym)
{
int count;
free ((char *) ptr->othersym);
ptr->othersym = empty_name;
*node = ptr;
- return TRUE;
+ return true;
}
ptr = ptr->next;
}
- return FALSE;
+ return false;
}
static asymbol *
asymbol *sym = from[src_count];
flagword flags = sym->flags;
char *name = (char *) bfd_asymbol_name (sym);
- bfd_boolean keep;
- bfd_boolean used_in_reloc = FALSE;
- bfd_boolean undefined;
- bfd_boolean rem_leading_char;
- bfd_boolean add_leading_char;
+ bool keep;
+ bool used_in_reloc = false;
+ bool undefined;
+ bool rem_leading_char;
+ bool add_leading_char;
undefined = bfd_is_und_section (bfd_asymbol_section (sym));
{
name[0] = bfd_get_symbol_leading_char (obfd);
bfd_set_asymbol_name (sym, name);
- rem_leading_char = FALSE;
- add_leading_char = FALSE;
+ rem_leading_char = false;
+ add_leading_char = false;
}
/* Remove leading char. */
}
if (strip_symbols == STRIP_ALL)
- keep = FALSE;
+ keep = false;
else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
|| ((flags & BSF_SECTION_SYM) != 0
&& ((*bfd_asymbol_section (sym)->symbol_ptr_ptr)->flags
& BSF_KEEP) != 0))
{
- keep = TRUE;
- used_in_reloc = TRUE;
+ keep = true;
+ used_in_reloc = true;
}
else if (relocatable /* Relocatable file. */
&& ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
|| bfd_is_com_section (bfd_asymbol_section (sym))))
- keep = TRUE;
+ 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 = TRUE;
+ keep = true;
else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
|| (flags & BSF_WEAK) != 0
|| undefined
else if (bfd_coff_get_comdat_section (abfd, bfd_asymbol_section (sym)))
/* COMDAT sections store special information in local
symbols, so we cannot risk stripping any of them. */
- keep = TRUE;
+ keep = true;
else /* Local symbol. */
keep = (strip_symbols != STRIP_UNNEEDED
&& (discard_locals != LOCALS_ALL
status = 1;
}
else
- keep = FALSE;
+ keep = false;
}
if (keep
&& !(flags & BSF_KEEP)
&& is_specified_symbol (name, strip_unneeded_htab))
- keep = FALSE;
+ keep = false;
if (!keep
&& ((keep_file_symbols && (flags & BSF_FILE))
|| is_specified_symbol (name, keep_specific_htab)))
- keep = TRUE;
+ keep = true;
if (keep && is_strip_section (abfd, bfd_asymbol_section (sym)))
- keep = FALSE;
+ keep = false;
if (keep)
{
- if ((flags & BSF_GLOBAL) != 0
+ if (((flags & BSF_GLOBAL) != 0
+ || undefined)
&& (weaken || is_specified_symbol (name, weaken_specific_htab)))
{
sym->flags &= ~ BSF_GLOBAL;
/* Copy unknown object file IBFD onto OBFD.
Returns TRUE upon success, FALSE otherwise. */
-static bfd_boolean
+static bool
copy_unknown_object (bfd *ibfd, bfd *obfd)
{
char *cbuf;
if (bfd_stat_arch_elt (ibfd, &buf) != 0)
{
bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
- return FALSE;
+ return false;
}
size = buf.st_size;
{
non_fatal (_("stat returns negative size for `%s'"),
bfd_get_archive_filename (ibfd));
- return FALSE;
+ return false;
}
if (bfd_seek (ibfd, (file_ptr) 0, SEEK_SET) != 0)
{
bfd_nonfatal (bfd_get_archive_filename (ibfd));
- return FALSE;
+ return false;
}
if (verbose)
{
bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
free (cbuf);
- return FALSE;
+ return false;
}
if (bfd_bwrite (cbuf, (bfd_size_type) tocopy, obfd)
{
bfd_nonfatal_message (NULL, obfd, NULL, NULL);
free (cbuf);
- return FALSE;
+ return false;
}
ncopied += tocopy;
unknown object in an archive. */
chmod (bfd_get_filename (obfd), buf.st_mode | S_IRUSR);
free (cbuf);
- return TRUE;
+ return true;
}
typedef struct objcopy_internal_note
/* Returns TRUE iff PNOTE1 overlaps or adjoins PNOTE2. */
-static bfd_boolean
+static bool
overlaps_or_adjoins (objcopy_internal_note * pnote1,
objcopy_internal_note * pnote2)
{
return BFD_ALIGN (pnote2->end, 16) < pnote1->start;
if (pnote1->end < pnote2->end)
- return TRUE;
+ return true;
if (pnote2->end < pnote1->end)
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
/* Returns TRUE iff NEEDLE is fully contained by HAYSTACK. */
-static bfd_boolean
+static bool
contained_by (objcopy_internal_note * needle,
objcopy_internal_note * haystack)
{
return needle->start >= haystack->start && needle->end <= haystack->end;
}
-static bfd_boolean
+static bool
is_open_note (objcopy_internal_note * pnote)
{
return pnote->note.type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
}
-static bfd_boolean
+static bool
is_func_note (objcopy_internal_note * pnote)
{
return pnote->note.type == NT_GNU_BUILD_ATTRIBUTE_FUNC;
}
-static bfd_boolean
+static bool
is_deleted_note (objcopy_internal_note * pnote)
{
return pnote->note.type == 0;
}
-static bfd_boolean
+static bool
is_version_note (objcopy_internal_note * pnote)
{
return (pnote->note.namesz > 4
&& pnote->note.namedata[3] == GNU_BUILD_ATTRIBUTE_VERSION);
}
-static bfd_boolean
+static bool
is_64bit (bfd * abfd)
{
/* Should never happen, but let's be paranoid. */
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
- return FALSE;
+ return false;
return elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64;
}
break;
case 8:
- if (! is_64bit (abfd))
- {
- start = bfd_get_32 (abfd, pnote->note.descdata);
- end = bfd_get_32 (abfd, pnote->note.descdata + 4);
- }
- else
- {
- start = bfd_get_64 (abfd, pnote->note.descdata);
- /* FIXME: For version 1 and 2 notes we should try to
- calculate the end address by finding a symbol whose
- value is START, and then adding in its size.
-
- For now though, since v1 and v2 was not intended to
- handle gaps, we chose an artificially large end
- address. */
- end = (bfd_vma) -1;
- }
+ start = bfd_get_32 (abfd, pnote->note.descdata);
+ end = bfd_get_32 (abfd, pnote->note.descdata + 4);
break;
case 16:
goto done;
}
+ if (start > end)
+ /* This can happen with PPC64LE binaries where empty notes are
+ encoded as start = end + 4. */
+ start = end;
+
if (is_open_note (pnote))
{
if (start)
/* Copy object file IBFD onto OBFD.
Returns TRUE upon success, FALSE otherwise. */
-static bfd_boolean
+static bool
copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
{
bfd_vma start;
may need to tidy temporary files. */
non_fatal (_("unable to change endianness of '%s'"),
bfd_get_archive_filename (ibfd));
- return FALSE;
+ return false;
}
if (ibfd->read_only)
{
non_fatal (_("unable to modify '%s' due to errors"),
bfd_get_archive_filename (ibfd));
- return FALSE;
+ return false;
}
if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
{
bfd_nonfatal_message (NULL, obfd, NULL, NULL);
- return FALSE;
+ return false;
}
if (ibfd->sections == NULL)
{
non_fatal (_("error: the input file '%s' has no sections"),
bfd_get_archive_filename (ibfd));
- return FALSE;
+ return false;
}
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
{
non_fatal (_("--compress-debug-sections=[zlib|zlib-gnu|zlib-gabi] is unsupported on `%s'"),
bfd_get_archive_filename (ibfd));
- return FALSE;
+ return false;
}
if (do_elf_stt_common)
{
non_fatal (_("--elf-stt-common=[yes|no] is unsupported on `%s'"),
bfd_get_archive_filename (ibfd));
- return FALSE;
+ return false;
}
}
|| !bfd_set_file_flags (obfd, flags))
{
bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
- return FALSE;
+ return false;
}
}
non_fatal (_("Output file cannot represent architecture `%s'"),
bfd_printable_arch_mach (bfd_get_arch (ibfd),
bfd_get_mach (ibfd)));
- return FALSE;
+ return false;
}
if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
{
bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
- return FALSE;
+ return false;
}
if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
pe->timestamp = pe_data (ibfd)->coff.timestamp;
}
- if (isympp)
- free (isympp);
+ free (isympp);
if (osympp != isympp)
free (osympp);
if (symsize < 0)
{
bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
- return FALSE;
+ return false;
}
osympp = isympp = (asymbol **) xmalloc (symsize);
if (symcount < 0)
{
bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
- return FALSE;
+ return false;
}
/* PR 17512: file: d6323821
If the symbol table could not be loaded do not pretend that we have
{
flagword flags;
- pset = find_section_list (padd->name, FALSE,
+ pset = find_section_list (padd->name, false,
SECTION_CONTEXT_SET_FLAGS);
if (pset != NULL)
{
{
bfd_nonfatal_message (NULL, obfd, NULL,
_("can't add section '%s'"), padd->name);
- return FALSE;
+ return false;
}
else
{
bfd_nonfatal_message (NULL, obfd, NULL,
_("can't create section `%s'"),
padd->name);
- return FALSE;
+ return false;
}
}
if (!bfd_set_section_size (padd->section, padd->size))
{
bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
- return FALSE;
+ return false;
}
- pset = find_section_list (padd->name, FALSE,
+ pset = find_section_list (padd->name, false,
SECTION_CONTEXT_SET_VMA | SECTION_CONTEXT_ALTER_VMA);
if (pset != NULL
&& !bfd_set_section_vma (padd->section, pset->vma_val))
{
bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
- return FALSE;
+ return false;
}
- pset = find_section_list (padd->name, FALSE,
+ pset = find_section_list (padd->name, false,
SECTION_CONTEXT_SET_LMA | SECTION_CONTEXT_ALTER_LMA);
if (pset != NULL)
{
(padd->section, bfd_section_alignment (padd->section)))
{
bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
- return FALSE;
+ return false;
}
}
}
if (pupdate->section == NULL)
{
non_fatal (_("error: %s not found, can't be updated"), pupdate->name);
- return FALSE;
+ return false;
}
osec = pupdate->section->output_section;
if (!bfd_set_section_size (osec, pupdate->size))
{
bfd_nonfatal_message (NULL, obfd, osec, NULL);
- return FALSE;
+ return false;
}
}
}
strerror (errno));
free (contents);
fclose (f);
- return FALSE;
+ return false;
}
}
else
bfd_nonfatal_message (NULL, obfd, NULL,
_("cannot create debug link section `%s'"),
gnu_debuglink_filename);
- return FALSE;
+ return false;
}
/* Special processing for PE format files. We
have been created, but before their contents are set. */
dhandle = NULL;
if (convert_debugging)
- dhandle = read_debugging_info (ibfd, isympp, symcount, FALSE);
+ dhandle = read_debugging_info (ibfd, isympp, symcount, false);
+
+ if ((obfd->flags & (EXEC_P | DYNAMIC)) != 0
+ && (obfd->flags & HAS_RELOC) == 0)
+ {
+ if (bfd_keep_unused_section_symbols (obfd) || keep_section_symbols)
+ {
+ /* Non-relocatable inputs may not have the unused section
+ symbols. Mark all section symbols as used to generate
+ section symbols. */
+ asection *asect;
+ for (asect = obfd->sections; asect != NULL; asect = asect->next)
+ if (asect->symbol)
+ asect->symbol->flags |= BSF_SECTION_SYM_USED;
+ }
+ else
+ {
+ /* Non-relocatable inputs may have the unused section symbols.
+ Mark all section symbols as unused to excluded them. */
+ long s;
+ for (s = 0; s < symcount; s++)
+ if ((isympp[s]->flags & BSF_SECTION_SYM_USED))
+ isympp[s]->flags &= ~BSF_SECTION_SYM_USED;
+ }
+ }
if (strip_symbols == STRIP_DEBUG
|| strip_symbols == STRIP_ALL
if (bfd_get_error () != bfd_error_no_error)
{
status = 1;
- return FALSE;
+ return false;
}
}
if (convert_debugging && dhandle != NULL)
{
- bfd_boolean res;
+ bool res;
res = write_debugging_info (obfd, dhandle, &symcount, &osympp);
if (! res)
{
status = 1;
- return FALSE;
+ return false;
}
}
0, padd->size))
{
bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
- return FALSE;
+ return false;
}
}
}
0, pupdate->size))
{
bfd_nonfatal_message (NULL, obfd, osec, NULL);
- return FALSE;
+ return false;
}
}
}
bfd_nonfatal_message
(NULL, obfd, osec,
_("error: failed to copy merged notes into output"));
- return FALSE;
+ return false;
}
merged = merged->next;
bfd_nonfatal_message (NULL, obfd, NULL,
_("cannot fill debug link section `%s'"),
gnu_debuglink_filename);
- return FALSE;
+ return false;
}
}
{
bfd_nonfatal_message (NULL, obfd, osections[i], NULL);
free (buf);
- return FALSE;
+ return false;
}
left -= now;
{
bfd_nonfatal_message (NULL, obfd, NULL,
_("error copying private BFD data"));
- return FALSE;
+ return false;
}
/* Switch to the alternate machine code. We have to do this at the
}
}
- return TRUE;
+ return true;
}
/* Read each archive element in turn from IBFD, copy the
static void
copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
- bfd_boolean force_output_target,
+ bool force_output_target,
const bfd_arch_info_type *input_arch)
{
struct name_list
strerror (errno));
if (strip_symbols == STRIP_ALL)
- obfd->has_armap = FALSE;
+ obfd->has_armap = false;
else
obfd->has_armap = ibfd->has_armap;
obfd->is_thin_archive = ibfd->is_thin_archive;
bfd *last_element;
struct stat buf;
int stat_status = 0;
- bfd_boolean del = TRUE;
- bfd_boolean ok_object;
+ bool del = true;
+ bool ok_object;
/* PR binutils/17533: Do not allow directory traversal
outside of the current directory tree by archive members. */
if (del && bfd_get_arch (this_element) == bfd_arch_unknown)
/* Try again as an unknown object file. */
- ok_object = FALSE;
+ ok_object = false;
else if (!bfd_close (output_bfd))
{
bfd_nonfatal_message (output_name, NULL, NULL, NULL);
static void
copy_file (const char *input_filename, const char *output_filename, int ofd,
- const char *input_target, const char *output_target,
- const bfd_arch_info_type *input_arch)
+ struct stat *in_stat, const char *input_target,
+ const char *output_target, const bfd_arch_info_type *input_arch)
{
bfd *ibfd;
char **obj_matching;
/* To allow us to do "strip *" without dying on the first
non-object file, failures are nonfatal. */
ibfd = bfd_openr (input_filename, input_target);
- if (ibfd == NULL)
+ if (ibfd == NULL || bfd_stat (ibfd, in_stat) != 0)
{
bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
status = 1;
if (bfd_check_format (ibfd, bfd_archive))
{
- bfd_boolean force_output_target;
+ bool force_output_target;
bfd *obfd;
/* bfd_get_target does not return the correct value until
if (output_target == NULL)
{
output_target = bfd_get_target (ibfd);
- force_output_target = FALSE;
+ force_output_target = false;
}
else
- force_output_target = TRUE;
+ force_output_target = true;
if (ofd >= 0)
obfd = bfd_fdopenw (output_filename, output_target, ofd);
const char * name;
const char * new_name;
char *prefix = NULL;
- bfd_boolean make_nobits;
+ bool make_nobits;
unsigned int alignment;
if (is_strip_section (ibfd, isection))
name = n;
}
- make_nobits = FALSE;
+ make_nobits = false;
- p = find_section_list (bfd_section_name (isection), FALSE,
+ p = find_section_list (bfd_section_name (isection), false,
SECTION_CONTEXT_SET_FLAGS);
if (p != NULL)
{
flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP);
if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
{
- make_nobits = TRUE;
+ make_nobits = true;
/* Twiddle the input section flags so that it seems to
elf.c:copy_private_bfd_data that section flags have not
}
vma = bfd_section_vma (isection);
- p = find_section_list (bfd_section_name (isection), FALSE,
+ p = find_section_list (bfd_section_name (isection), false,
SECTION_CONTEXT_ALTER_VMA | SECTION_CONTEXT_SET_VMA);
if (p != NULL)
{
}
lma = isection->lma;
- p = find_section_list (bfd_section_name (isection), FALSE,
+ p = find_section_list (bfd_section_name (isection), false,
SECTION_CONTEXT_ALTER_LMA | SECTION_CONTEXT_SET_LMA);
if (p != NULL)
{
osection->lma = lma;
- p = find_section_list (bfd_section_name (isection), FALSE,
+ p = find_section_list (bfd_section_name (isection), false,
SECTION_CONTEXT_SET_ALIGNMENT);
if (p != NULL)
alignment = p->alignment;
/* Return TRUE if input section ISECTION should be skipped. */
-static bfd_boolean
-skip_section (bfd *ibfd, sec_ptr isection, bfd_boolean skip_copy)
+static bool
+skip_section (bfd *ibfd, sec_ptr isection, bool skip_copy)
{
sec_ptr osection;
bfd_size_type size;
/* If we have already failed earlier on,
do not keep on generating complaints now. */
if (status != 0)
- return TRUE;
+ return true;
if (extract_symbol)
- return TRUE;
+ return true;
if (is_strip_section (ibfd, isection))
- return TRUE;
+ return true;
if (is_update_section (ibfd, isection))
- return TRUE;
+ return true;
/* When merging a note section we skip the copying of the contents,
but not the copying of the relocs associated with the contents. */
if (skip_copy && is_mergeable_note_section (ibfd, isection))
- return TRUE;
+ return true;
flags = bfd_section_flags (isection);
if ((flags & SEC_GROUP) != 0)
- return TRUE;
+ return true;
osection = isection->output_section;
size = bfd_section_size (isection);
if (size == 0 || osection == 0)
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
/* Add section SECTION_PATTERN to the list of sections that will have their
static void
handle_remove_relocations_option (const char *section_pattern)
{
- find_section_list (section_pattern, TRUE, SECTION_CONTEXT_REMOVE_RELOCS);
+ find_section_list (section_pattern, true, SECTION_CONTEXT_REMOVE_RELOCS);
}
/* Return TRUE if ISECTION from IBFD should have its relocations removed,
removed from a section that does not have relocations then this
function will still return TRUE. */
-static bfd_boolean
+static bool
discard_relocations (bfd *ibfd ATTRIBUTE_UNUSED, asection *isection)
{
- return (find_section_list (bfd_section_name (isection), FALSE,
+ return (find_section_list (bfd_section_name (isection), false,
SECTION_CONTEXT_REMOVE_RELOCS) != NULL);
}
static void
handle_remove_section_option (const char *section_pattern)
{
- find_section_list (section_pattern, TRUE, SECTION_CONTEXT_REMOVE);
- if (strncmp (section_pattern, ".rel", 4) == 0)
+ find_section_list (section_pattern, true, SECTION_CONTEXT_REMOVE);
+ if (startswith (section_pattern, ".rel"))
{
section_pattern += 4;
if (*section_pattern == 'a')
if (*section_pattern)
handle_remove_relocations_option (section_pattern);
}
- sections_removed = TRUE;
+ sections_removed = true;
}
/* Copy relocations in input section ISECTION of IBFD to an output
long relcount;
sec_ptr osection;
- if (skip_section (ibfd, isection, FALSE))
+ if (skip_section (ibfd, isection, false))
return;
osection = isection->output_section;
sec_ptr osection;
bfd_size_type size;
- if (skip_section (ibfd, isection, TRUE))
+ if (skip_section (ibfd, isection, true))
return;
osection = isection->output_section;
free (memhunk);
}
else if ((p = find_section_list (bfd_section_name (isection),
- FALSE, SECTION_CONTEXT_SET_FLAGS)) != NULL
+ false, SECTION_CONTEXT_SET_FLAGS)) != NULL
&& (p->flags & SEC_HAS_CONTENTS) != 0)
{
void *memhunk = xmalloc (size);
(*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
}
- if (relpp != NULL)
- free (relpp);
+ free (relpp);
}
/* Write out debugging information. */
-static bfd_boolean
+static bool
write_debugging_info (bfd *obfd, void *dhandle,
long *symcountp ATTRIBUTE_UNUSED,
asymbol ***symppp ATTRIBUTE_UNUSED)
if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
&symsize, &strings,
&stringsize))
- return FALSE;
+ return false;
flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
stabsec = bfd_make_section_with_flags (obfd, ".stab", flags);
bfd_nonfatal_message (NULL, obfd, NULL,
_("can't create debugging section"));
free (strings);
- return FALSE;
+ return false;
}
/* We can get away with setting the section contents now because
bfd_nonfatal_message (NULL, obfd, NULL,
_("can't set debugging section contents"));
free (strings);
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
bfd_nonfatal_message (NULL, obfd, NULL,
_("don't know how to write debugging information for %s"),
bfd_get_target (obfd));
- return FALSE;
+ return false;
}
/* If neither -D nor -U was specified explicitly,
{
char *input_target = NULL;
char *output_target = NULL;
- bfd_boolean show_version = FALSE;
- bfd_boolean formats_info = FALSE;
+ bool show_version = false;
+ bool formats_info = false;
int c;
int i;
char *output_file = NULL;
- bfd_boolean merge_notes_set = FALSE;
+ bool merge_notes_set = false;
while ((c = getopt_long (argc, argv, "I:O:F:K:MN:R:o:sSpdgxXHhVvwDU",
strip_options, (int *) 0)) != EOF)
handle_remove_section_option (optarg);
break;
case OPTION_KEEP_SECTION:
- find_section_list (optarg, TRUE, SECTION_CONTEXT_KEEP);
+ find_section_list (optarg, true, SECTION_CONTEXT_KEEP);
break;
case OPTION_REMOVE_RELOCS:
handle_remove_relocations_option (optarg);
add_specific_symbol (optarg, keep_specific_htab);
break;
case 'M':
- merge_notes = TRUE;
- merge_notes_set = TRUE;
+ merge_notes = true;
+ merge_notes_set = true;
break;
case OPTION_NO_MERGE_NOTES:
- merge_notes = FALSE;
- merge_notes_set = TRUE;
+ merge_notes = false;
+ merge_notes_set = true;
break;
case 'N':
add_specific_symbol (optarg, strip_specific_htab);
output_file = optarg;
break;
case 'p':
- preserve_dates = TRUE;
+ preserve_dates = true;
break;
case 'D':
- deterministic = TRUE;
+ deterministic = true;
break;
case 'U':
- deterministic = FALSE;
+ deterministic = false;
break;
case 'x':
discard_locals = LOCALS_ALL;
discard_locals = LOCALS_START_L;
break;
case 'v':
- verbose = TRUE;
+ verbose = true;
break;
case 'V':
- show_version = TRUE;
+ show_version = true;
break;
case OPTION_FORMATS_INFO:
- formats_info = TRUE;
+ formats_info = true;
break;
case OPTION_ONLY_KEEP_DEBUG:
strip_symbols = STRIP_NONDEBUG;
case OPTION_KEEP_FILE_SYMBOLS:
keep_file_symbols = 1;
break;
+ case OPTION_KEEP_SECTION_SYMBOLS:
+ keep_section_symbols = true;
+ break;
case 0:
/* We've been given a long option. */
break;
case 'w':
- wildcard = TRUE;
+ wildcard = true;
break;
case 'H':
case 'h':
|| strip_symbols == STRIP_UNNEEDED
|| strip_symbols == STRIP_NONDEBUG
|| strip_symbols == STRIP_NONDWO))
- merge_notes = TRUE;
+ merge_notes = true;
if (formats_info)
{
struct stat statbuf;
char *tmpname;
int tmpfd = -1;
+ int copyfd = -1;
if (get_file_size (argv[i]) < 1)
{
continue;
}
- if (preserve_dates)
- /* No need to check the return value of stat().
- It has already been checked in get_file_size(). */
- stat (argv[i], &statbuf);
-
if (output_file == NULL
|| filename_cmp (argv[i], output_file) == 0)
- tmpname = make_tempname (argv[i], &tmpfd);
+ {
+ tmpname = make_tempname (argv[i], &tmpfd);
+ if (tmpfd >= 0)
+ copyfd = dup (tmpfd);
+ }
else
tmpname = output_file;
}
status = 0;
- copy_file (argv[i], tmpname, tmpfd, input_target, output_target, NULL);
+ copy_file (argv[i], tmpname, tmpfd, &statbuf, input_target,
+ output_target, NULL);
if (status == 0)
{
- if (preserve_dates)
- set_times (tmpname, &statbuf);
- if (output_file != tmpname)
- status = (smart_rename (tmpname,
- output_file ? output_file : argv[i],
- preserve_dates) != 0);
+ const char *oname = output_file ? output_file : argv[i];
+ status = smart_rename (tmpname, oname, copyfd,
+ &statbuf, preserve_dates) != 0;
if (status == 0)
status = hold_status;
}
else
- unlink_if_ordinary (tmpname);
+ {
+ if (copyfd >= 0)
+ close (copyfd);
+ unlink_if_ordinary (tmpname);
+ }
if (output_file != tmpname)
free (tmpname);
}
char *tmpname;
char *input_target = NULL;
char *output_target = NULL;
- bfd_boolean show_version = FALSE;
- bfd_boolean change_warn = TRUE;
- bfd_boolean formats_info = FALSE;
- bfd_boolean use_globalize = FALSE;
- bfd_boolean use_keep_global = FALSE;
- int c, tmpfd = -1;
+ bool show_version = false;
+ bool change_warn = true;
+ bool formats_info = false;
+ bool use_globalize = false;
+ bool use_keep_global = false;
+ int c;
+ int tmpfd = -1;
+ int copyfd;
struct stat statbuf;
const bfd_arch_info_type *input_arch = NULL;
break;
case 'j':
- find_section_list (optarg, TRUE, SECTION_CONTEXT_COPY);
- sections_copied = TRUE;
+ find_section_list (optarg, true, SECTION_CONTEXT_COPY);
+ sections_copied = true;
break;
case 'R':
break;
case OPTION_KEEP_SECTION:
- find_section_list (optarg, TRUE, SECTION_CONTEXT_KEEP);
+ find_section_list (optarg, true, SECTION_CONTEXT_KEEP);
break;
case OPTION_REMOVE_RELOCS:
break;
case 'M':
- merge_notes = TRUE;
+ merge_notes = true;
break;
case OPTION_NO_MERGE_NOTES:
- merge_notes = FALSE;
+ merge_notes = false;
break;
case 'N':
break;
case OPTION_GLOBALIZE_SYMBOL:
- use_globalize = TRUE;
+ use_globalize = true;
add_specific_symbol (optarg, globalize_specific_htab);
break;
case 'G':
- use_keep_global = TRUE;
+ use_keep_global = true;
add_specific_symbol (optarg, keepglobal_specific_htab);
break;
break;
case 'p':
- preserve_dates = TRUE;
+ preserve_dates = true;
break;
case 'D':
- deterministic = TRUE;
+ deterministic = true;
break;
case 'U':
- deterministic = FALSE;
+ deterministic = false;
break;
case 'w':
- wildcard = TRUE;
+ wildcard = true;
break;
case 'x':
break;
case 'v':
- verbose = TRUE;
+ verbose = true;
break;
case 'V':
- show_version = TRUE;
+ show_version = true;
break;
case OPTION_FORMATS_INFO:
- formats_info = TRUE;
+ formats_info = true;
break;
case OPTION_WEAKEN:
- weaken = TRUE;
+ weaken = true;
break;
case OPTION_ADD_SECTION:
strncpy (name, optarg, len);
name[len] = '\0';
- p = find_section_list (name, TRUE, context);
+ p = find_section_list (name, true, context);
val = parse_vma (s + 1, option);
if (*s == '-')
break;
case OPTION_CHANGE_WARNINGS:
- change_warn = TRUE;
+ change_warn = true;
break;
case OPTION_CHANGE_LEADING_CHAR:
- change_leading_char = TRUE;
+ change_leading_char = true;
break;
case OPTION_COMPRESS_DEBUG_SECTIONS:
break;
case OPTION_DEBUGGING:
- convert_debugging = TRUE;
+ convert_debugging = true;
break;
case OPTION_DECOMPRESS_DEBUG_SECTIONS:
non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
buff, gap_fill);
}
- gap_fill_set = TRUE;
+ gap_fill_set = true;
}
break;
case OPTION_NO_CHANGE_WARNINGS:
- change_warn = FALSE;
+ change_warn = false;
break;
case OPTION_PAD_TO:
pad_to = parse_vma (optarg, "--pad-to");
- pad_to_set = TRUE;
+ pad_to_set = true;
break;
case OPTION_REMOVE_LEADING_CHAR:
- remove_leading_char = TRUE;
+ remove_leading_char = true;
break;
case OPTION_REDEFINE_SYM:
strncpy (name, optarg, len);
name[len] = '\0';
- p = find_section_list (name, TRUE, SECTION_CONTEXT_SET_FLAGS);
+ p = find_section_list (name, true, SECTION_CONTEXT_SET_FLAGS);
p->flags = parse_flags (s + 1);
}
strncpy (name, optarg, len);
name[len] = '\0';
- p = find_section_list (name, TRUE, SECTION_CONTEXT_SET_ALIGNMENT);
+ p = find_section_list (name, true, SECTION_CONTEXT_SET_ALIGNMENT);
if (p)
p->alignment = palign;
}
case OPTION_SET_START:
set_start = parse_vma (optarg, "--set-start");
- set_start_set = TRUE;
+ set_start_set = true;
break;
case OPTION_SREC_LEN:
break;
case OPTION_SREC_FORCES3:
- _bfd_srec_forceS3 = TRUE;
+ _bfd_srec_forceS3 = true;
break;
case OPTION_STRIP_SYMBOLS:
&keep_specific_buffer);
break;
+ case OPTION_KEEP_SECTION_SYMBOLS:
+ keep_section_symbols = true;
+ break;
+
case OPTION_LOCALIZE_HIDDEN:
- localize_hidden = TRUE;
+ localize_hidden = true;
break;
case OPTION_LOCALIZE_SYMBOLS:
break;
case OPTION_GLOBALIZE_SYMBOLS:
- use_globalize = TRUE;
+ use_globalize = true;
add_specific_symbols (optarg, globalize_specific_htab,
&globalize_specific_buffer);
break;
case OPTION_KEEPGLOBAL_SYMBOLS:
- use_keep_global = TRUE;
+ use_keep_global = true;
add_specific_symbols (optarg, keepglobal_specific_htab,
&keepglobal_specific_buffer);
break;
break;
case OPTION_EXTRACT_SYMBOL:
- extract_symbol = TRUE;
+ extract_symbol = true;
break;
case OPTION_REVERSE_BYTES:
/* Convert input EFI target to PEI target. */
if (input_target != NULL
- && strncmp (input_target, "efi-", 4) == 0)
+ && startswith (input_target, "efi-"))
{
char *efi;
efi = xstrdup (output_target + 4);
- if (strncmp (efi, "bsdrv-", 6) == 0
- || strncmp (efi, "rtdrv-", 6) == 0)
+ if (startswith (efi, "bsdrv-")
+ || startswith (efi, "rtdrv-"))
efi += 2;
- else if (strncmp (efi, "app-", 4) != 0)
+ else if (!startswith (efi, "app-"))
fatal (_("unknown input EFI target: %s"), input_target);
input_target = efi;
/* Convert output EFI target to PEI target. */
if (output_target != NULL
- && strncmp (output_target, "efi-", 4) == 0)
+ && startswith (output_target, "efi-"))
{
char *efi;
efi = xstrdup (output_target + 4);
- if (strncmp (efi, "app-", 4) == 0)
+ if (startswith (efi, "app-"))
{
if (pe_subsystem == -1)
pe_subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
}
- else if (strncmp (efi, "bsdrv-", 6) == 0)
+ else if (startswith (efi, "bsdrv-"))
{
if (pe_subsystem == -1)
pe_subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
efi += 2;
}
- else if (strncmp (efi, "rtdrv-", 6) == 0)
+ else if (startswith (efi, "rtdrv-"))
{
if (pe_subsystem == -1)
pe_subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
convert_efi_target (efi);
}
- if (preserve_dates)
- if (stat (input_filename, & statbuf) < 0)
- fatal (_("warning: could not locate '%s'. System error message: %s"),
- input_filename, strerror (errno));
-
/* 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. */
+ are the same, then create a temp and copy the result into the input. */
+ copyfd = -1;
if (output_filename == NULL
|| filename_cmp (input_filename, output_filename) == 0)
- tmpname = make_tempname (input_filename, &tmpfd);
+ {
+ tmpname = make_tempname (input_filename, &tmpfd);
+ if (tmpfd >= 0)
+ copyfd = dup (tmpfd);
+ }
else
tmpname = output_filename;
if (tmpname == NULL)
- fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
- input_filename, strerror (errno));
+ {
+ fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
+ input_filename, strerror (errno));
+ }
- copy_file (input_filename, tmpname, tmpfd, input_target, output_target,
- input_arch);
+ copy_file (input_filename, tmpname, tmpfd, &statbuf, input_target,
+ output_target, input_arch);
if (status == 0)
{
- if (preserve_dates)
- set_times (tmpname, &statbuf);
- if (tmpname != output_filename)
- status = (smart_rename (tmpname, input_filename,
- preserve_dates) != 0);
+ const char *oname = output_filename ? output_filename : input_filename;
+ status = smart_rename (tmpname, oname, copyfd,
+ &statbuf, preserve_dates) != 0;
}
else
- unlink_if_ordinary (tmpname);
+ {
+ if (copyfd >= 0)
+ close (copyfd);
+ unlink_if_ordinary (tmpname);
+ }
if (tmpname != output_filename)
free (tmpname);
}
}
- if (strip_specific_buffer)
- free (strip_specific_buffer);
-
- if (strip_unneeded_buffer)
- free (strip_unneeded_buffer);
-
- if (keep_specific_buffer)
- free (keep_specific_buffer);
-
- if (localize_specific_buffer)
- free (globalize_specific_buffer);
-
- if (globalize_specific_buffer)
- free (globalize_specific_buffer);
-
- if (keepglobal_specific_buffer)
- free (keepglobal_specific_buffer);
-
- if (weaken_specific_buffer)
- free (weaken_specific_buffer);
+ free (strip_specific_buffer);
+ free (strip_unneeded_buffer);
+ free (keep_specific_buffer);
+ free (localize_specific_buffer);
+ free (globalize_specific_buffer);
+ free (keepglobal_specific_buffer);
+ free (weaken_specific_buffer);
return 0;
}
int
main (int argc, char *argv[])
{
-#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+#ifdef HAVE_LC_MESSAGES
setlocale (LC_MESSAGES, "");
#endif
-#if defined (HAVE_SETLOCALE)
setlocale (LC_CTYPE, "");
-#endif
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);