Added +version (-V) option to print version number.
authorRob Savoye <rob@cygnus>
Wed, 19 Aug 1992 03:25:51 +0000 (03:25 +0000)
committerRob Savoye <rob@cygnus>
Wed, 19 Aug 1992 03:25:51 +0000 (03:25 +0000)
binutils/nm.c
binutils/objdump.c

index 7a7dea9daf698a31b6af73c31a028d75f310ae3b..8a9b6427ca0931067bd0a17f5a7ac4272c274d63 100644 (file)
@@ -1,5 +1,5 @@
 /* nm.c -- Describe symbol table of a rel file.
-   Copyright (C) 1991 Free Software Foundation, Inc.
+   Copyright 1991, 1992 Free Software Foundation, Inc.
 
 This file is part of GNU Binutils.
 
@@ -24,17 +24,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "aout/stab_gnu.h"
 #include "aout/ranlib.h"
 
+static boolean
+display_file PARAMS ((char *filename));
+
+static void
+do_one_rel_file PARAMS ((bfd *file));
 
+static unsigned int
+filter_symbols PARAMS ((bfd *file, asymbol **syms, unsigned long symcount));
 
-PROTO(static boolean, display_file, (char *filename));
-PROTO(static void, do_one_rel_file, (bfd *file));
-PROTO(static unsigned int, filter_symbols, (bfd *file, asymbol **syms,
-                                        unsigned long symcount));
+static void
+print_symbols PARAMS ((bfd *file, asymbol **syms, unsigned long symcount));
 
-PROTO(static void, print_symbols, (bfd *file, asymbol **syms,
-                                    unsigned long symcount));
-extern PROTO(int, (*sorters[2][2]), (char *x, char *y));
-PROTO(static void, print_symdef_entry, (bfd * abfd));
+static void
+print_symdef_entry PARAMS ((bfd * abfd));
 
 /* Command options.  */
 
@@ -46,6 +49,7 @@ int print_armap = 0;  /* describe __.SYMDEF data in archive files.  */
 int reverse_sort = 0;  /* sort in downward(alpha or numeric) order */
 int sort_numerically = 0; /* sort in numeric rather than alpha order */
 int undefined_only = 0;        /* print undefined symbols only */
+int show_version = 0;  /* show the version number */
 
 boolean print_each_filename = false; /* Ick.  Used in archives. */
 
@@ -53,6 +57,7 @@ boolean print_each_filename = false; /* Ick.  Used in archives. */
 extern char *program_name;
 extern char *program_version;
 extern char *target;
