* objcopy.c (filter_bytes): New function.

(copy_section): Call it.
	(copy_options, copy_usage, copy_main): Add --byte option to
	activate it.  Appropriate the -b option (which was an undocumented
	synonym for -F) for it, also.  Add --interleave, -i option for
	additional control.
	(setup_section, copy_section, mangle_section): Renamed with no `s'
	on the end.
	* objcopy.1, binutils.texi: Document the new options.

	* objdump.c (display_target_tables, display_target_list):
	New functions broken out of display_info.
	Eliminate some magic constants.  Use more meaningful variable names.
	(dump_bfd_header): New function broken out of display_bfd.
	(dump_section_header): New function broken out of dump_headers.
	(remove_useless_symbols): Don't shadow global variable name with
	parameter.
	(objdump_print_address): Fix backward test.
This commit is contained in:
David MacKenzie 1994-01-26 22:11:18 +00:00
parent d6d4e4c3d0
commit f7b839f7cd
5 changed files with 425 additions and 284 deletions

View File

@ -1,3 +1,24 @@
Wed Jan 26 13:13:18 1994 David J. Mackenzie (djm@thepub.cygnus.com)
* objcopy.c (filter_bytes): New function.
(copy_section): Call it.
(copy_options, copy_usage, copy_main): Add --byte option to
activate it. Appropriate the -b option (which was an undocumented
synonym for -F) for it, also. Add --interleave, -i option for
additional control.
(setup_section, copy_section, mangle_section): Renamed with no `s'
on the end.
* objcopy.1, binutils.texi: Document the new options.
* objdump.c (display_target_tables, display_target_list):
New functions broken out of display_info.
Eliminate some magic constants. Use more meaningful variable names.
(dump_bfd_header): New function broken out of display_bfd.
(dump_section_header): New function broken out of dump_headers.
(remove_useless_symbols): Don't shadow global variable name with
parameter.
(objdump_print_address): Fix backward test.
Tue Jan 25 19:40:54 1994 Stan Shebs (shebs@andros.cygnus.com)
* bucomm.c (print_arelt_descr): Change decl of `when' to time_t.

View File

@ -731,8 +731,9 @@ objcopy [ -F @var{bfdname} | --target=@var{bfdname} ]
[ -O @var{bfdname} | --output-target=@var{bfdname} ]
[ -S | --strip-all ] [ -g | --strip-debug ]
[ -x | --discard-all ] [ -X | --discard-locals ]
[ -b @var{byte} | --byte=@var{byte} ] [ -v | --verbose ]
[ -V | --version ] [ --help ]
[ -b @var{byte} | --byte=@var{byte} ]
[ -i @var{interleave} | --interleave=@var{interleave} ]
[ -v | --verbose ] [ -V | --version ] [ --help ]
@var{infile} [@var{outfile}]
@end smallexample
@ -793,9 +794,17 @@ Do not copy compiler-generated local symbols.
@item -b @var{byte}
@itemx --byte=@var{byte}
Keep only every @var{byte}th byte of the input file (header data is not
affected). @var{byte} can be in the range from 0 to 3. This option is
useful for creating files to program 4 ROMs to create 32-bit words. It
is typically used with an @code{srec} output target.
affected). @var{byte} can be in the range from 0 to @var{interleave}-1,
where @var{interleave} is given by the @samp{-i} or @samp{--interleave}
option, or the default of 4. This option is useful for creating files
to program ROMs. It is typically used with an @code{srec} output
target.
@item -i @var{interleave}
@itemx --interleave=@var{interleave}
Only copy one out of every @var{interleave} bytes. Which one to copy is
selected by the @var{-b} or @samp{--byte} option. The default is 4.
The interleave is ignored if neither @samp{-b} nor @samp{--byte} is given.
@item -V
@itemx --version

View File

@ -8,7 +8,7 @@
..
.SH NAME
objcopy\(em\&copy and translate object files
objcopy \- copy and translate object files
.SH SYNOPSIS
.hy 0
@ -22,6 +22,8 @@ objcopy\(em\&copy and translate object files
.RB "[\|" \-g\ |\ \-\-strip\-debug\fR "\|]"
.RB "[\|" \-x\ |\ \-\-discard\-all\fR "\|]"
.RB "[\|" \-X\ |\ \-\-discard\-locals\fR "\|]"
.RB "[\|" \-b\ \fIbyte\fP |\ \-\-byte=\fIbyte\fP "\|]"
.RB "[\|" \-i\ \fIinterleave\fP |\ \-\-interleave=\fIinterleave\fP "\|]"
.RB "[\|" \-v\ |\ \-\-verbose\fR "\|]"
.RB "[\|" \-V\ |\ \-\-version\fR "\|]"
.RB "[\|" \-\-help\fR "\|]"
@ -85,6 +87,17 @@ Do not copy non-global symbols from the source file.
Do not copy compiler-generated local symbols. (These usually start
with "L" or ".").
.TP
.B \-b \fIbyte\fR, \fB\-\-byte=\fIbyte
Keep only every \fIbyte\fPth byte of the input file (header data is
not affected). \fIbyte\fP can be in the range from 0 to the
interleave-1. This option is useful for creating files to program
ROMs. It is typically used with an srec output target.
.TP
.B \-i \fIinterleave\fR, \fB\-\-interleave=\fIinterleave
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.
The interleave is ignored if neither \fB\-b\fP nor \fB\-\-byte\fP is given.
.TP
.B \-v\fR, \fB\-\-verbose
Verbose output: list all object files modified. In the case of
archives, "\fBobjcopy \-V\fR" lists all members of the archive.

View File

@ -1,5 +1,5 @@
/* objcopy.c -- copy object file from input to output, optionally massaging it.
Copyright (C) 1991 Free Software Foundation, Inc.
Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
This file is part of GNU Binutils.
@ -22,16 +22,21 @@
#include "bucomm.h"
#include <getopt.h>
static void setup_sections ();
static void copy_sections ();
static void mangle_sections ();
static void setup_section ();
static void copy_section ();
static void mangle_section ();
#define nonfatal(s) {bfd_nonfatal(s); status = 1; return;}
static asymbol **isympp = NULL; /* Input symbols */
static asymbol **osympp = NULL; /* Output symbols that survive stripping */
/* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
static int copy_byte = -1;
static int interleave = 4;
static boolean verbose; /* Print file and target names. */
static int status = 0;
static int status = 0; /* Exit status. */
enum strip_action
{
@ -58,20 +63,19 @@ static enum locals_action discard_locals;
static struct option strip_options[] =
{
{"strip-all", no_argument, 0, 's'},
{"strip-debug", no_argument, 0, 'S'},
{"discard-all", no_argument, 0, 'x'},
{"discard-locals", no_argument, 0, 'X'},
{"help", no_argument, 0, 'h'},
{"input-target", required_argument, 0, 'I'},
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
{"output-target", required_argument, 0, 'O'},
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
{"target", required_argument, 0, 'F'},
{"format", required_argument, 0, 'F'}, /* Obsolete */
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
{"input-target", required_argument, 0, 'I'},
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
{"output-target", required_argument, 0, 'O'},
{"strip-all", no_argument, 0, 's'},
{"strip-debug", no_argument, 0, 'S'},
{"target", required_argument, 0, 'F'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{0, no_argument, 0, 0}
};
@ -79,20 +83,21 @@ static struct option strip_options[] =
static struct option copy_options[] =
{
{"strip-all", no_argument, 0, 'S'},
{"strip-debug", no_argument, 0, 'g'},
{"byte", required_argument, 0, 'b'},
{"discard-all", no_argument, 0, 'x'},
{"discard-locals", no_argument, 0, 'X'},
{"help", no_argument, 0, 'h'},
{"input-target", required_argument, 0, 'I'},
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
{"output-target", required_argument, 0, 'O'},
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
{"target", required_argument, 0, 'F'},
{"format", required_argument, 0, 'F'}, /* Obsolete */
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
{"input-target", required_argument, 0, 'I'},
{"interleave", required_argument, 0, 'i'},
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
{"output-target", required_argument, 0, 'O'},
{"strip-all", no_argument, 0, 'S'},
{"strip-debug", no_argument, 0, 'g'},
{"target", required_argument, 0, 'F'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{0, no_argument, 0, 0}
};
@ -112,10 +117,12 @@ copy_usage (stream, status)
int status;
{
fprintf (stream, "\
Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname]\n\
Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n\
[-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\
[--verbose] [--version] [--help] in-file [out-file]\n", program_name);
[--verbose] [--version] [--help] in-file [out-file]\n",
program_name);
exit (status);
}
@ -200,6 +207,21 @@ filter_symbols (abfd, osyms, isyms, symcount)
return dst_count;
}
/* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
Adjust *SIZE. */
void
filter_bytes (memhunk, size)
PTR memhunk;
bfd_size_type *size;
{
char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
for (; from < end; from += interleave)
*to++ = *from;
*size /= interleave;
}
/* Copy object file IBFD onto OBFD. */
static void
@ -266,9 +288,9 @@ copy_object (ibfd, obfd)
/* bfd mandates that all output sections be created and sizes set before
any output is done. Thus, we traverse all sections multiple times. */
bfd_map_over_sections (ibfd, setup_sections, (void *) obfd);
bfd_map_over_sections (ibfd, copy_sections, (void *) obfd);
bfd_map_over_sections (ibfd, mangle_sections, (void *) obfd);
bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
bfd_map_over_sections (ibfd, mangle_section, (void *) obfd);
}
static char *
@ -419,7 +441,7 @@ copy_file (input_filename, output_filename, input_target, output_target)
as ISECTION in IBFD. */
static void
setup_sections (ibfd, isection, obfd)
setup_section (ibfd, isection, obfd)
bfd *ibfd;
sec_ptr isection;
bfd *obfd;
@ -493,7 +515,7 @@ loser:
If stripping then don't copy any relocation info. */
static void
copy_sections (ibfd, isection, obfd)
copy_section (ibfd, isection, obfd)
bfd *ibfd;
sec_ptr isection;
bfd *obfd;
@ -544,6 +566,9 @@ copy_sections (ibfd, isection, obfd)
nonfatal (bfd_get_filename (ibfd));
}
if (copy_byte >= 0)
filter_bytes (memhunk, &size);
if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
size))
{
@ -559,7 +584,7 @@ copy_sections (ibfd, isection, obfd)
their new location in the output file, through some complex sums. */
static void
mangle_sections (ibfd, p, obfd)
mangle_section (ibfd, p, obfd)
bfd *ibfd;
asection *p;
bfd *obfd;
@ -747,11 +772,29 @@ copy_main (argc, argv)
boolean show_version = false;
int c;
while ((c = getopt_long (argc, argv, "I:s:O:d:F:b:SgxXVv",
while ((c = getopt_long (argc, argv, "b:i:I:s:O:d:F:SgxXVv",
copy_options, (int *) 0)) != EOF)
{
switch (c)
{
case 'b':
copy_byte = atoi(optarg);
if (copy_byte < 0)
{
fprintf (stderr, "%s: byte number must be non-negative\n",
program_name);
exit (1);
}
break;
case 'i':
interleave = atoi(optarg);
if (interleave < 1)
{
fprintf(stderr, "%s: interleave must be positive\n",
program_name);
exit (1);
}
break;
case 'I':
case 's': /* "source" - 'I' is preferred */
input_target = optarg;
@ -760,7 +803,6 @@ copy_main (argc, argv)
output_target = optarg;
break;
case 'F':
case 'b': /* "both" - 'F' is preferred */
input_target = output_target = optarg;
break;
case 'S':
@ -796,6 +838,13 @@ copy_main (argc, argv)
exit (0);
}
if (copy_byte >= interleave)
{
fprintf (stderr, "%s: byte number must be less than interleave\n",
program_name);
exit (1);
}
if (optind == argc || optind + 2 < argc)
copy_usage (stderr, 1);

View File

@ -57,11 +57,16 @@ struct objdump_disasm_info {
asection *sec;
};
/* Architecture to disassemble for. */
char *machine = (char *) NULL;
/* The symbol table. */
asymbol **syms;
/* Number of bytes allocated for `syms'. */
unsigned int storage;
/* Number of symbols in `syms'. */
unsigned int symcount = 0;
/* Forward declarations. */
@ -118,52 +123,53 @@ static struct option long_options[]=
{"version", no_argument, &show_version, 1},
{0, no_argument, 0, 0}
};
static void
dump_section_header (abfd, section, ignored)
bfd *abfd;
asection *section;
PTR ignored;
{
char *comma = "";
#define PF(x,y) \
if (section->flags & x) { printf("%s%s",comma,y); comma = ", "; }
printf ("SECTION %d [%s]\t: size %08x",
section->index,
section->name,
(unsigned) bfd_get_section_size_before_reloc (section));
printf (" vma ");
printf_vma (section->vma);
printf (" align 2**%u\n ",
section->alignment_power);
PF (SEC_ALLOC, "ALLOC");
PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT");
PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA");
PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS");
PF (SEC_LOAD, "LOAD");
PF (SEC_RELOC, "RELOC");
#ifdef SEC_BALIGN
PF (SEC_BALIGN, "BALIGN");
#endif
PF (SEC_READONLY, "READONLY");
PF (SEC_CODE, "CODE");
PF (SEC_DATA, "DATA");
PF (SEC_ROM, "ROM");
PF (SEC_DEBUGGING, "DEBUGGING");
printf ("\n");
#undef PF
}
static void
dump_headers (abfd)
bfd *abfd;
{
asection *section;
for (section = abfd->sections;
section != (asection *) NULL;
section = section->next)
{
char *comma = "";
#define PF(x,y) \
if (section->flags & x) { printf("%s%s",comma,y); comma = ", "; }
printf ("SECTION %d [%s]\t: size %08x",
section->index,
section->name,
(unsigned) bfd_get_section_size_before_reloc (section));
printf (" vma ");
printf_vma (section->vma);
printf (" align 2**%u\n ",
section->alignment_power);
PF (SEC_ALLOC, "ALLOC");
PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT");
PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA");
PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS");
PF (SEC_LOAD, "LOAD");
PF (SEC_RELOC, "RELOC");
#ifdef SEC_BALIGN
PF (SEC_BALIGN, "BALIGN");
#endif
PF (SEC_READONLY, "READONLY");
PF (SEC_CODE, "CODE");
PF (SEC_DATA, "DATA");
PF (SEC_ROM, "ROM");
PF (SEC_DEBUGGING, "DEBUGGING");
printf ("\n");
#undef PF
}
bfd_map_over_sections (abfd, dump_section_header, (PTR) NULL);
}
static asymbol **
slurp_symtab (abfd)
bfd *abfd;
@ -172,8 +178,8 @@ slurp_symtab (abfd)
if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
{
(void) printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
return (NULL);
printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
return NULL;
}
storage = get_symtab_upper_bound (abfd);
@ -191,17 +197,18 @@ slurp_symtab (abfd)
return sy;
}
/* Filter out (in place) symbols that are useless for dis-assemble.
Return count of useful symbols. */
/* Filter out (in place) symbols that are useless for disassembly.
COUNT is the number of elements in SYMBOLS.
Return the number of useful symbols. */
int remove_useless_symbols (syms, count)
asymbol **syms;
int
remove_useless_symbols (symbols, count)
asymbol **symbols;
int count;
{
register asymbol **in_ptr = syms;
register asymbol **out_ptr = syms;
register asymbol **in_ptr = symbols, **out_ptr = symbols;
while ( --count >= 0 )
while (--count >= 0)
{
asymbol *sym = *in_ptr++;
@ -215,10 +222,9 @@ int remove_useless_symbols (syms, count)
*out_ptr++ = sym;
}
return out_ptr - syms;
return out_ptr - symbols;
}
/* Sort symbols into value order. */
static int
@ -241,14 +247,13 @@ compare_symbols (ap, bp)
return 0;
}
/* Print the supplied address symbolically if possible */
/* Print VMA symbolically to INFO if possible. */
void
objdump_print_address (vma, info)
bfd_vma vma;
struct disassemble_info *info;
{
/* Perform a binary search looking for the closest symbol to
the required value. */
/* @@ For relocateable files, should filter out symbols belonging to
the wrong section. Unfortunately, not enough information is supplied
to this routine to determine the correct section in all cases. */
@ -257,9 +262,9 @@ objdump_print_address (vma, info)
operand can be present at a time, so the 2-entry cache wouldn't be
constantly churned by code doing heavy memory accesses. */
/* Indices in `syms'. */
unsigned int min = 0;
unsigned int max = symcount;
unsigned int thisplace = 1;
unsigned int oldthisplace;
@ -267,117 +272,125 @@ objdump_print_address (vma, info)
fprintf_vma (info->stream, vma);
if (symcount > 0)
if (symcount < 1)
return;
/* Perform a binary search looking for the closest symbol to
the required value. */
while (true)
{
while (true)
{
asymbol *sym; asection *sym_sec;
oldthisplace = thisplace;
thisplace = (max + min) / 2;
if (thisplace == oldthisplace)
break;
sym = syms[thisplace];
vardiff = sym->value - vma;
sym_sec = sym->section;
asymbol *sym;
#if 0
asection *sym_sec;
#endif
oldthisplace = thisplace;
thisplace = (max + min) / 2;
if (thisplace == oldthisplace)
break;
sym = syms[thisplace];
vardiff = sym->value - vma;
#if 0
sym_sec = sym->section;
#endif
if (vardiff > 0)
max = thisplace;
else if (vardiff < 0)
min = thisplace;
else
goto found;
}
/* We've run out of places to look, print the symbol before this one
see if this or the symbol before describes this location the best */
if (thisplace != 0)
{
if (syms[thisplace - 1]->value - vma >
syms[thisplace]->value - vma)
{
/* Previous symbol is in correct section and is closer */
thisplace--;
}
}
found:
{
bfd_vma val = syms[thisplace]->value;
int i;
if (syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
for (i = thisplace - 1; i >= 0; i--)
{
if (syms[i]->value == val
&& (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|| ((syms[thisplace]->flags & BSF_DEBUGGING)
&& !(syms[i]->flags & BSF_DEBUGGING))))
{
thisplace = i;
break;
}
}
if (syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
for (i = thisplace + 1; i < symcount; i++)
{
if (syms[i]->value == val
&& (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|| ((syms[thisplace]->flags & BSF_DEBUGGING)
&& !(syms[i]->flags & BSF_DEBUGGING))))
{
thisplace = i;
break;
}
}
}
{
/* If the file is relocateable, and the symbol could be from this
section, prefer a symbol from this section over symbols from
others, even if the other symbol's value might be closer.
Note that this may be wrong for some symbol references if the
sections have overlapping memory ranges, but in that case there's
no way to tell what's desired without looking at the relocation
table. */
struct objdump_disasm_info *aux;
int i;
aux = (struct objdump_disasm_info *) info->application_data;
if (aux->abfd->flags & HAS_RELOC
&& vma >= bfd_get_section_vma (aux->abfd, aux->sec)
&& vma < (bfd_get_section_vma (aux->abfd, aux->sec)
+ bfd_get_section_size_before_reloc (aux->sec))
&& syms[thisplace]->section != aux->sec)
{
for (i = thisplace + 1; i < symcount; i++)
if (syms[i]->value != syms[thisplace]->value)
break;
while (--i >= 0)
if (syms[i]->section == aux->sec)
{
thisplace = i;
break;
}
}
}
fprintf (info->stream, " <%s", syms[thisplace]->name);
if (syms[thisplace]->value > vma)
{
char buf[30], *p = buf;
sprintf_vma (buf, syms[thisplace]->value - vma);
while (*p == '0')
p++;
fprintf (info->stream, "-%s", p);
}
else if (vma > syms[thisplace]->value)
{
char buf[30], *p = buf;
sprintf_vma (buf, vma - syms[thisplace]->value);
while (*p == '0')
p++;
fprintf (info->stream, "+%s", p);
}
fprintf (info->stream, ">");
if (vardiff > 0)
max = thisplace;
else if (vardiff < 0)
min = thisplace;
else
goto found;
}
/* We've run out of places to look; see whether this or the
symbol before this describes this location the best. */
if (thisplace != 0)
{
if (syms[thisplace - 1]->value - vma < syms[thisplace]->value - vma)
{
/* Previous symbol is in correct section and is closer. */
thisplace--;
}
}
found:
{
/* If this symbol isn't global, search for one with the same value
that is. */
bfd_vma val = syms[thisplace]->value;
int i;
if (syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
for (i = thisplace - 1; i >= 0; i--)
{
if (syms[i]->value == val
&& (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|| ((syms[thisplace]->flags & BSF_DEBUGGING)
&& !(syms[i]->flags & BSF_DEBUGGING))))
{
thisplace = i;
break;
}
}
if (syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
for (i = thisplace + 1; i < symcount; i++)
{
if (syms[i]->value == val
&& (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|| ((syms[thisplace]->flags & BSF_DEBUGGING)
&& !(syms[i]->flags & BSF_DEBUGGING))))
{
thisplace = i;
break;
}
}
}
{
/* If the file is relocateable, and the symbol could be from this
section, prefer a symbol from this section over symbols from
others, even if the other symbol's value might be closer.
Note that this may be wrong for some symbol references if the
sections have overlapping memory ranges, but in that case there's
no way to tell what's desired without looking at the relocation
table. */
struct objdump_disasm_info *aux;
int i;
aux = (struct objdump_disasm_info *) info->application_data;
if ((aux->abfd->flags & HAS_RELOC)
&& vma >= bfd_get_section_vma (aux->abfd, aux->sec)
&& vma < (bfd_get_section_vma (aux->abfd, aux->sec)
+ bfd_get_section_size_before_reloc (aux->sec))
&& syms[thisplace]->section != aux->sec)
{
for (i = thisplace + 1; i < symcount; i++)
if (syms[i]->value != syms[thisplace]->value)
break;
while (--i >= 0)
if (syms[i]->section == aux->sec)
{
thisplace = i;
break;
}
}
}
fprintf (info->stream, " <%s", syms[thisplace]->name);
if (syms[thisplace]->value > vma)
{
char buf[30], *p = buf;
sprintf_vma (buf, syms[thisplace]->value - vma);
while (*p == '0')
p++;
fprintf (info->stream, "-%s", p);
}
else if (vma > syms[thisplace]->value)
{
char buf[30], *p = buf;
sprintf_vma (buf, vma - syms[thisplace]->value);
while (*p == '0')
p++;
fprintf (info->stream, "+%s", p);
}
fprintf (info->stream, ">");
}
#ifdef ARCH_all
@ -432,7 +445,7 @@ disassemble_data (abfd)
symcount = remove_useless_symbols (syms, symcount);
/* Sort the symbols into section and symbol order */
(void) qsort (syms, symcount, sizeof (asymbol *), compare_symbols);
qsort (syms, symcount, sizeof (asymbol *), compare_symbols);
if (machine != (char *) NULL)
{
@ -834,7 +847,33 @@ dump_stabs_1 (abfd, name1, name2)
}
static void
list_matching_formats(p)
dump_bfd_header (abfd)
bfd *abfd;
{
char *comma = "";
printf ("architecture: %s, ",
bfd_printable_arch_mach (bfd_get_arch (abfd),
bfd_get_mach (abfd)));
printf ("flags 0x%08x:\n", abfd->flags);
#define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
PF (HAS_RELOC, "HAS_RELOC");
PF (EXEC_P, "EXEC_P");
PF (HAS_LINENO, "HAS_LINENO");
PF (HAS_DEBUG, "HAS_DEBUG");
PF (HAS_SYMS, "HAS_SYMS");
PF (HAS_LOCALS, "HAS_LOCALS");
PF (DYNAMIC, "DYNAMIC");
PF (WP_TEXT, "WP_TEXT");
PF (D_PAGED, "D_PAGED");
PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
printf ("\nstart address 0x");
printf_vma (abfd->start_address);
}
static void
list_matching_formats (p)
char **p;
{
fprintf(stderr, "%s: Matching formats:", program_name);
@ -860,35 +899,13 @@ display_bfd (abfd)
}
return;
}
printf ("\n%s: file format %s\n", abfd->filename, abfd->xvec->name);
if (dump_ar_hdrs)
print_arelt_descr (stdout, abfd, true);
if (dump_file_header)
{
char *comma = "";
printf ("architecture: %s, ",
bfd_printable_arch_mach (bfd_get_arch (abfd),
bfd_get_mach (abfd)));
printf ("flags 0x%08x:\n", abfd->flags);
#define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
PF (HAS_RELOC, "HAS_RELOC");
PF (EXEC_P, "EXEC_P");
PF (HAS_LINENO, "HAS_LINENO");
PF (HAS_DEBUG, "HAS_DEBUG");
PF (HAS_SYMS, "HAS_SYMS");
PF (HAS_LOCALS, "HAS_LOCALS");
PF (DYNAMIC, "DYNAMIC");
PF (WP_TEXT, "WP_TEXT");
PF (D_PAGED, "D_PAGED");
PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
printf ("\nstart address 0x");
printf_vma (abfd->start_address);
}
printf ("\n");
dump_bfd_header (abfd);
putchar ('\n');
if (dump_section_headers)
dump_headers (abfd);
if (dump_symtab || dump_reloc_info || disassemble)
@ -1150,92 +1167,124 @@ dump_relocs (abfd)
}
}
/* A file to open each BFD on. It will never actually be written to. */
#ifdef unix
#define _DUMMY_NAME_ "/dev/null"
#else
#define _DUMMY_NAME_ "##dummy"
#endif
/* The length of the longest architecture name + 1. */
#define LONGEST_ARCH sizeof("rs6000:6000")
/* List the targets that BFD is configured to support, each followed
by its endianness and the architectures it supports. */
static void
display_target_list ()
{
extern bfd_target *bfd_target_vector[];
int t;
for (t = 0; bfd_target_vector[t]; t++)
{
int a;
bfd_target *p = bfd_target_vector[t];
bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
bfd_set_format (abfd, bfd_object);
printf ("%s\n (header %s, data %s)\n", p->name,
p->header_byteorder_big_p ? "big endian" : "little endian",
p->byteorder_big_p ? "big endian" : "little endian");
for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
printf (" %s\n",
bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
}
}
/* Print a table showing which architectures are supported for entries
FIRST through LAST-1 of bfd_target_vector (targets across,
architectures down). */
static void
display_info_table (first, last)
int first;
int last;
{
unsigned int i, j;
int t, a;
extern bfd_target *bfd_target_vector[];
printf ("\n%12s", " ");
for (i = first; i++ < last && bfd_target_vector[i];)
printf ("%s ", bfd_target_vector[i]->name);
printf ("\n");
/* Print heading of target names. */
printf ("\n%*s", LONGEST_ARCH, " ");
for (t = first; t++ < last && bfd_target_vector[t];)
printf ("%s ", bfd_target_vector[t]->name);
putchar ('\n');
for (j = (int) bfd_arch_obscure + 1; (int) j < (int) bfd_arch_last; j++)
if (strcmp (bfd_printable_arch_mach (j, 0), "UNKNOWN!") != 0)
for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
{
printf ("%11s ", bfd_printable_arch_mach (j, 0));
for (i = first; i++ < last && bfd_target_vector[i];)
printf ("%*s ", LONGEST_ARCH - 1, bfd_printable_arch_mach (a, 0));
for (t = first; t++ < last && bfd_target_vector[t];)
{
bfd_target *p = bfd_target_vector[i];
bfd_target *p = bfd_target_vector[t];
bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
int l = strlen (p->name);
int ok;
bfd_set_format (abfd, bfd_object);
ok = bfd_set_arch_mach (abfd, j, 0);
if (ok)
bfd_set_format (abfd, bfd_object);
if (bfd_set_arch_mach (abfd, a, 0))
printf ("%s ", p->name);
else
{
int l = strlen (p->name);
while (l--)
printf ("%c", ok ? '*' : '-');
printf (" ");
putchar ('-');
putchar (' ');
}
}
printf ("\n");
putchar ('\n');
}
}
/* Print tables of all the target-architecture combinations that
BFD has been configured to support. */
static void
display_target_tables ()
{
int t, columns;
extern bfd_target *bfd_target_vector[];
char *colum;
extern char *getenv ();
columns = 0;
colum = getenv ("COLUMNS");
if (colum != NULL)
columns = atoi (colum);
if (columns == 0)
columns = 80;
for (t = 0; bfd_target_vector[t];)
{
int oldt = t, wid;
for (wid = LONGEST_ARCH; bfd_target_vector[t] && wid < columns; t++)
wid += strlen (bfd_target_vector[t]->name) + 1;
t--;
if (oldt == t)
break;
display_info_table (oldt, t);
}
}
static void
display_info ()
{
char *colum;
unsigned int i, j, columns;
extern bfd_target *bfd_target_vector[];
extern char *getenv ();
printf ("BFD header file version %s\n", BFD_VERSION);
for (i = 0; bfd_target_vector[i]; i++)
{
bfd_target *p = bfd_target_vector[i];
bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
bfd_set_format (abfd, bfd_object);
printf ("%s\n (header %s, data %s)\n", p->name,
p->header_byteorder_big_p ? "big endian" : "little endian",
p->byteorder_big_p ? "big endian" : "little endian");
for (j = (int) bfd_arch_obscure + 1; j < (int) bfd_arch_last; j++)
if (bfd_set_arch_mach (abfd, (enum bfd_architecture) j, 0))
printf (" %s\n",
bfd_printable_arch_mach ((enum bfd_architecture) j, 0));
}
columns = 0;
if ((colum = getenv ("COLUMNS")) != (char *) NULL)
columns = atoi (colum);
if (!columns)
columns = 80;
for (i = 0; bfd_target_vector[i];)
{
int old;
old = i;
for (j = 12; bfd_target_vector[i] && j < columns; i++)
j += strlen (bfd_target_vector[i]->name) + 1;
i--;
if (old == i)
break;
display_info_table (old, i);
}
display_target_list ();
display_target_tables ();
}
/** main and like trivia */
int
main (argc, argv)
int argc;