* objcopy.c (main): Fix is_strip test. From

pirker@eiunix.tuwien.ac.at (Martin Pirker).
This commit is contained in:
Ian Lance Taylor 1994-11-17 20:12:51 +00:00
parent 60822a364f
commit 87a15686e4
2 changed files with 144 additions and 55 deletions

View File

@ -1,5 +1,14 @@
Thu Nov 17 15:00:13 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
* objcopy.c (main): Fix is_strip test. From
pirker@eiunix.tuwien.ac.at (Martin Pirker).
Tue Nov 8 13:12:54 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
* objdump.c (display_target_list, display_info_table): Pass an
array to tmparg, rather than NULL, since some systems can't handle
NULL.
* objcopy.c (copy_archive): Keep a list of the names of the
temporary files we created. Close each input BFD after we open
its successor.

View File

@ -95,7 +95,11 @@ static struct section_list *adjust_sections;
/* Filling gaps between sections. */
static boolean gap_fill_set = false;
static bfd_byte gap_fill;
static bfd_byte gap_fill = 0;
/* Pad to a given address. */
static boolean pad_to_set = false;
static bfd_vma pad_to;
/* Options to handle if running as "strip". */
@ -128,7 +132,8 @@ static struct option strip_options[] =
#define OPTION_ADJUST_WARNINGS (OPTION_ADJUST_SECTION_VMA + 1)
#define OPTION_GAP_FILL (OPTION_ADJUST_WARNINGS + 1)
#define OPTION_NO_ADJUST_WARNINGS (OPTION_GAP_FILL + 1)
#define OPTION_SET_START (OPTION_NO_ADJUST_WARNINGS + 1)
#define OPTION_PAD_TO (OPTION_NO_ADJUST_WARNINGS + 1)
#define OPTION_SET_START (OPTION_PAD_TO + 1)
static struct option copy_options[] =
{
@ -148,6 +153,7 @@ static struct option copy_options[] =
{"no-adjust-warnings", no_argument, 0, OPTION_NO_ADJUST_WARNINGS},
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
{"output-target", required_argument, 0, 'O'},
{"pad-to", required_argument, 0, OPTION_PAD_TO},
{"remove-section", required_argument, 0, 'R'},
{"set-start", required_argument, 0, OPTION_SET_START},
{"strip-all", no_argument, 0, 'S'},
@ -178,8 +184,8 @@ Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n\
[-R section] [-i interleave] [--interleave=interleave] [--byte=byte]\n\
[--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
[--strip-all] [--strip-debug] [--discard-all] [--discard-locals]\n\
[--remove-section=section] [--gap-fill=val] [--set-start=val]\n\
[--adjust-start=incr] [--adjust-vma=incr]\n\
[--remove-section=section] [--gap-fill=val] [--pad-to=address]\n\
[--set-start=val] [--adjust-start=incr] [--adjust-vma=incr]\n\
[--adjust-section-vma=section{=,+,-}val] [--adjust-warnings]\n\
[--no-adjust-warnings] [--verbose] [--version] [--help]\n\
in-file [out-file]\n",
@ -361,14 +367,16 @@ copy_object (ibfd, obfd)
any output is done. Thus, we traverse all sections multiple times. */
bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
if (gap_fill_set)
if (gap_fill_set || pad_to_set)
{
asection **set;
unsigned int c, i;
/* We must fill in gaps between the sections. We do this by
/* We must fill in gaps between the sections and/or we must pad
the last section to a specified address. We do this by
grabbing a list of the sections, sorting them by VMA, and
adding new sections to occupy any gaps. */
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 *));
@ -378,39 +386,69 @@ copy_object (ibfd, obfd)
qsort (osections, c, sizeof (asection *), compare_section_vma);
gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
for (i = 0; i < c - 1; i++)
memset (gaps, 0, c * sizeof (bfd_size_type));
if (gap_fill_set)
{
flagword flags;
bfd_size_type size;
bfd_vma gap_start, gap_stop;
flags = bfd_get_section_flags (obfd, osections[i]);
if ((flags & SEC_HAS_CONTENTS) == 0
|| (flags & SEC_LOAD) == 0)
continue;
size = bfd_section_size (obfd, osections[i]);
gap_start = bfd_section_vma (obfd, osections[i]) + size;
gap_stop = bfd_section_vma (obfd, osections[i + 1]);
if (gap_start >= gap_stop)
gaps[i] = 0;
else
for (i = 0; i < c - 1; i++)
{
if (! bfd_set_section_size (obfd, osections[i],
size + (gap_stop - gap_start)))
flagword flags;
bfd_size_type size;
bfd_vma gap_start, gap_stop;
flags = bfd_get_section_flags (obfd, osections[i]);
if ((flags & SEC_HAS_CONTENTS) == 0
|| (flags & SEC_LOAD) == 0)
continue;
size = bfd_section_size (obfd, osections[i]);
gap_start = bfd_section_vma (obfd, osections[i]) + size;
gap_stop = bfd_section_vma (obfd, osections[i + 1]);
if (gap_start < gap_stop)
{
fprintf (stderr, "%s: Can't fill gap after %s: %s\n",
program_name,
bfd_get_section_name (obfd, osections[i]),
bfd_errmsg (bfd_get_error()));
status = 1;
break;
if (! bfd_set_section_size (obfd, osections[i],
size + (gap_stop - gap_start)))
{
fprintf (stderr, "%s: Can't fill gap after %s: %s\n",
program_name,
bfd_get_section_name (obfd, osections[i]),
bfd_errmsg (bfd_get_error()));
status = 1;
break;
}
gaps[i] = gap_stop - gap_start;
if (max_gap < gap_stop - gap_start)
max_gap = gap_stop - gap_start;
}
gaps[i] = gap_stop - gap_start;
if (max_gap < gap_stop - gap_start)
max_gap = gap_stop - gap_start;
}
}
if (pad_to_set)
{
bfd_vma vma;
bfd_size_type size;
vma = bfd_section_vma (obfd, osections[c - 1]);
size = bfd_section_size (obfd, osections[c - 1]);
if (vma + size < pad_to)
{
if (! bfd_set_section_size (obfd, osections[c - 1],
pad_to - vma))
{
fprintf (stderr, "%s: Can't add padding to %s: %s\n",
program_name,
bfd_get_section_name (obfd, osections[c - 1]),
bfd_errmsg (bfd_get_error ()));
status = 1;
}
else
{
gaps[c - 1] = pad_to - (vma + size);
if (max_gap < pad_to - (vma + size))
max_gap = pad_to - (vma + size);
}
}
}
}
/* Symbol filtering must happen after the output sections have
@ -460,7 +498,7 @@ copy_object (ibfd, obfd)
/* This has to happen after the symbol table has been set. */
bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
if (gap_fill_set)
if (gap_fill_set || pad_to_set)
{
bfd_byte *buf;
int c, i;
@ -473,7 +511,7 @@ copy_object (ibfd, obfd)
memset (buf, gap_fill, max_gap);
c = bfd_count_sections (obfd);
for (i = 0; i < c - 1; i++)
for (i = 0; i < c; i++)
{
if (gaps[i] != 0)
{
@ -541,6 +579,11 @@ copy_archive (ibfd, obfd, output_target)
bfd *obfd;
char *output_target;
{
struct name_list
{
struct name_list *next;
char *name;
} *list, *l;
bfd **ptr = &obfd->archive_head;
bfd *this_element;
char *dir = make_tempname (bfd_get_filename (obfd));
@ -549,13 +592,20 @@ copy_archive (ibfd, obfd, output_target)
mkdir (dir, 0700);
obfd->has_armap = ibfd->has_armap;
list = NULL;
this_element = bfd_openr_next_archived_file (ibfd, NULL);
ibfd->archive_head = this_element;
while (this_element != (bfd *) NULL)
{
/* Create an output file for this member. */
char *output_name = cat (dir, "/", bfd_get_filename(this_element));
bfd *output_bfd = bfd_openw (output_name, output_target);
bfd *last_element;
l = (struct name_list *) xmalloc (sizeof (struct name_list));
l->name = output_name;
l->next = list;
list = l;
if (output_bfd == (bfd *) NULL)
{
@ -572,14 +622,18 @@ copy_archive (ibfd, obfd, output_target)
}
bfd_close (output_bfd);
/* Open the newly output file and attatch to our list. */
/* Open the newly output file and attach to our list. */
output_bfd = bfd_openr (output_name, output_target);
/* Mark it for deletion. */
*ptr = output_bfd;
ptr = &output_bfd->next;
this_element->next = bfd_openr_next_archived_file (ibfd, this_element);
this_element = this_element->next;
last_element = this_element;
this_element = bfd_openr_next_archived_file (ibfd, last_element);
bfd_close (last_element);
}
*ptr = (bfd *) NULL;
@ -588,16 +642,11 @@ copy_archive (ibfd, obfd, output_target)
nonfatal (bfd_get_filename (obfd));
}
/* Delete all the files that we opened.
Construct their names again, unfortunately, but
we're about to exit anyway. */
for (this_element = ibfd->archive_head;
this_element != (bfd *) NULL;
this_element = this_element->next)
{
unlink (cat (dir, "/", bfd_get_filename (this_element)));
}
/* Delete all the files that we opened. */
for (l = list; l != NULL; l = l->next)
unlink (l->name);
rmdir (dir);
if (!bfd_close (ibfd))
{
nonfatal (bfd_get_filename (ibfd));
@ -878,7 +927,8 @@ copy_section (ibfd, isection, obfdarg)
}
}
/* Get all the sections. This is used when --gap-fill is used. */
/* Get all the sections. This is used when --gap-fill or --pad-to is
used. */
static void
get_sections (obfd, osection, secppparg)
@ -893,7 +943,8 @@ get_sections (obfd, osection, secppparg)
}
/* Sort sections by VMA. This is called via qsort, and is used when
--gap-fill is used. */
--gap-fill or --pad-to is used. We force non loadable or empty
sections to the front, where they are easier to ignore. */
static int
compare_section_vma (arg1, arg2)
@ -902,13 +953,38 @@ compare_section_vma (arg1, arg2)
{
const asection **sec1 = (const asection **) arg1;
const asection **sec2 = (const asection **) arg2;
flagword flags1, flags2;
/* Sort non loadable sections to the front. */
flags1 = (*sec1)->flags;
flags2 = (*sec2)->flags;
if ((flags1 & SEC_HAS_CONTENTS) == 0
|| (flags1 & SEC_LOAD) == 0)
{
if ((flags2 & SEC_HAS_CONTENTS) != 0
&& (flags2 & SEC_LOAD) != 0)
return -1;
}
else
{
if ((flags2 & SEC_HAS_CONTENTS) == 0
|| (flags2 & SEC_LOAD) == 0)
return 1;
}
/* Sort sections by VMA. */
if ((*sec1)->vma > (*sec2)->vma)
return 1;
else if ((*sec1)->vma < (*sec2)->vma)
return -1;
else
return 0;
/* Sort sections with the same VMA by size. */
if ((*sec1)->_raw_size > (*sec2)->_raw_size)
return 1;
else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
return -1;
return 0;
}
/* Mark all the symbols which will be used in output relocations with
@ -1280,6 +1356,10 @@ copy_main (argc, argv)
case OPTION_NO_ADJUST_WARNINGS:
adjust_warn = false;
break;
case OPTION_PAD_TO:
pad_to = parse_vma (optarg, "--pad-to");
pad_to_set = true;
break;
case OPTION_SET_START:
set_start = parse_vma (optarg, "--set-start");
set_start_set = true;
@ -1373,7 +1453,7 @@ main (argc, argv)
if (is_strip < 0)
{
int i = strlen (program_name);
is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip"));
is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip") == 0);
}
if (is_strip)