+extern int print_version;
 
 struct option long_options[] = {
        {"debug-syms",      no_argument, &print_debug_syms,  1},
@@ -64,6 +69,7 @@ struct option long_options[] = {
        {"reverse-sort",    no_argument, &reverse_sort,      1},
        {"target",          optional_argument, (int *)NULL,        0},
        {"undefined-only",  no_argument, &undefined_only,    1},
+       {"version",         no_argument, &show_version,    1},
        {0, no_argument, 0, 0}
 };
 
@@ -74,7 +80,7 @@ int show_names = 0;
 void
 usage ()
 {
-  fprintf(stderr, "nm %s\nUsage: %s [-agnoprsu] filename...\n",
+  fprintf(stderr, "nm %s\nUsage: %s [-agnoprsuV] filename...\n",
          program_version, program_name);
   exit(0);
 }
@@ -86,12 +92,12 @@ main (argc, argv)
 {
   int c;                       /* sez which option char */
   int option_index = 0;                /* used by getopt and ignored by us */
-  int retval;  
+  int retval;
   program_name = *argv;
 
   bfd_init();
 
-  while ((c = getopt_long(argc, argv, "agnoprsu", long_options, &option_index)) != EOF) {
+  while ((c = getopt_long(argc, argv, "agnoprsuV", long_options, &option_index)) != EOF) {
     switch (c) {
     case 'a': print_debug_syms = 1; break;
     case 'g': external_only = 1; break;
@@ -101,25 +107,29 @@ main (argc, argv)
     case 'r': reverse_sort = 1; break;
     case 's': print_armap = 1; break;
     case 'u': undefined_only = 1; break;
-                       
+    case 'V': show_version = 1; break;
+
     case  0:
       if (!strcmp("target",(long_options[option_index]).name)) {
        target = optarg;
       }
-                       
+
       break;                   /* we've been given a long option */
-                       
+
     default:
       usage ();
     }
   }
-       
+
+  if (show_version)
+       printf ("%s version %s\n", program_name, program_version);
+
   /* Strangely, for the shell you should return only a nonzero value
      on sucess -- the inverse of the C sense. */
-  
+
   /* OK, all options now parsed.  If no filename specified, do a.out. */
   if (option_index == argc) return !display_file ("a.out");
-  
+
   retval = 0;
   show_names = (argc -optind)>1;
   /* We were given several filenames to do: */
@@ -132,7 +142,7 @@ main (argc, argv)
   return retval;
 }
 \f
-/** Display a file's stats */
+/* Display a file's stats */
 
 /* goto here is marginally cleaner than the nested if syntax */
 
@@ -143,23 +153,19 @@ display_file (filename)
   boolean retval = true;
   bfd *file;
   bfd *arfile = NULL;
-       
+
   file = bfd_openr(filename, target);
   if (file == NULL) {
     fprintf (stderr, "\n%s: can't open '%s'.\n", program_name, filename);
     return false;
-
-
   }
 
-
-  if (bfd_check_format(file, bfd_object)) 
+  if (bfd_check_format(file, bfd_object))
       {
        if (show_names) {
          printf ("\n%s:\n",filename);
        }
        do_one_rel_file (file);
       }
   else if (bfd_check_format (file, bfd_archive)) {
     if (!bfd_check_format (file, bfd_archive)) {
@@ -178,7 +184,7 @@ display_file (filename)
          bfd_fatal (filename);
        goto closer;
       }
-                       
+
       if (!bfd_check_format(arfile, bfd_object))
        printf("%s: not an object file\n", arfile->filename);
       else {
@@ -192,7 +198,6 @@ display_file (filename)
     retval = false;
   }
 
-
  closer:
   if (bfd_close(file) == false)
     bfd_fatal (filename);
@@ -200,7 +205,49 @@ display_file (filename)
   return retval;
 }
 \f
+/* Symbol-sorting predicates */
+#define valueof(x) ((x)->section->vma + (x)->value)
+int
+numeric_forward (x, y)
+     CONST void *x;
+     CONST void *y;
+{
+  return (valueof(*(asymbol **)x) - valueof(*(asymbol **) y));
+}
+
+int
+numeric_reverse (x, y)
+     CONST void *x;
+     CONST void *y;
+{
+  return (valueof(*(asymbol **)y) - valueof(*(asymbol **) x));
+}
+
+int
+non_numeric_forward (x, y)
+     CONST void *x;
+     CONST void *y;
+{
+  CONST char *xn = (*(asymbol **) x)->name;
+  CONST char *yn = (*(asymbol **) y)->name;
+
+  return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
+         ((yn == NULL) ? 1 : strcmp (xn, yn)));
+}
+
+int
+non_numeric_reverse (x, y)
+     CONST void *x;
+     CONST void *y;
+{
+  return -(non_numeric_forward (x, y));
+}
 
+int (*(sorters[2][2])) PARAMS ((CONST void *, CONST void *)) = {
+       {non_numeric_forward, non_numeric_reverse},
+       {numeric_forward, numeric_reverse},
+};
+\f
 static void
 do_one_rel_file (abfd)
      bfd *abfd;
@@ -214,7 +261,6 @@ do_one_rel_file (abfd)
     return;
   }
 
-      
   storage = get_symtab_upper_bound (abfd);
   if (storage == 0) {
   nosymz:
@@ -233,65 +279,18 @@ do_one_rel_file (abfd)
      (after printing) */
 
   symcount = filter_symbols (abfd, syms, symcount);
-       
-  if (!no_sort) 
+
+  if (!no_sort)
     qsort((char *) syms, symcount, sizeof (asymbol *),
          sorters[sort_numerically][reverse_sort]);
 
   if (print_each_filename && !file_on_each_line)
     printf("\n%s:\n", bfd_get_filename(abfd));
-       
+
   print_symbols (abfd, syms, symcount);
   free (syms);
-
 }
 \f
-/* Symbol-sorting predicates */
-#define valueof(x) ((x)->section->vma + (x)->value)
-int
-numeric_forward (x, y)
-     char *x;
-     char *y;
-{
-
-  return (valueof(*(asymbol **)x) - valueof(*(asymbol **) y));;
-}
-
-int
-numeric_reverse (x, y)
-     char *x;
-     char *y;
-{
-  return (valueof(*(asymbol **)y) - valueof(*(asymbol **) x));
-
-}
-
-int
-non_numeric_forward (x, y)
-     char *x;
-     char *y;
-{
-  CONST char *xn = (*(asymbol **) x)->name;
-  CONST char *yn = (*(asymbol **) y)->name;
-
-  return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
-         ((yn == NULL) ? 1 : strcmp (xn, yn)));
-}
-
-int
-non_numeric_reverse (x, y)
-     char *x;
-     char *y;
-{
-  return -(non_numeric_forward (x, y));
-}
-
-int (*sorters[2][2])() = {
-       {non_numeric_forward, non_numeric_reverse},
-       {numeric_forward, numeric_reverse},
-};
-\f
-
 /* Choose which symbol entries to print;
    compact them downward to get rid of the rest.
    Return the number of symbols to be printed.  */
