diff options
-rw-r--r-- | binutils/ChangeLog | 21 | ||||
-rw-r--r-- | binutils/binutils.texi | 19 | ||||
-rw-r--r-- | binutils/objcopy.1 | 15 | ||||
-rw-r--r-- | binutils/objcopy.c | 107 | ||||
-rw-r--r-- | binutils/objdump.c | 493 |
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\© 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. 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; |