* objcopy.c (filter_bytes): New function.
authorDavid MacKenzie <djm@cygnus>
Wed, 26 Jan 1994 22:11:18 +0000 (22:11 +0000)
committerDavid MacKenzie <djm@cygnus>
Wed, 26 Jan 1994 22:11:18 +0000 (22:11 +0000)
(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.

binutils/ChangeLog
binutils/binutils.texi
binutils/objcopy.1
binutils/objcopy.c
binutils/objdump.c

index 3f25ad6f81df6f80caf7f1dc1c452abbad230a4a..b2d56a1cb8ee5eb9760b705f63dbefccb64744d4 100644 (file)
@@ -1,3 +1,24 @@
+Wed Jan 26 13:13:18 1994  David J. Mackenzie  (djm@thepub.cygnus.com)
+
+       * objcopy.c (filter_bytes): New function.
+       (copy_section): Call it.
+       (copy_options, copy_usage, copy_main): Add --byte option to
+       activate it.  Appropriate the -b option (which was an undocumented
+       synonym for -F) for it, also.  Add --interleave, -i option for
+       additional control.
+       (setup_section, copy_section, mangle_section): Renamed with no `s'
+       on the end.
+       * objcopy.1, binutils.texi: Document the new options.
+
+       * objdump.c (display_target_tables, display_target_list):
+       New functions broken out of display_info.
+       Eliminate some magic constants.  Use more meaningful variable names.
+       (dump_bfd_header): New function broken out of display_bfd.
+       (dump_section_header): New function broken out of dump_headers.
+       (remove_useless_symbols): Don't shadow global variable name with
+       parameter. 
+       (objdump_print_address): Fix backward test.
+
 Tue Jan 25 19:40:54 1994  Stan Shebs  (shebs@andros.cygnus.com)
 
        * bucomm.c (print_arelt_descr): Change decl of `when' to time_t.
index 7187b7e724cd1aa74869c0a42e88114aeee826e3..003f63eda123d8da671ce3ed5ce5c3bd222c55b2 100644 (file)
@@ -731,8 +731,9 @@ objcopy [ -F @var{bfdname} | --target=@var{bfdname} ]
         [ -O @var{bfdname} | --output-target=@var{bfdname} ]
         [ -S | --strip-all ]  [ -g | --strip-debug ]
         [ -x | --discard-all ]  [ -X | --discard-locals ]
-        [ -b @var{byte} | --byte=@var{byte} ]  [ -v | --verbose ]
-        [ -V | --version ]  [ --help ]
+        [ -b @var{byte} | --byte=@var{byte} ]
+        [ -i @var{interleave} | --interleave=@var{interleave} ]
+        [ -v | --verbose ] [ -V | --version ]  [ --help ]
         @var{infile} [@var{outfile}]
 @end smallexample
 
@@ -793,9 +794,17 @@ Do not copy compiler-generated local symbols.
 @item -b @var{byte}
 @itemx --byte=@var{byte}
 Keep only every @var{byte}th byte of the input file (header data is not
-affected).  @var{byte} can be in the range from 0 to 3.  This option is
-useful for creating files to program 4 ROMs to create 32-bit words.  It
-is typically used with an @code{srec} output target.
+affected).  @var{byte} can be in the range from 0 to @var{interleave}-1,
+where @var{interleave} is given by the @samp{-i} or @samp{--interleave}
+option, or the default of 4.  This option is useful for creating files
+to program ROMs.  It is typically used with an @code{srec} output
+target.
+
+@item -i @var{interleave}
+@itemx --interleave=@var{interleave}
+Only copy one out of every @var{interleave} bytes.  Which one to copy is
+selected by the @var{-b} or @samp{--byte} option.  The default is 4.
+The interleave is ignored if neither @samp{-b} nor @samp{--byte} is given.
 
 @item -V
 @itemx --version
index 74e718eba35d6e0653093cbea01766d5395a32b1..4ba11646d72d0b94904aa94b145fd5f316b30eef 100644 (file)
@@ -8,7 +8,7 @@
 ..
 
 .SH NAME
-objcopy\(em\&copy and translate object files
+objcopy \- copy and translate object files
 
 .SH SYNOPSIS
 .hy 0
@@ -22,6 +22,8 @@ objcopy\(em\&copy and translate object files
 .RB "[\|" \-g\ |\ \-\-strip\-debug\fR "\|]" 
 .RB "[\|" \-x\ |\ \-\-discard\-all\fR "\|]" 
 .RB "[\|" \-X\ |\ \-\-discard\-locals\fR "\|]" 
+.RB  "[\|" \-b\ \fIbyte\fP |\ \-\-byte=\fIbyte\fP "\|]" 
+.RB  "[\|" \-i\ \fIinterleave\fP |\ \-\-interleave=\fIinterleave\fP "\|]" 
 .RB "[\|" \-v\ |\ \-\-verbose\fR "\|]" 
 .RB "[\|" \-V\ |\ \-\-version\fR "\|]" 
 .RB "[\|" \-\-help\fR "\|]" 
@@ -85,6 +87,17 @@ Do not copy non-global symbols from the source file.
 Do not copy compiler-generated local symbols. (These usually start
 with "L" or ".").
 .TP
+.B \-b \fIbyte\fR, \fB\-\-byte=\fIbyte
+Keep only every \fIbyte\fPth byte of the input file (header data is
+not affected).  \fIbyte\fP can be in the range from 0 to the
+interleave-1.  This option is useful for creating files to program
+ROMs.  It is typically used with an srec output target.
+.TP
+.B \-i \fIinterleave\fR, \fB\-\-interleave=\fIinterleave
+Only copy one out of every \fIinterleave\fP bytes.  Which one to copy is
+selected by the \fB\-b\fP or \fB\-\-byte\fP option.  The default is 4.
+The interleave is ignored if neither \fB\-b\fP nor \fB\-\-byte\fP is given.
+.TP
 .B \-v\fR, \fB\-\-verbose
 Verbose output: list all object files modified.  In the case of
 archives, "\fBobjcopy \-V\fR" lists all members of the archive.
index f2dd5a4e6d8f36b93590316af3f453205460d894..01eb6c02380483ff489c1e8cce4bc4128ec67b45 100644 (file)
@@ -1,5 +1,5 @@
 /* objcopy.c -- copy object file from input to output, optionally massaging it.
-   Copyright (C) 1991 Free Software Foundation, Inc.
+   Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
 #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);
 
index 870bb9d0ffea9e35c765a16a9f36b0219a648771..85022966aa09fd84787693bf50ca4de905756718 100644 (file)
@@ -57,11 +57,16 @@ struct objdump_disasm_info {
   asection *sec;
 };
 
+/* Architecture to disassemble for.  */
 char *machine = (char *) NULL;
+
+/* The symbol table.  */
 asymbol **syms;
 
+/* Number of bytes allocated for `syms'.  */
 unsigned int storage;
 
+/* Number of symbols in `syms'.  */
 unsigned int symcount = 0;
 
 /* Forward declarations.  */
@@ -118,52 +123,53 @@ static struct option long_options[]=
   {"version", no_argument, &show_version,    1},
   {0, no_argument, 0, 0}
 };
-
-
+\f
 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);
+}
+\f
 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)
 
     }
 }
-
+\f
+/* 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;