@@ -304,26 +303,23 @@ filter_symbols (abfd, syms, symcount)
   asymbol **from, **to;
   unsigned int dst_count = 0;
   asymbol *sym;
-  
+
   unsigned int src_count;
   for (from = to = syms, src_count = 0; src_count <symcount; src_count++) {
     int keep = 0;
 
-    
-       
     flagword flags = (from[src_count])->flags;
     sym = from[src_count];
     if (undefined_only) {
       keep = sym->section == &bfd_und_section;
     } else if (external_only) {
-      keep = ((flags & BSF_GLOBAL) 
-             || (sym->section == &bfd_und_section) 
+      keep = ((flags & BSF_GLOBAL)
+             || (sym->section == &bfd_und_section)
              ||   (sym->section == &bfd_com_section));
-      
     } else {
       keep = 1;
     }
-               
+
     if (!print_debug_syms && ((flags & BSF_DEBUGGING) != 0)) {
       keep = 0;
     }
@@ -332,7 +328,7 @@ filter_symbols (abfd, syms, symcount)
       to[dst_count++] = from[src_count];
     }
   }
-       
+
   return dst_count;
 }
 \f
@@ -379,7 +375,7 @@ print_symdef_entry (abfd)
     }
     elt = bfd_get_elt_at_index (abfd, idx);
     if (thesym->name != (char *)NULL) {
-    printf ("%s in %s\n", thesym->name, bfd_get_filename (elt));
-}
+      printf ("%s in %s\n", thesym->name, bfd_get_filename (elt));
+    }
   }
 }
index 4e868ea66dba1cc10d3b79b46006e43c58ed2852..876ee50d1cb85e5bf3b4842d5053e8784c569702 100644 (file)
@@ -45,8 +45,10 @@ char *xmalloc ();
 
 char *default_target = NULL;   /* default at runtime */
 
+extern *program_version;
 char *program_name = NULL;
 
+int show_version = 0;          /* show the version number */
 int dump_section_contents;     /* -s */
 int dump_section_headers;      /* -h */
 boolean dump_file_header;      /* -f */
@@ -94,6 +96,7 @@ static struct option long_options[]=
   {"syms", no_argument, &dump_symtab, 1},
   {"reloc", no_argument, &dump_reloc_info, 1},
   {"header", no_argument, &dump_section_headers, 1},
+  {"version", no_argument, &show_version,    1},
 #ifdef ELF_STAB_DISPLAY
   {"stabs", no_argument, &dump_stab_section_info, 1},
 #endif
@@ -476,6 +479,8 @@ struct stab_print stab_print[] = {
   {0, 0}
 };
 
+void dump_elf_stabs_1 ();
+
 /* This is a kludge for dumping the stabs section from an ELF file that
    uses Sun stabs encoding.  It has to use some hooks into BFD because
    string table sections are not normally visible to BFD callers.  */
@@ -484,10 +489,7 @@ void
 dump_elf_stabs (abfd)
      bfd *abfd;
 {
-  Elf_Internal_Shdr *stab_hdr, *stabstr_hdr;
-  char *strtab;
-  struct internal_nlist *stabs, *stabs_end;
-  int i, j;
+  int i;
 
   /* Initialize stab name array if first time.  */
   if (stab_name[0][0] == 0) 
@@ -508,19 +510,35 @@ dump_elf_stabs (abfd)
       return;
     }
 
