* 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:
parent
d6d4e4c3d0
commit
f7b839f7cd
@ -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.
|
||||
|
@ -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
|
||||
|
@ -8,7 +8,7 @@
|
||||
..
|
||||
|
||||
.SH NAME
|
||||
objcopy\(em\© and translate object files
|
||||
objcopy \- copy and translate object files
|
||||
|
||||
.SH SYNOPSIS
|
||||
.hy 0
|
||||
@ -22,6 +22,8 @@ objcopy\(em\© 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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user