/* objcopy.c -- copy object file from input to output, optionally massaging it.
- Copyright (C) 1991-2019 Free Software Foundation, Inc.
+ Copyright (C) 1991-2020 Free Software Foundation, Inc.
This file is part of GNU Binutils.
long symval;
flagword flags;
char * section;
- char * othersym;
+ const char * othersym;
};
typedef struct section_rename
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_SET_VMA (1 << 2) /* Set the sections' VMA address. */
-#define SECTION_CONTEXT_ALTER_VMA (1 << 3) /* Increment or decrement the section's VMA address. */
-#define SECTION_CONTEXT_SET_LMA (1 << 4) /* Set the sections' LMA address. */
-#define SECTION_CONTEXT_ALTER_LMA (1 << 5) /* Increment or decrement the section's LMA address. */
-#define SECTION_CONTEXT_SET_FLAGS (1 << 6) /* Set the section's flags. */
-#define SECTION_CONTEXT_REMOVE_RELOCS (1 << 7) /* Remove relocations for this section. */
-#define SECTION_CONTEXT_SET_ALIGNMENT (1 << 8) /* Set alignment for section. */
+#define SECTION_CONTEXT_KEEP (1 << 2) /* Keep this section. */
+#define SECTION_CONTEXT_SET_VMA (1 << 3) /* Set the sections' VMA address. */
+#define SECTION_CONTEXT_ALTER_VMA (1 << 4) /* Increment or decrement the section's VMA address. */
+#define SECTION_CONTEXT_SET_LMA (1 << 5) /* Set the sections' LMA address. */
+#define SECTION_CONTEXT_ALTER_LMA (1 << 6) /* Increment or decrement the section's LMA address. */
+#define SECTION_CONTEXT_SET_FLAGS (1 << 7) /* Set the section's flags. */
+#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. */
OPTION_INTERLEAVE_WIDTH,
OPTION_KEEPGLOBAL_SYMBOLS,
OPTION_KEEP_FILE_SYMBOLS,
+ OPTION_KEEP_SECTION,
OPTION_KEEP_SYMBOLS,
OPTION_LOCALIZE_HIDDEN,
OPTION_LOCALIZE_SYMBOLS,
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
{"input-target", required_argument, 0, 'I'},
{"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
+ {"keep-section", required_argument, 0, OPTION_KEEP_SECTION},
{"keep-symbol", required_argument, 0, 'K'},
{"merge-notes", no_argument, 0, 'M'},
{"no-merge-notes", no_argument, 0, OPTION_NO_MERGE_NOTES},
{"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
{"keep-global-symbol", required_argument, 0, 'G'},
{"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
+ {"keep-section", required_argument, 0, OPTION_KEEP_SECTION},
{"keep-symbol", required_argument, 0, 'K'},
{"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
{"localize-hidden", no_argument, 0, OPTION_LOCALIZE_HIDDEN},
--only-keep-debug Strip everything but the debug information\n\
--extract-dwo Copy only DWO sections\n\
--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-file-symbols Do not strip file symbol(s)\n\
--localize-hidden Turn all ELF hidden symbols into locals\n\
-M --merge-notes Remove redundant entries in note sections (default)\n\
--no-merge-notes Do not attempt to remove redundant notes\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-file-symbols Do not strip file symbol(s)\n\
-w --wildcard Permit wildcard in symbol comparison\n\
PARSE_FLAG ("code", SEC_CODE);
PARSE_FLAG ("data", SEC_DATA);
PARSE_FLAG ("rom", SEC_ROM);
+ PARSE_FLAG ("exclude", SEC_EXCLUDE);
PARSE_FLAG ("share", SEC_COFF_SHARED);
PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
PARSE_FLAG ("merge", SEC_MERGE);
copy[len] = '\0';
non_fatal (_("unrecognized section flag `%s'"), copy);
fatal (_("supported flags: %s"),
- "alloc, load, noload, readonly, debug, code, data, rom, share, contents, merge, strings");
+ "alloc, load, noload, readonly, debug, code, data, rom, exclude, share, contents, merge, strings");
}
s = snext;
string can't be parsed. */
static flagword
-parse_symflags (const char *s, char **other)
+parse_symflags (const char *s, const char **other)
{
flagword ret;
const char *snext;
static bfd_boolean
is_strip_section_1 (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
{
+ if (find_section_list (bfd_section_name (sec), FALSE, SECTION_CONTEXT_KEEP)
+ != NULL)
+ return FALSE;
+
if (sections_removed || sections_copied)
{
struct section_list *p;
is_nondebug_keep_contents_section (bfd *ibfd, asection *isection)
{
/* Always keep ELF note sections. */
- if (ibfd->xvec->flavour == bfd_target_elf_flavour)
- return (elf_section_type (isection) == SHT_NOTE);
+ if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
+ return elf_section_type (isection) == SHT_NOTE;
/* Always keep the .buildid section for PE/COFF.
Strictly, this should be written "always keep the section storing the debug
directory", but that may be the .text section for objects produced by some
tools, which it is not sensible to keep. */
- if (ibfd->xvec->flavour == bfd_target_coff_flavour)
- return (strcmp (bfd_section_name (isection), ".buildid") == 0);
+ if (bfd_get_flavour (ibfd) == bfd_target_coff_flavour)
+ return strcmp (bfd_section_name (isection), ".buildid") == 0;
return FALSE;
}
return FALSE;
}
+/* Empty name is hopefully never a valid symbol name. */
+static const char * empty_name = "";
+
static bfd_boolean
need_sym_before (struct addsym_node **node, const char *sym)
{
{
if (!ptr->othersym)
break;
+ if (ptr->othersym == empty_name)
+ continue;
else if (strcmp (ptr->othersym, sym) == 0)
{
- free (ptr->othersym);
- ptr->othersym = ""; /* Empty name is hopefully never a valid symbol name. */
+ free ((char *) ptr->othersym);
+ ptr->othersym = empty_name;
*node = ptr;
return TRUE;
}
/* Check if we will remove the current leading character. */
rem_leading_char =
- (name[0] == bfd_get_symbol_leading_char (abfd))
- && (change_leading_char
- || (remove_leading_char
- && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
- || undefined
- || bfd_is_com_section (bfd_asymbol_section (sym)))));
+ (name[0] != '\0'
+ && name[0] == bfd_get_symbol_leading_char (abfd)
+ && (change_leading_char
+ || (remove_leading_char
+ && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
+ || undefined
+ || bfd_is_com_section (bfd_asymbol_section (sym))))));
/* Check if we will add a new leading character. */
add_leading_char =
if (add_leading_char || prefix_symbols_string)
{
char *n, *ptr;
+ size_t len = strlen (name) + 1;
- ptr = n = (char *) xmalloc (1 + strlen (prefix_symbols_string)
- + strlen (name) + 1);
+ if (add_leading_char)
+ len++;
+ if (prefix_symbols_string)
+ len += strlen (prefix_symbols_string);
+
+ ptr = n = (char *) xmalloc (len);
if (add_leading_char)
*ptr++ = bfd_get_symbol_leading_char (obfd);
{
if (ptr->othersym)
{
- if (strcmp (ptr->othersym, ""))
+ if (ptr->othersym != empty_name)
fatal (_("'before=%s' not found"), ptr->othersym);
}
else
bfd_vma start;
bfd_vma end;
} objcopy_internal_note;
-
+
#define DEBUG_MERGE 0
#if DEBUG_MERGE
pnote1->note.namesz - 3 : pnote2->note.namesz - 3);
if (cmp)
return cmp;
-
+
if (pnote1->end < pnote2->start)
return -1;
if (pnote1->start > pnote2->end)
return -1;
if (pnote1->end > pnote2->end)
return 1;
-
+ if (pnote1->end < pnote2->end)
+ return -1;
+
/* Put OPEN notes before function notes. */
if (is_open_note (pnote1) && ! is_open_note (pnote2))
return -1;
if (! is_open_note (pnote1) && is_open_note (pnote2))
return 1;
-
+
return 0;
}
return -1;
if (is_deleted_note (pnote2)) /* 1: F 2: O D */
- return 1;
+ return -1;
return 1; /* 1: F 2: O */
}
-
+
/* Sort by starting address. */
if (pnote1->start < pnote2->start)
return -1;
&& pnote2->note.namesz > 4
&& pnote1->note.namedata[3] != pnote2->note.namedata[3])
return pnote1->note.namedata[3] - pnote2->note.namedata[3];
-
+
return 0;
}
goto done;
}
}
-
+
/* Make a copy of the notes and convert to our internal format.
Minimum size of a note is 12 bytes. Also locate the version
notes and check them. */
address. */
end = (bfd_vma) -1;
break;
-
+
case 8:
if (! is_64bit (abfd))
{
start = bfd_get_64 (abfd, pnote->note.descdata);
end = bfd_get_64 (abfd, pnote->note.descdata + 8);
break;
-
+
default:
err = _("corrupt GNU build attribute note: bad description size");
goto done;
|| memcmp (back->note.namedata,
pnote->note.namedata, pnote->note.namesz) != 0)
break;
-
+
if (back->start == pnote->start
&& back->end == pnote->end)
{
if (! is_deleted_note (pnote))
merge_debug ("Unable to do anything with note at %#08lx\n",
(pnote->note.namedata - (char *) contents) - 12);
-#endif
+#endif
}
/* Resort the notes. */
bfd_vma prev_start = 0;
bfd_vma prev_end = 0;
- new = new_contents = xmalloc (size);
+ /* Not sure how, but the notes might grow in size.
+ (eg see PR 1774507). Allow for this here. */
+ new = new_contents = xmalloc (size * 2);
for (pnote = pnotes, old = contents;
pnote < pnotes_end;
pnote ++)
pnote->note.namesz
);
#endif
-
+
new_size = new - new_contents;
- memcpy (contents, new_contents, new_size);
- size = new_size;
+ if (new_size < size)
+ {
+ memcpy (contents, new_contents, new_size);
+ size = new_size;
+ }
free (new_contents);
done:
return size;
}
+static flagword
+check_new_section_flags (flagword flags, bfd * abfd, const char * secname)
+{
+ /* Only set the SEC_COFF_SHARED flag on COFF files.
+ The same bit value is used by ELF targets to indicate
+ compressed sections, and setting that flag here breaks
+ things. */
+ if ((flags & SEC_COFF_SHARED)
+ && bfd_get_flavour (abfd) != bfd_target_coff_flavour)
+ {
+ non_fatal (_("%s[%s]: Note - dropping 'share' flag as output format is not COFF"),
+ bfd_get_filename (abfd), secname);
+ flags &= ~ SEC_COFF_SHARED;
+ }
+ return flags;
+}
+
/* Copy object file IBFD onto OBFD.
Returns TRUE upon success, FALSE otherwise. */
void *dhandle;
enum bfd_architecture iarch;
unsigned int imach;
- unsigned int c, i;
+ unsigned int num_sec, i;
if (ibfd->xvec->byteorder != obfd->xvec->byteorder
&& ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
{
/* PR 17636: Call non-fatal so that we return to our parent who
may need to tidy temporary files. */
- non_fatal (_("Unable to change endianness of input file(s)"));
+ non_fatal (_("unable to change endianness of '%s'"),
+ bfd_get_archive_filename (ibfd));
+ 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 (ibfd->xvec->flavour != bfd_target_elf_flavour)
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
{
if ((do_debug_sections & compress) != 0
&& do_debug_sections != compress)
imach = bfd_get_mach (ibfd);
if (input_arch)
{
- if (bfd_get_arch_info (ibfd) == NULL
- || bfd_get_arch_info (ibfd)->arch == bfd_arch_unknown)
+ if (iarch == bfd_arch_unknown)
{
iarch = input_arch->arch;
imach = input_arch->mach;
non_fatal (_("Input file `%s' ignores binary architecture parameter."),
bfd_get_archive_filename (ibfd));
}
+ if (iarch == bfd_arch_unknown
+ && bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ && bfd_get_flavour (obfd) == bfd_target_elf_flavour)
+ {
+ const struct elf_backend_data *bed = get_elf_backend_data (obfd);
+ iarch = bed->arch;
+ imach = 0;
+ }
if (!bfd_set_arch_mach (obfd, iarch, imach)
&& (ibfd->target_defaulted
|| bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
pe_data_type *pe = pe_data (obfd);
/* Copy PE parameters before changing them. */
- if (ibfd->xvec->flavour == bfd_target_coff_flavour
+ if (bfd_get_flavour (ibfd) == bfd_target_coff_flavour
&& bfd_pei_p (ibfd))
pe->pe_opthdr = pe_data (ibfd)->pe_opthdr;
file_alignment, section_alignment);
}
+
+ if (preserve_dates
+ && bfd_get_flavour (ibfd) == bfd_target_coff_flavour
+ && bfd_pei_p (ibfd))
+ pe->timestamp = pe_data (ibfd)->coff.timestamp;
}
if (isympp)
pset = find_section_list (padd->name, FALSE,
SECTION_CONTEXT_SET_FLAGS);
if (pset != NULL)
- flags = pset->flags | SEC_HAS_CONTENTS;
+ {
+ flags = pset->flags | SEC_HAS_CONTENTS;
+ flags = check_new_section_flags (flags, obfd, padd->name);
+ }
else
flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
if (! is_mergeable_note_section (ibfd, osec))
continue;
+ /* If the section is going to be completly deleted then
+ do not bother to merge it. */
+ if (osec->output_section == NULL)
+ continue;
+
bfd_size_type size = bfd_section_size (osec);
if (size == 0)
{
bfd_nonfatal_message (NULL, ibfd, osec,
_("warning: could not load note section"));
- free (merged->contents);
free (merged);
continue;
}
merged->size = merge_gnu_build_notes (ibfd, osec, size,
merged->contents);
- if (merged->size == size)
- {
- /* Merging achieves nothing. */
- merge_debug ("Merge of section %s achieved nothing - skipping\n",
- bfd_section_name (osec));
- free (merged->contents);
- free (merged);
- continue;
- }
- if (osec->output_section == NULL
- || !bfd_set_section_size (osec->output_section, merged->size))
+ /* FIXME: Once we have read the contents in, we must write
+ them out again. So even if the mergeing has achieved
+ nothing we still add this entry to the merge list. */
+
+ if (size != merged->size
+ && !bfd_set_section_size (osec->output_section, merged->size))
{
bfd_nonfatal_message (NULL, obfd, osec,
_("warning: failed to set merged notes size"));
for (pdump = dump_sections; pdump != NULL; pdump = pdump->next)
{
+ FILE * f;
+ bfd_byte *contents;
+
osec = bfd_get_section_by_name (ibfd, pdump->name);
if (osec == NULL)
{
}
bfd_size_type size = bfd_section_size (osec);
- if (size == 0)
- {
- bfd_nonfatal_message (NULL, ibfd, osec,
- _("can't dump section - it is empty"));
- continue;
- }
+ /* Note - we allow the dumping of zero-sized sections,
+ creating an empty file. */
- FILE * f;
f = fopen (pdump->filename, FOPEN_WB);
if (f == NULL)
{
continue;
}
- bfd_byte *contents;
if (bfd_malloc_and_get_section (ibfd, osec, &contents))
{
- if (fwrite (contents, 1, size, f) != size)
+ if (size != 0 && fwrite (contents, 1, size, f) != size)
{
non_fatal (_("error writing section contents to %s (error: %s)"),
pdump->filename,
}
}
- c = bfd_count_sections (obfd);
- if (c != 0
+ num_sec = bfd_count_sections (obfd);
+ if (num_sec != 0
&& (gap_fill_set || pad_to_set))
{
asection **set;
increasing the section sizes as required to fill the gaps.
We write out the gap contents below. */
- osections = (asection **) xmalloc (c * sizeof (asection *));
+ osections = xmalloc (num_sec * sizeof (*osections));
set = osections;
bfd_map_over_sections (obfd, get_sections, &set);
- qsort (osections, c, sizeof (asection *), compare_section_lma);
+ qsort (osections, num_sec, sizeof (*osections), compare_section_lma);
- gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
- memset (gaps, 0, c * sizeof (bfd_size_type));
+ gaps = xmalloc (num_sec * sizeof (*gaps));
+ memset (gaps, 0, num_sec * sizeof (*gaps));
if (gap_fill_set)
{
- for (i = 0; i < c - 1; i++)
+ for (i = 0; i < num_sec - 1; i++)
{
flagword flags;
- bfd_size_type size;
- bfd_vma gap_start, gap_stop;
+ bfd_size_type size; /* Octets. */
+ bfd_vma gap_start, gap_stop; /* Octets. */
+ unsigned int opb1 = bfd_octets_per_byte (obfd, osections[i]);
+ unsigned int opb2 = bfd_octets_per_byte (obfd, osections[i+1]);
flags = bfd_section_flags (osections[i]);
if ((flags & SEC_HAS_CONTENTS) == 0
continue;
size = bfd_section_size (osections[i]);
- gap_start = bfd_section_lma (osections[i]) + size;
- gap_stop = bfd_section_lma (osections[i + 1]);
+ gap_start = bfd_section_lma (osections[i]) * opb1 + size;
+ gap_stop = bfd_section_lma (osections[i + 1]) * opb2;
if (gap_start < gap_stop)
{
if (!bfd_set_section_size (osections[i],
if (pad_to_set)
{
- bfd_vma lma;
- bfd_size_type size;
-
- lma = bfd_section_lma (osections[c - 1]);
- size = bfd_section_size (osections[c - 1]);
- if (lma + size < pad_to)
+ bfd_vma lma; /* Octets. */
+ bfd_size_type size; /* Octets. */
+ unsigned int opb = bfd_octets_per_byte (obfd, osections[num_sec - 1]);
+ bfd_vma _pad_to = pad_to * opb;
+
+ lma = bfd_section_lma (osections[num_sec - 1]) * opb;
+ size = bfd_section_size (osections[num_sec - 1]);
+ if (lma + size < _pad_to)
{
- if (!bfd_set_section_size (osections[c - 1], pad_to - lma))
+ if (!bfd_set_section_size (osections[num_sec - 1], _pad_to - lma))
{
- bfd_nonfatal_message (NULL, obfd, osections[c - 1],
+ bfd_nonfatal_message (NULL, obfd, osections[num_sec - 1],
_("can't add padding"));
status = 1;
}
else
{
- gaps[c - 1] = pad_to - (lma + size);
- if (max_gap < pad_to - (lma + size))
- max_gap = pad_to - (lma + size);
+ gaps[num_sec - 1] = _pad_to - (lma + size);
+ if (max_gap < _pad_to - (lma + size))
+ max_gap = _pad_to - (lma + size);
}
}
}
{
bfd_nonfatal_message
(NULL, obfd, osec,
- _("error: failed to copy merged notes into output"));
+ _("error: failed to locate merged notes"));
continue;
}
}
- if (! is_mergeable_note_section (obfd, osec))
+ if (merged->contents == NULL)
{
bfd_nonfatal_message
(NULL, obfd, osec,
- _("error: failed to copy merged notes into output"));
+ _("error: failed to merge notes"));
continue;
}
}
}
- if (gap_fill_set || pad_to_set)
+ if (gaps != NULL)
{
bfd_byte *buf;
buf = (bfd_byte *) xmalloc (max_gap);
memset (buf, gap_fill, max_gap);
- c = bfd_count_sections (obfd);
- for (i = 0; i < c; i++)
+ for (i = 0; i < num_sec; i++)
{
if (gaps[i] != 0)
{
status = 1;
return;
}
+
+ if (gnu_debuglink_filename != NULL)
+ {
+ non_fatal (_("--add-gnu-debuglink ignored for archive %s"),
+ bfd_get_filename (ibfd));
+ gnu_debuglink_filename = NULL;
+ }
+
/* This is a no-op on non-Coff targets. */
set_long_section_mode (obfd, ibfd, long_section_names);
flagword flags;
const char *err;
const char * name;
+ const char * new_name;
char *prefix = NULL;
bfd_boolean make_nobits;
unsigned int alignment;
/* Get the, possibly new, name of the output section. */
name = bfd_section_name (isection);
flags = bfd_section_flags (isection);
- name = find_section_rename (name, &flags);
+ if (bfd_get_flavour (ibfd) != bfd_get_flavour (obfd))
+ {
+ flags &= bfd_applicable_section_flags (ibfd);
+ flags &= bfd_applicable_section_flags (obfd);
+ }
+ new_name = find_section_rename (name, &flags);
+ if (new_name != name)
+ {
+ name = new_name;
+ flags = check_new_section_flags (flags, obfd, name);
+ }
/* Prefix sections. */
- if ((prefix_alloc_sections_string)
- && (bfd_section_flags (isection) & SEC_ALLOC))
+ if (prefix_alloc_sections_string
+ && (bfd_section_flags (isection) & SEC_ALLOC) != 0)
prefix = prefix_alloc_sections_string;
else if (prefix_sections_string)
prefix = prefix_sections_string;
p = find_section_list (bfd_section_name (isection), FALSE,
SECTION_CONTEXT_SET_FLAGS);
if (p != NULL)
- flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
+ {
+ flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
+ flags = check_new_section_flags (flags, obfd, bfd_section_name (isection));
+ }
else if (strip_symbols == STRIP_NONDEBUG
&& (flags & (SEC_ALLOC | SEC_GROUP)) != 0
&& !is_nondebug_keep_contents_section (ibfd, isection))
{
flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP);
- if (obfd->xvec->flavour == bfd_target_elf_flavour)
+ if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
{
make_nobits = TRUE;
alignment = p->alignment;
else
alignment = bfd_section_alignment (isection);
-
+
/* FIXME: This is probably not enough. If we change the LMA we
may have to recompute the header for the file as well. */
if (!bfd_set_section_alignment (osection, alignment))
if (gsym != NULL)
{
gsym->flags |= BSF_KEEP;
- if (ibfd->xvec->flavour == bfd_target_elf_flavour)
+ if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
elf_group_id (isection) = gsym;
}
}
status = 1;
bfd_nonfatal_message (NULL, ibfd, isection,
_("relocation count is negative"));
+ free (relpp);
return;
}
}
temp_relpp [temp_relcount++] = relpp [i];
}
relcount = temp_relcount;
- if (isection->orelocation == NULL)
+ if (relpp != isection->orelocation)
free (relpp);
relpp = temp_relpp;
}
if (relcount == 0)
{
osection->flags &= ~SEC_RELOC;
- free (relpp);
+ if (relpp != isection->orelocation)
+ free (relpp);
}
}
}
case 'R':
handle_remove_section_option (optarg);
break;
+ case OPTION_KEEP_SECTION:
+ find_section_list (optarg, TRUE, SECTION_CONTEXT_KEEP);
+ break;
case OPTION_REMOVE_RELOCS:
handle_remove_relocations_option (optarg);
break;
handle_remove_section_option (optarg);
break;
+ case OPTION_KEEP_SECTION:
+ find_section_list (optarg, TRUE, SECTION_CONTEXT_KEEP);
+ break;
+
case OPTION_REMOVE_RELOCS:
handle_remove_relocations_option (optarg);
break;
s = strchr (optarg, '=');
if (s == NULL)
fatal (_("bad format for --set-section-alignment: argument needed"));
-
+
align = atoi (s + 1);
if (align <= 0)
fatal (_("bad format for --set-section-alignment: numeric argument needed"));
align >>= 1;
++palign;
}
-
+
if (align != 1)
/* Number has more than on 1, i.e. wasn't a power of 2. */
fatal (_("bad format for --set-section-alignment: alignment is not a power of two"));
p->alignment = palign;
}
break;
-
+
case OPTION_RENAME_SECTION:
{
flagword flags;