-  stab_hdr = bfd_elf_find_section (abfd, ".stab");
+  dump_elf_stabs_1 (abfd, ".stab", ".stabstr");
+  dump_elf_stabs_1 (abfd, ".stab.excl", ".stab.exclstr");
+  dump_elf_stabs_1 (abfd, ".stab.index", ".stab.indexstr");
+}
+
+void
+dump_elf_stabs_1 (abfd, name1, name2)
+     bfd *abfd;
+     char *name1;              /* Section name of .stab */
+     char *name2;              /* Section name of its string section */
+{
+  Elf_Internal_Shdr *stab_hdr, *stabstr_hdr;
+  char *strtab;
+  struct internal_nlist *stabs, *stabs_end;
+  int i;
+  unsigned file_string_table_offset, next_file_string_table_offset;
+
+  stab_hdr = bfd_elf_find_section (abfd, name1);
   if (0 == stab_hdr)
     {
-      fprintf (stderr, "%s: %s has no .stab section.\n", program_name,
-              abfd->filename);
+      printf ("Contents of %s section:  none.\n\n", name1);
       return;
     }
 
-  stabstr_hdr = bfd_elf_find_section (abfd, ".stabstr");
+  stabstr_hdr = bfd_elf_find_section (abfd, name2);
   if (0 == stabstr_hdr)
     {
-      fprintf (stderr, "%s: %s has no .stabstr section.\n", program_name,
-              abfd->filename);
+      fprintf (stderr, "%s: %s has no %s section.\n", program_name,
+              abfd->filename, name2);
       return;
     }
 
@@ -531,8 +549,8 @@ dump_elf_stabs (abfd)
   if (bfd_seek (abfd, stab_hdr->sh_offset, L_SET) < 0 ||
       stab_hdr->sh_size != bfd_read ((PTR)stabs, stab_hdr->sh_size, 1, abfd))
     {
-      fprintf (stderr, "%s: reading .stab section of %s failed.\n",
-              program_name,
+      fprintf (stderr, "%s: reading %s section of %s failed.\n",
+              program_name, name1, 
               abfd->filename);
       return;
     }
@@ -541,8 +559,8 @@ dump_elf_stabs (abfd)
       stabstr_hdr->sh_size != bfd_read ((PTR)strtab, stabstr_hdr->sh_size,
                                        1, abfd))
     {
-      fprintf (stderr, "%s: reading .stabstr section of %s failed.\n",
-              program_name,
+      fprintf (stderr, "%s: reading %s section of %s failed.\n",
+              program_name, name2,
               abfd->filename);
       return;
     }
@@ -557,11 +575,17 @@ dump_elf_stabs (abfd)
                                (unsigned char *)&(symp)->n_value);     \
   }
 
-  printf ("Contents of .stab section:\n\n");
+  printf ("Contents of %s section:\n\n", name1);
   printf ("Symnum n_type n_othr n_desc n_value  n_strx String\n");
 
-  /* We start the index at -1 because there is a dummy symbol on
+  file_string_table_offset = 0;
+  next_file_string_table_offset = 0;
+
+  /* Loop through all symbols and print them.
+
+     We start the index at -1 because there is a dummy symbol on
      the front of Sun's stabs-in-elf sections.  */
+
   for (i = -1; stabs < stabs_end; stabs++, i++)
     {
       SWAP_SYMBOL (stabs, abfd);
@@ -569,14 +593,29 @@ dump_elf_stabs (abfd)
              stab_name [stabs->n_type],
              stabs->n_other, stabs->n_desc, stabs->n_value,
              stabs->n_strx);
-      if (stabs->n_strx < stabstr_hdr->sh_size)
-       printf (" %s", &strtab[stabs->n_strx]);
+
+      /* Symbols with type == 0 (N_UNDF) specify the length of the
+        string table associated with this file.  We use that info
+        to know how to relocate the *next* file's string table indices.  */
+
+      if (stabs->n_type == N_UNDF)
+       {
+         file_string_table_offset = next_file_string_table_offset;
+         next_file_string_table_offset += stabs->n_value;
+       }
+
+      /* Now, using the possibly updated string table offset, print the
+        string (if any) associated with this symbol.  */
+
+      if ((stabs->n_strx + file_string_table_offset) < stabstr_hdr->sh_size)
+       printf (" %s", &strtab[stabs->n_strx + file_string_table_offset]);
+      else
+        printf (" *");
     }
   printf ("\n\n");
 }
 #endif /* ELF_STAB_DISPLAY */
-\f
-void
+
 display_bfd (abfd)
      bfd *abfd;
 {
@@ -610,6 +649,7 @@ display_bfd (abfd)
       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);
     }
@@ -881,7 +921,9 @@ DEFUN (display_info_table, (first, last),
            bfd_target *p = target_vector[i];
            bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
            int l = strlen (p->name);
-           int ok = bfd_set_arch_mach (abfd, j, 0);
+           int ok;
+           bfd_set_format (abfd, bfd_object);
+           ok = bfd_set_arch_mach (abfd, j, 0);
 
            if (ok)
              printf ("%s ", p->name);
@@ -909,7 +951,7 @@ DEFUN_VOID (display_info)
     {
       bfd_target *p = 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");
@@ -952,7 +994,7 @@ main (argc, argv)
   bfd_init ();
   program_name = *argv;
 
-  while ((c = getopt_long (argc, argv, "ib:m:dlfahrtxsj:", long_options, &ind))
+  while ((c = getopt_long (argc, argv, "ib:m:Vdlfahrtxsj:", long_options, &ind))
         != EOF)
     {
       seenflag = true;
@@ -1003,11 +1045,17 @@ main (argc, argv)
        case 'h':
          dump_section_headers = 1;
          break;
+       case 'V':
+         show_version = 1;
+         break;
        default:
          usage ();
        }
     }
 
+  if (show_version)
+    printf ("%s version %s\n", program_name, program_version);
+
   if (seenflag == false)
     usage ();