* objcopy.c (gap_fill_set, gap_fill): New static variables.
(copy_options): Accept --gap-fill. (copy_usage): Mention --gap-fill. (copy_object): Support --gap-fill. (get_sections, compare_section_vma): New static functions. (copy_main): Handle --gap-fill. * binutils.texi, objcopy.1: Document --gap-fill.
This commit is contained in:
parent
3066e752a5
commit
596d99ba32
@ -1,3 +1,13 @@
|
|||||||
|
Thu Oct 20 13:51:31 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
|
||||||
|
|
||||||
|
* objcopy.c (gap_fill_set, gap_fill): New static variables.
|
||||||
|
(copy_options): Accept --gap-fill.
|
||||||
|
(copy_usage): Mention --gap-fill.
|
||||||
|
(copy_object): Support --gap-fill.
|
||||||
|
(get_sections, compare_section_vma): New static functions.
|
||||||
|
(copy_main): Handle --gap-fill.
|
||||||
|
* binutils.texi, objcopy.1: Document --gap-fill.
|
||||||
|
|
||||||
Wed Oct 19 14:09:16 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
|
Wed Oct 19 14:09:16 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
|
||||||
|
|
||||||
* Makefile.in (check): Add a dummy else clause to the if
|
* Makefile.in (check): Add a dummy else clause to the if
|
||||||
|
@ -747,8 +747,8 @@ objcopy [ -F @var{bfdname} | --target=@var{bfdname} ]
|
|||||||
[ -b @var{byte} | --byte=@var{byte} ]
|
[ -b @var{byte} | --byte=@var{byte} ]
|
||||||
[ -i @var{interleave} | --interleave=@var{interleave} ]
|
[ -i @var{interleave} | --interleave=@var{interleave} ]
|
||||||
[ -R @var{sectionname} | --remove-section=@var{sectionname} ]
|
[ -R @var{sectionname} | --remove-section=@var{sectionname} ]
|
||||||
[ --set-start=@var{val} ] [ --adjust-start=@var{incr} ]
|
[ --gap-fill=@var{val} ] [ --set-start=@var{val} ]
|
||||||
[ --adjust-vma=@var{incr} ]
|
[ --adjust-start=@var{incr} ] [ --adjust-vma=@var{incr} ]
|
||||||
[ --adjust-section-vma=@var{section}@{=,+,-@}@var{val} ]
|
[ --adjust-section-vma=@var{section}@{=,+,-@}@var{val} ]
|
||||||
[ --adjust-warnings ] [ --no-adjust-warnings ]
|
[ --adjust-warnings ] [ --no-adjust-warnings ]
|
||||||
[ -v | --verbose ] [ -V | --version ] [ --help ]
|
[ -v | --verbose ] [ -V | --version ] [ --help ]
|
||||||
@ -846,6 +846,11 @@ copy with the @var{-b} or @samp{--byte} option. The default is 4.
|
|||||||
@code{objcopy} ignores this option if you do not specify either @samp{-b} or
|
@code{objcopy} ignores this option if you do not specify either @samp{-b} or
|
||||||
@samp{--byte}.
|
@samp{--byte}.
|
||||||
|
|
||||||
|
@item --gap-fill @var{val}
|
||||||
|
Fill gaps between sections with @var{val}. This is done by increasing
|
||||||
|
the size of the section with the lower address, and filling in the extra
|
||||||
|
space created with @var{val}.
|
||||||
|
|
||||||
@item --set-start @var{val}
|
@item --set-start @var{val}
|
||||||
Set the address of the new file to @var{val}. Not all object file
|
Set the address of the new file to @var{val}. Not all object file
|
||||||
formats support setting the start address.
|
formats support setting the start address.
|
||||||
|
@ -25,6 +25,7 @@ objcopy \- copy and translate object files
|
|||||||
.RB "[\|" \-X\ |\ \-\-discard\-locals\fR "\|]"
|
.RB "[\|" \-X\ |\ \-\-discard\-locals\fR "\|]"
|
||||||
.RB "[\|" \-b\ \fIbyte\fP |\ \-\-byte=\fIbyte\fP "\|]"
|
.RB "[\|" \-b\ \fIbyte\fP |\ \-\-byte=\fIbyte\fP "\|]"
|
||||||
.RB "[\|" \-i\ \fIinterleave\fP |\ \-\-interleave=\fIinterleave\fP "\|]"
|
.RB "[\|" \-i\ \fIinterleave\fP |\ \-\-interleave=\fIinterleave\fP "\|]"
|
||||||
|
.RB "[\|" \-\-gap\-fill=\fIval\fP "\|]"
|
||||||
.RB "[\|" \-\-set\-start=\fIval\fP "\|]"
|
.RB "[\|" \-\-set\-start=\fIval\fP "\|]"
|
||||||
.RB "[\|" \-\-adjust\-start=\fIincr\fP "\|]"
|
.RB "[\|" \-\-adjust\-start=\fIincr\fP "\|]"
|
||||||
.RB "[\|" \-\-adjust\-vma=\fIincr\fP "\|]"
|
.RB "[\|" \-\-adjust\-vma=\fIincr\fP "\|]"
|
||||||
@ -136,6 +137,11 @@ Only copy one out of every \fIinterleave\fP bytes. Which one to copy is
|
|||||||
selected by the \fB\-b\fP or \fB\-\-byte\fP option. The default is 4.
|
selected by the \fB\-b\fP or \fB\-\-byte\fP option. The default is 4.
|
||||||
The interleave is ignored if neither \fB\-b\fP nor \fB\-\-byte\fP is given.
|
The interleave is ignored if neither \fB\-b\fP nor \fB\-\-byte\fP is given.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-\-gap\-fill=\fIval
|
||||||
|
Fill gaps between sections with \fIval\fP. This is done by increasing
|
||||||
|
the size of the section with the lower address, and filling in the extra
|
||||||
|
space created with \fIval\fP.
|
||||||
|
.TP
|
||||||
.B \fB\-\-set\-start=\fIval
|
.B \fB\-\-set\-start=\fIval
|
||||||
Set the start address of the new file to \fIval\fP. Not all object
|
Set the start address of the new file to \fIval\fP. Not all object
|
||||||
file formats support setting the start address.
|
file formats support setting the start address.
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
static bfd_vma parse_vma PARAMS ((const char *, const char *));
|
static bfd_vma parse_vma PARAMS ((const char *, const char *));
|
||||||
static void setup_section PARAMS ((bfd *, asection *, PTR));
|
static void setup_section PARAMS ((bfd *, asection *, PTR));
|
||||||
static void copy_section PARAMS ((bfd *, asection *, PTR));
|
static void copy_section PARAMS ((bfd *, asection *, PTR));
|
||||||
|
static void get_sections PARAMS ((bfd *, asection *, PTR));
|
||||||
|
static int compare_section_vma PARAMS ((const PTR, const PTR));
|
||||||
static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR));
|
static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR));
|
||||||
|
|
||||||
#define nonfatal(s) {bfd_nonfatal(s); status = 1; return;}
|
#define nonfatal(s) {bfd_nonfatal(s); status = 1; return;}
|
||||||
@ -91,6 +93,10 @@ static bfd_vma set_start;
|
|||||||
static bfd_vma adjust_section_vma = 0;
|
static bfd_vma adjust_section_vma = 0;
|
||||||
static struct section_list *adjust_sections;
|
static struct section_list *adjust_sections;
|
||||||
|
|
||||||
|
/* Filling gaps between sections. */
|
||||||
|
static boolean gap_fill_set = false;
|
||||||
|
static bfd_byte gap_fill;
|
||||||
|
|
||||||
/* Options to handle if running as "strip". */
|
/* Options to handle if running as "strip". */
|
||||||
|
|
||||||
static struct option strip_options[] =
|
static struct option strip_options[] =
|
||||||
@ -120,7 +126,8 @@ static struct option strip_options[] =
|
|||||||
#define OPTION_ADJUST_VMA (OPTION_ADJUST_START + 1)
|
#define OPTION_ADJUST_VMA (OPTION_ADJUST_START + 1)
|
||||||
#define OPTION_ADJUST_SECTION_VMA (OPTION_ADJUST_VMA + 1)
|
#define OPTION_ADJUST_SECTION_VMA (OPTION_ADJUST_VMA + 1)
|
||||||
#define OPTION_ADJUST_WARNINGS (OPTION_ADJUST_SECTION_VMA + 1)
|
#define OPTION_ADJUST_WARNINGS (OPTION_ADJUST_SECTION_VMA + 1)
|
||||||
#define OPTION_NO_ADJUST_WARNINGS (OPTION_ADJUST_WARNINGS + 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_SET_START (OPTION_NO_ADJUST_WARNINGS + 1)
|
||||||
|
|
||||||
static struct option copy_options[] =
|
static struct option copy_options[] =
|
||||||
@ -133,6 +140,7 @@ static struct option copy_options[] =
|
|||||||
{"discard-all", no_argument, 0, 'x'},
|
{"discard-all", no_argument, 0, 'x'},
|
||||||
{"discard-locals", no_argument, 0, 'X'},
|
{"discard-locals", no_argument, 0, 'X'},
|
||||||
{"format", required_argument, 0, 'F'}, /* Obsolete */
|
{"format", required_argument, 0, 'F'}, /* Obsolete */
|
||||||
|
{"gap-fill", required_argument, 0, OPTION_GAP_FILL},
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
|
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
|
||||||
{"input-target", required_argument, 0, 'I'},
|
{"input-target", required_argument, 0, 'I'},
|
||||||
@ -170,10 +178,11 @@ Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n\
|
|||||||
[-R section] [-i interleave] [--interleave=interleave] [--byte=byte]\n\
|
[-R section] [-i interleave] [--interleave=interleave] [--byte=byte]\n\
|
||||||
[--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
|
[--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
|
||||||
[--strip-all] [--strip-debug] [--discard-all] [--discard-locals]\n\
|
[--strip-all] [--strip-debug] [--discard-all] [--discard-locals]\n\
|
||||||
[--remove-section=section] [--set-start=val] [--adjust-start=incr]\n\
|
[--remove-section=section] [--gap-fill=val] [--set-start=val]\n\
|
||||||
[--adjust-vma=incr] [--adjust-section-vma=section{=,+,-}val]\n\
|
[--adjust-start=incr] [--adjust-vma=incr]\n\
|
||||||
[--adjust-warnings] [--no-adjust-warnings] [--verbose] [--version]\n\
|
[--adjust-section-vma=section{=,+,-}val] [--adjust-warnings]\n\
|
||||||
[--help] in-file [out-file]\n",
|
[--no-adjust-warnings] [--verbose] [--version] [--help]\n\
|
||||||
|
in-file [out-file]\n",
|
||||||
program_name);
|
program_name);
|
||||||
exit (status);
|
exit (status);
|
||||||
}
|
}
|
||||||
@ -302,6 +311,9 @@ copy_object (ibfd, obfd)
|
|||||||
{
|
{
|
||||||
bfd_vma start;
|
bfd_vma start;
|
||||||
long symcount;
|
long symcount;
|
||||||
|
asection **osections = NULL;
|
||||||
|
bfd_size_type *gaps = NULL;
|
||||||
|
bfd_size_type max_gap = 0;
|
||||||
|
|
||||||
if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
|
if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
|
||||||
{
|
{
|
||||||
@ -349,6 +361,58 @@ copy_object (ibfd, obfd)
|
|||||||
any output is done. Thus, we traverse all sections multiple times. */
|
any output is done. Thus, we traverse all sections multiple times. */
|
||||||
bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
|
bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
|
||||||
|
|
||||||
|
if (gap_fill_set)
|
||||||
|
{
|
||||||
|
asection **set;
|
||||||
|
unsigned int c, i;
|
||||||
|
|
||||||
|
/* We must fill in gaps between the sections. We do this by
|
||||||
|
grabbing a list of the sections, sorting them by VMA, and
|
||||||
|
adding new sections to occupy any gaps. */
|
||||||
|
|
||||||
|
c = bfd_count_sections (obfd);
|
||||||
|
osections = (asection **) xmalloc (c * sizeof (asection *));
|
||||||
|
set = osections;
|
||||||
|
bfd_map_over_sections (obfd, get_sections, (void *) &set);
|
||||||
|
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Symbol filtering must happen after the output sections have
|
/* Symbol filtering must happen after the output sections have
|
||||||
been created, but before their contents are set. */
|
been created, but before their contents are set. */
|
||||||
if (strip_symbols == strip_all && discard_locals == locals_undef)
|
if (strip_symbols == strip_all && discard_locals == locals_undef)
|
||||||
@ -396,6 +460,49 @@ copy_object (ibfd, obfd)
|
|||||||
/* This has to happen after the symbol table has been set. */
|
/* This has to happen after the symbol table has been set. */
|
||||||
bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
|
bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
|
||||||
|
|
||||||
|
if (gap_fill_set)
|
||||||
|
{
|
||||||
|
bfd_byte *buf;
|
||||||
|
int c, i;
|
||||||
|
|
||||||
|
/* Fill in the gaps. */
|
||||||
|
|
||||||
|
if (max_gap > 8192)
|
||||||
|
max_gap = 8192;
|
||||||
|
buf = (bfd_byte *) xmalloc (max_gap);
|
||||||
|
memset (buf, gap_fill, max_gap);
|
||||||
|
|
||||||
|
c = bfd_count_sections (obfd);
|
||||||
|
for (i = 0; i < c - 1; i++)
|
||||||
|
{
|
||||||
|
if (gaps[i] != 0)
|
||||||
|
{
|
||||||
|
bfd_size_type left;
|
||||||
|
file_ptr off;
|
||||||
|
|
||||||
|
left = gaps[i];
|
||||||
|
off = bfd_section_size (obfd, osections[i]) - left;
|
||||||
|
while (left > 0)
|
||||||
|
{
|
||||||
|
bfd_size_type now;
|
||||||
|
|
||||||
|
if (left > 8192)
|
||||||
|
now = 8192;
|
||||||
|
else
|
||||||
|
now = left;
|
||||||
|
if (! bfd_set_section_contents (obfd, osections[i], buf,
|
||||||
|
off, now))
|
||||||
|
{
|
||||||
|
nonfatal (bfd_get_filename (obfd));
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
left -= now;
|
||||||
|
off += now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Allow the BFD backend to copy any private data it understands
|
/* Allow the BFD backend to copy any private data it understands
|
||||||
from the input BFD to the output BFD. This is done last to
|
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
|
permit the routine to look at the filtered symbol table, which is
|
||||||
@ -771,6 +878,39 @@ copy_section (ibfd, isection, obfdarg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get all the sections. This is used when --gap-fill is used. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_sections (obfd, osection, secppparg)
|
||||||
|
bfd *obfd;
|
||||||
|
asection *osection;
|
||||||
|
PTR secppparg;
|
||||||
|
{
|
||||||
|
asection ***secppp = (asection ***) secppparg;
|
||||||
|
|
||||||
|
**secppp = osection;
|
||||||
|
++(*secppp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sort sections by VMA. This is called via qsort, and is used when
|
||||||
|
--gap-fill is used. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_section_vma (arg1, arg2)
|
||||||
|
const PTR arg1;
|
||||||
|
const PTR arg2;
|
||||||
|
{
|
||||||
|
const asection **sec1 = (const asection **) arg1;
|
||||||
|
const asection **sec2 = (const asection **) arg2;
|
||||||
|
|
||||||
|
if ((*sec1)->vma > (*sec2)->vma)
|
||||||
|
return 1;
|
||||||
|
else if ((*sec1)->vma < (*sec2)->vma)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mark all the symbols which will be used in output relocations with
|
/* Mark all the symbols which will be used in output relocations with
|
||||||
the BSF_KEEP flag so that those symbols will not be stripped.
|
the BSF_KEEP flag so that those symbols will not be stripped.
|
||||||
|
|
||||||
@ -1121,6 +1261,22 @@ copy_main (argc, argv)
|
|||||||
case OPTION_ADJUST_WARNINGS:
|
case OPTION_ADJUST_WARNINGS:
|
||||||
adjust_warn = true;
|
adjust_warn = true;
|
||||||
break;
|
break;
|
||||||
|
case OPTION_GAP_FILL:
|
||||||
|
{
|
||||||
|
bfd_vma gap_fill_vma;
|
||||||
|
|
||||||
|
gap_fill_vma = parse_vma (optarg, "--gap-fill");
|
||||||
|
gap_fill = (bfd_byte) gap_fill_vma;
|
||||||
|
if ((bfd_vma) gap_fill != gap_fill_vma)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: warning: truncating gap-fill from 0x",
|
||||||
|
program_name);
|
||||||
|
fprintf_vma (stderr, gap_fill_vma);
|
||||||
|
fprintf (stderr, "to 0x%x\n", (unsigned int) gap_fill);
|
||||||
|
}
|
||||||
|
gap_fill_set = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case OPTION_NO_ADJUST_WARNINGS:
|
case OPTION_NO_ADJUST_WARNINGS:
|
||||||
adjust_warn = false;
|
adjust_warn = false;
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user