/* objcopy.c -- copy object file from input to output, optionally massaging it.
- Copyright (C) 1991-2015 Free Software Foundation, Inc.
+ Copyright (C) 1991-2016 Free Software Foundation, Inc.
This file is part of GNU Binutils.
struct is_specified_symbol_predicate_data
{
- const char *name;
+ const char * name;
bfd_boolean found;
};
struct redefine_node *next;
};
+struct addsym_node
+{
+ struct addsym_node *next;
+ char * symdef;
+ long symval;
+ flagword flags;
+ char * section;
+ char * othersym;
+};
+
typedef struct section_rename
{
const char * old_name;
static int status = 0; /* Exit status. */
enum strip_action
- {
- STRIP_UNDEF,
- STRIP_NONE, /* Don't strip. */
- STRIP_DEBUG, /* Strip all debugger symbols. */
- STRIP_UNNEEDED, /* Strip unnecessary symbols. */
- STRIP_NONDEBUG, /* Strip everything but debug info. */
- STRIP_DWO, /* Strip all DWO info. */
- STRIP_NONDWO, /* Strip everything but DWO info. */
- STRIP_ALL /* Strip all symbols. */
- };
+{
+ STRIP_UNDEF,
+ STRIP_NONE, /* Don't strip. */
+ STRIP_DEBUG, /* Strip all debugger symbols. */
+ STRIP_UNNEEDED, /* Strip unnecessary symbols. */
+ STRIP_NONDEBUG, /* Strip everything but debug info. */
+ STRIP_DWO, /* Strip all DWO info. */
+ STRIP_NONDWO, /* Strip everything but DWO info. */
+ STRIP_ALL /* Strip all symbols. */
+};
/* Which symbols to remove. */
static enum strip_action strip_symbols = STRIP_UNDEF;
enum locals_action
- {
- LOCALS_UNDEF,
- LOCALS_START_L, /* Discard locals starting with L. */
- LOCALS_ALL /* Discard all locals. */
- };
+{
+ LOCALS_UNDEF,
+ LOCALS_START_L, /* Discard locals starting with L. */
+ LOCALS_ALL /* Discard all locals. */
+};
/* Which local symbols to remove. Overrides STRIP_ALL. */
static enum locals_action discard_locals;
decompress = 1 << 4
} do_debug_sections = nothing;
+/* Whether to generate ELF common symbols with the STT_COMMON type. */
+static enum bfd_link_discard do_elf_stt_common = unchanged;
+
/* Whether to change the leading character in symbol names. */
static bfd_boolean change_leading_char = FALSE;
static htab_t keepglobal_specific_htab = NULL;
static htab_t weaken_specific_htab = NULL;
static struct redefine_node *redefine_sym_list = NULL;
+static struct addsym_node *add_sym_list = NULL, **add_sym_tail = &add_sym_list;
+static int add_symbols = 0;
/* If this is TRUE, we weaken global symbols (set BSF_WEAK). */
static bfd_boolean weaken = FALSE;
/* For Coff objects, we may want to allow or disallow long section names,
or preserve them where found in the inputs. Debug info relies on them. */
enum long_section_name_handling
- {
- DISABLE,
- ENABLE,
- KEEP
- };
+{
+ DISABLE,
+ ENABLE,
+ KEEP
+};
/* The default long section handling mode is to preserve them.
This is also the only behaviour for 'strip'. */
/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
enum command_line_switch
- {
- OPTION_ADD_SECTION=150,
- OPTION_UPDATE_SECTION,
- OPTION_DUMP_SECTION,
- OPTION_CHANGE_ADDRESSES,
- OPTION_CHANGE_LEADING_CHAR,
- OPTION_CHANGE_START,
- OPTION_CHANGE_SECTION_ADDRESS,
- OPTION_CHANGE_SECTION_LMA,
- OPTION_CHANGE_SECTION_VMA,
- OPTION_CHANGE_WARNINGS,
- OPTION_COMPRESS_DEBUG_SECTIONS,
- OPTION_DEBUGGING,
- OPTION_DECOMPRESS_DEBUG_SECTIONS,
- OPTION_GAP_FILL,
- OPTION_NO_CHANGE_WARNINGS,
- OPTION_PAD_TO,
- OPTION_REMOVE_LEADING_CHAR,
- OPTION_SET_SECTION_FLAGS,
- OPTION_SET_START,
- OPTION_STRIP_UNNEEDED,
- OPTION_WEAKEN,
- OPTION_REDEFINE_SYM,
- OPTION_REDEFINE_SYMS,
- OPTION_SREC_LEN,
- OPTION_SREC_FORCES3,
- OPTION_STRIP_SYMBOLS,
- OPTION_STRIP_UNNEEDED_SYMBOL,
- OPTION_STRIP_UNNEEDED_SYMBOLS,
- OPTION_KEEP_SYMBOLS,
- OPTION_LOCALIZE_HIDDEN,
- OPTION_LOCALIZE_SYMBOLS,
- OPTION_LONG_SECTION_NAMES,
- OPTION_GLOBALIZE_SYMBOL,
- OPTION_GLOBALIZE_SYMBOLS,
- OPTION_KEEPGLOBAL_SYMBOLS,
- OPTION_WEAKEN_SYMBOLS,
- OPTION_RENAME_SECTION,
- OPTION_ALT_MACH_CODE,
- OPTION_PREFIX_SYMBOLS,
- OPTION_PREFIX_SECTIONS,
- OPTION_PREFIX_ALLOC_SECTIONS,
- OPTION_FORMATS_INFO,
- OPTION_ADD_GNU_DEBUGLINK,
- OPTION_ONLY_KEEP_DEBUG,
- OPTION_KEEP_FILE_SYMBOLS,
- OPTION_READONLY_TEXT,
- OPTION_WRITABLE_TEXT,
- OPTION_PURE,
- OPTION_IMPURE,
- OPTION_EXTRACT_SYMBOL,
- OPTION_REVERSE_BYTES,
- OPTION_FILE_ALIGNMENT,
- OPTION_HEAP,
- OPTION_IMAGE_BASE,
- OPTION_SECTION_ALIGNMENT,
- OPTION_STACK,
- OPTION_INTERLEAVE_WIDTH,
- OPTION_SUBSYSTEM,
- OPTION_EXTRACT_DWO,
- OPTION_STRIP_DWO
- };
+{
+ OPTION_ADD_SECTION=150,
+ OPTION_ADD_GNU_DEBUGLINK,
+ OPTION_ADD_SYMBOL,
+ OPTION_ALT_MACH_CODE,
+ OPTION_CHANGE_ADDRESSES,
+ OPTION_CHANGE_LEADING_CHAR,
+ OPTION_CHANGE_SECTION_ADDRESS,
+ OPTION_CHANGE_SECTION_LMA,
+ OPTION_CHANGE_SECTION_VMA,
+ OPTION_CHANGE_START,
+ OPTION_CHANGE_WARNINGS,
+ OPTION_COMPRESS_DEBUG_SECTIONS,
+ OPTION_DEBUGGING,
+ OPTION_DECOMPRESS_DEBUG_SECTIONS,
+ OPTION_DUMP_SECTION,
+ OPTION_ELF_STT_COMMON,
+ OPTION_EXTRACT_DWO,
+ OPTION_EXTRACT_SYMBOL,
+ OPTION_FILE_ALIGNMENT,
+ OPTION_FORMATS_INFO,
+ OPTION_GAP_FILL,
+ OPTION_GLOBALIZE_SYMBOL,
+ OPTION_GLOBALIZE_SYMBOLS,
+ OPTION_HEAP,
+ OPTION_IMAGE_BASE,
+ OPTION_IMPURE,
+ OPTION_INTERLEAVE_WIDTH,
+ OPTION_KEEPGLOBAL_SYMBOLS,
+ OPTION_KEEP_FILE_SYMBOLS,
+ OPTION_KEEP_SYMBOLS,
+ OPTION_LOCALIZE_HIDDEN,
+ OPTION_LOCALIZE_SYMBOLS,
+ OPTION_LONG_SECTION_NAMES,
+ OPTION_NO_CHANGE_WARNINGS,
+ OPTION_ONLY_KEEP_DEBUG,
+ OPTION_PAD_TO,
+ OPTION_PREFIX_ALLOC_SECTIONS,
+ OPTION_PREFIX_SECTIONS,
+ OPTION_PREFIX_SYMBOLS,
+ OPTION_PURE,
+ OPTION_READONLY_TEXT,
+ OPTION_REDEFINE_SYM,
+ OPTION_REDEFINE_SYMS,
+ OPTION_REMOVE_LEADING_CHAR,
+ OPTION_RENAME_SECTION,
+ OPTION_REVERSE_BYTES,
+ OPTION_SECTION_ALIGNMENT,
+ OPTION_SET_SECTION_FLAGS,
+ OPTION_SET_START,
+ OPTION_SREC_FORCES3,
+ OPTION_SREC_LEN,
+ OPTION_STACK,
+ OPTION_STRIP_DWO,
+ OPTION_STRIP_SYMBOLS,
+ OPTION_STRIP_UNNEEDED,
+ OPTION_STRIP_UNNEEDED_SYMBOL,
+ OPTION_STRIP_UNNEEDED_SYMBOLS,
+ OPTION_SUBSYSTEM,
+ OPTION_UPDATE_SECTION,
+ OPTION_WEAKEN,
+ OPTION_WEAKEN_SYMBOLS,
+ OPTION_WRITABLE_TEXT
+};
/* Options to handle if running as "strip". */
{"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
{"keep-symbol", required_argument, 0, 'K'},
{"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
+ {"output-file", required_argument, 0, 'o'},
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
{"output-target", required_argument, 0, 'O'},
- {"output-file", required_argument, 0, 'o'},
{"preserve-dates", no_argument, 0, 'p'},
{"remove-section", required_argument, 0, 'R'},
{"strip-all", no_argument, 0, 's'},
{"strip-debug", no_argument, 0, 'S'},
{"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
- {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
{"strip-symbol", required_argument, 0, 'N'},
+ {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
{"target", required_argument, 0, 'F'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{
{"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
{"add-section", required_argument, 0, OPTION_ADD_SECTION},
- {"update-section", required_argument, 0, OPTION_UPDATE_SECTION},
+ {"add-symbol", required_argument, 0, OPTION_ADD_SYMBOL},
+ {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
{"adjust-start", required_argument, 0, OPTION_CHANGE_START},
{"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
- {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
{"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
{"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
{"binary-architecture", required_argument, 0, 'B'},
{"discard-all", no_argument, 0, 'x'},
{"discard-locals", no_argument, 0, 'X'},
{"dump-section", required_argument, 0, OPTION_DUMP_SECTION},
+ {"elf-stt-common", required_argument, 0, OPTION_ELF_STT_COMMON},
{"enable-deterministic-archives", no_argument, 0, 'D'},
{"extract-dwo", no_argument, 0, OPTION_EXTRACT_DWO},
{"extract-symbol", no_argument, 0, OPTION_EXTRACT_SYMBOL},
+ {"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT},
{"format", required_argument, 0, 'F'}, /* Obsolete */
{"gap-fill", required_argument, 0, OPTION_GAP_FILL},
{"globalize-symbol", required_argument, 0, OPTION_GLOBALIZE_SYMBOL},
{"globalize-symbols", required_argument, 0, OPTION_GLOBALIZE_SYMBOLS},
+ {"heap", required_argument, 0, OPTION_HEAP},
{"help", no_argument, 0, 'h'},
+ {"image-base", required_argument, 0 , OPTION_IMAGE_BASE},
{"impure", no_argument, 0, OPTION_IMPURE},
{"info", no_argument, 0, OPTION_FORMATS_INFO},
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
{"output-target", required_argument, 0, 'O'},
{"pad-to", required_argument, 0, OPTION_PAD_TO},
- {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
- {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
{"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
+ {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
+ {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
{"preserve-dates", no_argument, 0, 'p'},
{"pure", no_argument, 0, OPTION_PURE},
{"readonly-text", no_argument, 0, OPTION_READONLY_TEXT},
{"remove-section", required_argument, 0, 'R'},
{"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
{"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES},
+ {"section-alignment", required_argument, 0, OPTION_SECTION_ALIGNMENT},
{"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},
{"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
+ {"srec-len", required_argument, 0, OPTION_SREC_LEN},
+ {"stack", required_argument, 0, OPTION_STACK},
{"strip-all", no_argument, 0, 'S'},
{"strip-debug", no_argument, 0, 'g'},
{"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
+ {"strip-symbol", required_argument, 0, 'N'},
+ {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
{"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
{"strip-unneeded-symbol", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOL},
{"strip-unneeded-symbols", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOLS},
- {"strip-symbol", required_argument, 0, 'N'},
- {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
+ {"subsystem", required_argument, 0, OPTION_SUBSYSTEM},
{"target", required_argument, 0, 'F'},
+ {"update-section", required_argument, 0, OPTION_UPDATE_SECTION},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"weaken", no_argument, 0, OPTION_WEAKEN},
{"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
{"wildcard", no_argument, 0, 'w'},
{"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT},
- {"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT},
- {"heap", required_argument, 0, OPTION_HEAP},
- {"image-base", required_argument, 0 , OPTION_IMAGE_BASE},
- {"section-alignment", required_argument, 0, OPTION_SECTION_ALIGNMENT},
- {"stack", required_argument, 0, OPTION_STACK},
- {"subsystem", required_argument, 0, OPTION_SUBSYSTEM},
{0, no_argument, 0, 0}
};
--globalize-symbols <file> --globalize-symbol for all in <file>\n\
--keep-global-symbols <file> -G for all symbols listed in <file>\n\
--weaken-symbols <file> -W for all symbols listed in <file>\n\
+ --add-symbol <name>=[<section>:]<value>[,<flags>] Add a symbol\n\
--alt-machine-code <index> Use the target's <index>'th alternative machine\n\
--writable-text Mark the output text as writable\n\
--readonly-text Make the output text write protected\n\
--compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi}]\n\
Compress DWARF debug sections using zlib\n\
--decompress-debug-sections Decompress DWARF debug sections using zlib\n\
+ --elf-stt-common=[yes|no] Generate ELF common symbols with STT_COMMON\n\
+ type\n\
-v --verbose List all object files modified\n\
@<file> Read options from <file>\n\
-V --version Display this program's version number\n\
return ret;
}
+/* Parse symbol flags into a flagword, with a fatal error if the
+ string can't be parsed. */
+
+static flagword
+parse_symflags (const char *s, char **other)
+{
+ flagword ret;
+ const char *snext;
+ int len;
+
+ ret = BSF_NO_FLAGS;
+
+ do
+ {
+ snext = strchr (s, ',');
+ if (snext == NULL)
+ len = strlen (s);
+ else
+ {
+ len = snext - s;
+ ++snext;
+ }
+
+#define PARSE_FLAG(fname,fval) \
+ else if (len == (int) sizeof fname - 1 && strncasecmp (fname, s, len) == 0) \
+ ret |= fval
+
+#define PARSE_OTHER(fname,fval) \
+ else if (len >= (int) sizeof fname && strncasecmp (fname, s, sizeof fname - 1) == 0) \
+ fval = xstrndup (s + sizeof fname - 1, len - sizeof fname + 1)
+
+ if (0) ;
+ PARSE_FLAG ("local", BSF_LOCAL);
+ PARSE_FLAG ("global", BSF_GLOBAL);
+ PARSE_FLAG ("export", BSF_EXPORT);
+ PARSE_FLAG ("debug", BSF_DEBUGGING);
+ PARSE_FLAG ("function", BSF_FUNCTION);
+ PARSE_FLAG ("weak", BSF_WEAK);
+ PARSE_FLAG ("section", BSF_SECTION_SYM);
+ PARSE_FLAG ("constructor", BSF_CONSTRUCTOR);
+ PARSE_FLAG ("warning", BSF_WARNING);
+ PARSE_FLAG ("indirect", BSF_INDIRECT);
+ PARSE_FLAG ("file", BSF_FILE);
+ PARSE_FLAG ("object", BSF_OBJECT);
+ PARSE_FLAG ("synthetic", BSF_SYNTHETIC);
+ PARSE_FLAG ("indirect-function", BSF_GNU_INDIRECT_FUNCTION | BSF_FUNCTION);
+ PARSE_FLAG ("unique-object", BSF_GNU_UNIQUE | BSF_OBJECT);
+ PARSE_OTHER ("before=", *other);
+
+#undef PARSE_FLAG
+#undef PARSE_OTHER
+ else
+ {
+ char *copy;
+
+ copy = (char *) xmalloc (len + 1);
+ strncpy (copy, s, len);
+ copy[len] = '\0';
+ non_fatal (_("unrecognized symbol flag `%s'"), copy);
+ fatal (_("supported flags: %s"),
+ "local, global, export, debug, function, weak, section, "
+ "constructor, warning, indirect, file, object, synthetic, "
+ "indirect-function, unique-object, before=<othersym>");
+ }
+
+ s = snext;
+ }
+ while (s != NULL);
+
+ return ret;
+}
+
/* Find and optionally add an entry in the change_sections list.
We need to be careful in how we match section names because of the support
for wildcard characters. For example suppose that the user has invoked
objcopy like this:
-
+
--set-section-flags .debug_*=debug
--set-section-flags .debug_str=readonly,debug
--change-section-address .debug_*ranges=0x1000
struct section_list *p;
/* assert ((context & ((1 << 7) - 1)) != 0); */
-
+
for (p = change_sections; p != NULL; p = p->next)
{
if (add)
if (! fnmatch (slot_name, d->name, 0))
{
d->found = TRUE;
- /* Stop traversal. */
- return 0;
+ /* Continue traversal, there might be a non-match rule. */
+ return 1;
}
}
else
{
- if (fnmatch (slot_name + 1, d->name, 0))
+ if (! fnmatch (slot_name + 1, d->name, 0))
{
- d->found = TRUE;
+ d->found = FALSE;
/* Stop traversal. */
return 0;
}
return FALSE;
}
+static bfd_boolean
+need_sym_before (struct addsym_node **node, const char *sym)
+{
+ int count;
+ struct addsym_node *ptr = add_sym_list;
+
+ /* 'othersym' symbols are at the front of the list. */
+ for (count = 0; count < add_symbols; count++)
+ {
+ if (!ptr->othersym)
+ break;
+ else if (strcmp (ptr->othersym, sym) == 0)
+ {
+ free (ptr->othersym);
+ ptr->othersym = ""; /* Empty name is hopefully never a valid symbol name. */
+ *node = ptr;
+ return TRUE;
+ }
+ ptr = ptr->next;
+ }
+ return FALSE;
+}
+
+static asymbol *
+create_new_symbol (struct addsym_node *ptr, bfd *obfd)
+{
+ asymbol *sym = bfd_make_empty_symbol(obfd);
+
+ bfd_asymbol_name(sym) = ptr->symdef;
+ sym->value = ptr->symval;
+ sym->flags = ptr->flags;
+ if (ptr->section)
+ {
+ asection *sec = bfd_get_section_by_name (obfd, ptr->section);
+ if (!sec)
+ fatal (_("Section %s not found"), ptr->section);
+ sym->section = sec;
+ }
+ else
+ sym->section = bfd_abs_section_ptr;
+ return sym;
+}
+
/* Choose which symbol entries to copy; put the result in OSYMS.
We don't copy in place, because that confuses the relocs.
Return the number of symbols to print. */
undefined = bfd_is_und_section (bfd_get_section (sym));
+ if (add_sym_list)
+ {
+ struct addsym_node *ptr;
+
+ if (need_sym_before (&ptr, name))
+ to[dst_count++] = create_new_symbol (ptr, obfd);
+ }
+
if (redefine_sym_list)
{
char *old_name, *new_name;
to[dst_count++] = sym;
}
}
+ if (add_sym_list)
+ {
+ struct addsym_node *ptr = add_sym_list;
+
+ for (src_count = 0; src_count < add_symbols; src_count++)
+ {
+ if (ptr->othersym)
+ {
+ if (strcmp (ptr->othersym, ""))
+ fatal (_("'before=%s' not found"), ptr->othersym);
+ }
+ else
+ to[dst_count++] = create_new_symbol (ptr, obfd);
+
+ ptr = ptr->next;
+ }
+ }
to[dst_count] = NULL;
void *dhandle;
enum bfd_architecture iarch;
unsigned int imach;
+ unsigned int c, i;
if (ibfd->xvec->byteorder != obfd->xvec->byteorder
&& ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
return FALSE;
}
- if ((do_debug_sections & compress) != 0
- && do_debug_sections != compress
- && ibfd->xvec->flavour != bfd_target_elf_flavour)
+ if (ibfd->xvec->flavour != 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;
+ if ((do_debug_sections & compress) != 0
+ && do_debug_sections != compress)
+ {
+ non_fatal (_("--compress-debug-sections=[zlib|zlib-gnu|zlib-gabi] is unsupported on `%s'"),
+ bfd_get_archive_filename (ibfd));
+ 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;
+ }
}
if (verbose)
_("can't dump section - it has no contents"));
continue;
}
-
+
bfd_size_type size = bfd_get_section_size (sec);
if (size == 0)
{
free (contents);
}
}
-
+
if (gnu_debuglink_filename != NULL)
{
/* PR 15125: Give a helpful warning message if
}
}
- if (bfd_count_sections (obfd) != 0
+ c = bfd_count_sections (obfd);
+ if (c != 0
&& (gap_fill_set || pad_to_set))
{
asection **set;
- unsigned int c, i;
/* We must fill in gaps between the sections and/or we must pad
the last section to a specified address. We do this by
increasing the section sizes as required to fill the gaps.
We write out the gap contents below. */
- c = bfd_count_sections (obfd);
osections = (asection **) xmalloc (c * sizeof (asection *));
set = osections;
bfd_map_over_sections (obfd, get_sections, &set);
|| change_leading_char
|| remove_leading_char
|| redefine_sym_list
- || weaken)
+ || weaken
+ || add_symbols)
{
/* Mark symbols used in output relocations so that they
are kept, even if they are local labels or static symbols.
bfd_map_over_sections (ibfd,
mark_symbols_used_in_relocations,
isympp);
- osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
+ osympp = (asymbol **) xmalloc ((symcount + add_symbols + 1) * sizeof (asymbol *));
symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
}
if (gap_fill_set || pad_to_set)
{
bfd_byte *buf;
- int c, i;
/* Fill in the gaps. */
if (max_gap > 8192)
}
}
- /* Do not copy backend data if --extract-symbol is passed; anything
- that needs to look at the section contents will fail. */
- if (extract_symbol)
- return TRUE;
-
/* Allow the BFD backend to copy any private data it understands
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
break;
}
+ switch (do_elf_stt_common)
+ {
+ case elf_stt_common:
+ ibfd->flags |= BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON;
+ break;
+ break;
+ case no_elf_stt_common:
+ ibfd->flags |= BFD_CONVERT_ELF_COMMON;
+ break;
+ default:
+ break;
+ }
+
if (bfd_check_format (ibfd, bfd_archive))
{
bfd_boolean force_output_target;
isection->output_section = osection;
isection->output_offset = 0;
- /* Do not copy backend data if --extract-symbol is passed; anything
- that needs to look at the section contents will fail. */
- if (extract_symbol)
- return;
-
if ((isection->flags & SEC_GROUP) != 0)
{
asymbol *gsym = group_signature (isection);
osection = isection->output_section;
/* The output SHF_COMPRESSED section size is different from input if
- ELF classes of input and output aren't the same. We must use the
- output section size here, which has been updated in setup_section
- via bfd_convert_section_size. */
- size = bfd_get_section_size (osection);
+ ELF classes of input and output aren't the same. We can't use
+ the output section size since --interleave will shrink the output
+ section. Size will be updated if the section is converted. */
+ size = bfd_get_section_size (isection);
if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
&& bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
if (!bfd_get_full_section_contents (ibfd, isection, &memhunk)
|| !bfd_convert_section_contents (ibfd, isection, obfd,
- &memhunk))
+ &memhunk, &size))
{
status = 1;
bfd_nonfatal_message (NULL, ibfd, isection, NULL);
dump_sections = init_section_add (optarg, dump_sections,
"--dump-section");
break;
-
+
+ case OPTION_ADD_SYMBOL:
+ {
+ char *s, *t;
+ struct addsym_node *newsym = xmalloc (sizeof *newsym);
+
+ newsym->next = NULL;
+ s = strchr (optarg, '=');
+ if (s == NULL)
+ fatal (_("bad format for %s"), "--add-symbol");
+ t = strchr (s + 1, ':');
+
+ newsym->symdef = xstrndup (optarg, s - optarg);
+ if (t)
+ {
+ newsym->section = xstrndup (s + 1, t - (s + 1));
+ newsym->symval = strtol (t + 1, NULL, 0);
+ }
+ else
+ {
+ newsym->section = NULL;
+ newsym->symval = strtol (s + 1, NULL, 0);
+ t = s;
+ }
+
+ t = strchr (t + 1, ',');
+ if (t)
+ newsym->flags = parse_symflags (t+1, &newsym->othersym);
+ else
+ newsym->flags = BSF_GLOBAL;
+
+ /* Keep 'othersym' symbols at the front of the list. */
+ if (newsym->othersym)
+ {
+ newsym->next = add_sym_list;
+ if (!add_sym_list)
+ add_sym_tail = &newsym->next;
+ add_sym_list = newsym;
+ }
+ else
+ {
+ *add_sym_tail = newsym;
+ add_sym_tail = &newsym->next;
+ }
+ add_symbols++;
+ }
+ break;
+
case OPTION_CHANGE_START:
change_start = parse_vma (optarg, "--change-start");
break;
do_debug_sections = decompress;
break;
+ case OPTION_ELF_STT_COMMON:
+ if (strcasecmp (optarg, "yes") == 0)
+ do_elf_stt_common = elf_stt_common;
+ else if (strcasecmp (optarg, "no") == 0)
+ do_elf_stt_common = no_elf_stt_common;
+ else
+ fatal (_("unrecognized --elf-stt-common= option `%s'"),
+ optarg);
+ break;
+
case OPTION_GAP_FILL:
{
bfd_vma gap_fill_vma;