aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog21
-rw-r--r--binutils/binutils.texi19
-rw-r--r--binutils/objcopy.115
-rw-r--r--binutils/objcopy.c107
-rw-r--r--binutils/objdump.c493
5 files changed, 398 insertions, 257 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 3f25ad6..b2d56a1 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -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.
diff --git a/binutils/binutils.texi b/binutils/binutils.texi
index 7187b7e..003f63e 100644
--- a/binutils/binutils.texi
+++ b/binutils/binutils.texi
@@ -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
diff --git a/binutils/objcopy.1 b/binutils/objcopy.1
index 74e718e..4ba1164 100644
--- a/binutils/objcopy.1
+++ b/binutils/objcopy.1
@@ -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.
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index f2dd5a4..01eb6c0 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -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'},
+ {"format", required_argument, 0, 'F'}, /* Obsolete */
{"help", no_argument, 0, 'h'},
- {"input-target", required_argument, 0, 'I'},
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
- {"output-target", required_argument, 0, 'O'},
+ {"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'},
- {"format", required_argument, 0, 'F'}, /* Obsolete */
-
- {"version", no_argument, 0, 'V'},
{"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'},
+ {"format", required_argument, 0, 'F'}, /* Obsolete */
{"help", no_argument, 0, 'h'},
- {"input-target", required_argument, 0, 'I'},
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
- {"output-target", required_argument, 0, 'O'},
+ {"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'},
- {"format", required_argument, 0, 'F'}, /* Obsolete */
-
- {"version", no_argument, 0, 'V'},
{"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);
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 870bb9d..8502296 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -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_headers (abfd)
+dump_section_header (abfd, section, ignored)
bfd *abfd;
+ asection *section;
+ PTR ignored;
{
- asection *section;
-
- for (section = abfd->sections;
- section != (asection *) NULL;
- section = section->next)
- {
- char *comma = "";
+ 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");
+ 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");
+ 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");
+ 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;
+{
+ 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;
+#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; 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)
{
- 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;
-
- if (vardiff > 0)
- max = thisplace;
- else if (vardiff < 0)
- min = thisplace;
- else
- goto found;
+ /* Previous symbol is in correct section and is closer. */
+ thisplace--;
}
- /* 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)
+ 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[thisplace - 1]->value - vma >
- syms[thisplace]->value - vma)
+ if (syms[i]->value == val
+ && (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
+ || ((syms[thisplace]->flags & BSF_DEBUGGING)
+ && !(syms[i]->flags & BSF_DEBUGGING))))
{
- /* Previous symbol is in correct section and is closer */
- thisplace--;
+ thisplace = i;
+ break;
}
}
-
- 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[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))))
{
- 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;
- }
+ thisplace = i;
+ break;
}
- if (syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
- for (i = thisplace + 1; i < symcount; i++)
+ }
+ }
+ {
+ /* 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)
{
- 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;
- }
+ 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, ">");
+ }
+ 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_info ()
+display_target_tables ()
{
- char *colum;
- unsigned int i, j, columns;
+ int t, columns;
extern bfd_target *bfd_target_vector[];
+ char *colum;
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)
+ colum = getenv ("COLUMNS");
+ if (colum != NULL)
columns = atoi (colum);
- if (!columns)
+ if (columns == 0)
columns = 80;
- for (i = 0; bfd_target_vector[i];)
+
+ for (t = 0; bfd_target_vector[t];)
{
- 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)
+ 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 (old, i);
+ display_info_table (oldt, t);
}
}
-/** main and like trivia */
+static void
+display_info ()
+{
+ printf ("BFD header file version %s\n", BFD_VERSION);
+ display_target_list ();
+ display_target_tables ();
+}
+
int
main (argc, argv)
int argc;