]> Git Repo - binutils.git/blobdiff - binutils/nm.c
Move printing from bfd to nm and add POSIX and SysV compatibility.
[binutils.git] / binutils / nm.c
index e6ab17f66e9608529dfabbe0364cca908ff85421..4fe3e58eb5b8d2543dcf038076c7ad832af03536 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,21 @@ 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, bfd *archive));
 
-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 unsigned int
+filter_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_symbols PARAMS ((bfd *file, asymbol **syms, unsigned long symcount,
+                      bfd *archive));
+
+static void
+print_symdef_entry PARAMS ((bfd * abfd));
 
 /* Command options.  */
 
@@ -46,6 +50,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,18 +58,20 @@ 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",      0, &print_debug_syms,  1},
-       {"extern-only",     0, &external_only,     1},
-       {"no-sort",         0, &no_sort,           1},
-       {"numeric-sort",    0, &sort_numerically,  1},
-       {"print-armap",     0, &print_armap,       1},
-       {"print-file-name", 0, &file_on_each_line, 1},
-       {"reverse-sort",    0, &reverse_sort,      1},
-       {"target",          2, (int *)NULL,        0},
-       {"undefined-only",  0, &undefined_only,    1},
-       {0, 0, 0, 0}
+       {"debug-syms",      no_argument, &print_debug_syms,  1},
+       {"extern-only",     no_argument, &external_only,     1},
+       {"no-sort",         no_argument, &no_sort,           1},
+       {"numeric-sort",    no_argument, &sort_numerically,  1},
+       {"print-armap",     no_argument, &print_armap,       1},
+       {"print-file-name", no_argument, &file_on_each_line, 1},
+       {"reverse-sort",    no_argument, &reverse_sort,      1},
+       {"target",          optional_argument, 0,            200},
+       {"undefined-only",  no_argument, &undefined_only,    1},
+       {"version",         no_argument, &show_version,      1},
+       {0, no_argument, 0, 0}
 };
 
 int show_names = 0;
@@ -74,9 +81,12 @@ int show_names = 0;
 void
 usage ()
 {
-  fprintf(stderr, "nm %s\nUsage: %s [-agnoprsu] filename...\n",
+  fprintf(stderr, "nm %s\n\
+Usage: %s [-agnoprsuV] [--debug-syms] [--extern-only] [--print-armap]\n\
+       [--print-file-name] [--numeric-sort] [--no-sort] [--reverse-sort]\n\
+       [--undefined-only] [--target=bfdname] [file...]\n",
          program_version, program_name);
-  exit(0);
+  exit(1);
 }
 
 int
@@ -85,14 +95,12 @@ main (argc, argv)
      char **argv;
 {
   int c;                       /* sez which option char */
-  int ind = 0;                 /* used by getopt and ignored by us */
-  extern int optind;           /* steps thru options */
-  int retval;  
+  int retval;
   program_name = *argv;
 
   bfd_init();
 
-  while ((c = getopt_long(argc, argv, "agnoprsu", long_options, &ind)) != EOF) {
+  while ((c = getopt_long(argc, argv, "agnoprsuvABV", long_options, (int *) 0)) != EOF) {
     switch (c) {
     case 'a': print_debug_syms = 1; break;
     case 'g': external_only = 1; break;
@@ -102,25 +110,33 @@ main (argc, argv)
     case 'r': reverse_sort = 1; break;
     case 's': print_armap = 1; break;
     case 'u': undefined_only = 1; break;
-                       
-    case  0:
-      if (!strcmp("target",(long_options[option_index]).name)) {
-       target = optarg;
-      }
-                       
-      break;                   /* we've been given a long option */
-                       
+    case 'v':
+    case 'V': show_version = 1; break;
+
+    /* For MIPS compatibility, -A selects System V style output, -B
+       selects BSD style output.  These are not implemented.  When
+       they are, they should be added to usage ().  */
+    case 'A': break;
+    case 'B': break;
+
+    case 200:                  /* --target */
+      target = optarg;
+      break;
+
     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 (optind == argc) return !display_file ("a.out");
-  
+
   retval = 0;
   show_names = (argc -optind)>1;
   /* We were given several filenames to do: */
@@ -133,7 +149,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 */
 
@@ -144,32 +160,30 @@ 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);
+    fprintf (stderr, "%s: ", program_name);
+    bfd_perror (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);
+       do_one_rel_file (file, NULL);
       }
   else if (bfd_check_format (file, bfd_archive)) {
     if (!bfd_check_format (file, bfd_archive)) {
-      fprintf (stderr, "%s:  %s: unknown format.\n", program_name, filename);
+      fprintf (stderr, "%s: %s: unknown format\n", program_name, filename);
       retval = false;
       goto closer;
     }
 
-    printf("\n%s:\n", filename);
+    if (!file_on_each_line)
+      printf("\n%s:\n", filename);
     if (print_armap) print_symdef_entry (file);
     for (;;) {
       arfile = bfd_openr_next_archived_file (file, arfile);
@@ -179,21 +193,21 @@ 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 {
-       printf ("\n%s:\n", arfile->filename);
-       do_one_rel_file (arfile) ;
+       if (!file_on_each_line)
+         printf ("\n%s:\n", arfile->filename);
+       do_one_rel_file (arfile, file) ;
       }
     }
   }
   else {
-    fprintf (stderr, "\n%s:  %s: unknown format.\n", program_name, filename);
+    fprintf (stderr, "\n%s: %s: unknown format\n", program_name, filename);
     retval = false;
   }
 
-
  closer:
   if (bfd_close(file) == false)
     bfd_fatal (filename);
@@ -201,10 +215,53 @@ 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)
+do_one_rel_file (abfd, archive_bfd)
      bfd *abfd;
+     bfd *archive_bfd; /* If non-NULL: archive containing abfd. */
 {
   unsigned int storage;
   asymbol **syms;
@@ -215,13 +272,12 @@ do_one_rel_file (abfd)
     return;
   }
 
-      
   storage = get_symtab_upper_bound (abfd);
   if (storage == 0) {
   nosymz:
     fprintf (stderr, "%s: Symflags set but there are none?\n",
             bfd_get_filename (abfd));
-    exit (1);
+    return;
   }
 
   syms = (asymbol **) xmalloc (storage);
@@ -234,65 +290,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);
 
+  print_symbols (abfd, syms, symcount, archive_bfd);
+  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,20 +313,24 @@ 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;
 
+    flagword flags = (from[src_count])->flags;
+    sym = from[src_count];
     if (undefined_only) {
-      keep = (flags & BSF_UNDEFINED);
+      keep = sym->section == &bfd_und_section;
     } else if (external_only) {
-      keep = ((flags & BSF_GLOBAL) || (flags & BSF_UNDEFINED) ||
-             (flags & BSF_FORT_COMM));
+      keep = ((flags & BSF_GLOBAL)
+             || (sym->section == &bfd_und_section)
+             || (bfd_is_com_section (sym->section)));
     } else {
       keep = 1;
     }
-               
+
     if (!print_debug_syms && ((flags & BSF_DEBUGGING) != 0)) {
       keep = 0;
     }
@@ -326,23 +339,28 @@ filter_symbols (abfd, syms, symcount)
       to[dst_count++] = from[src_count];
     }
   }
-       
+
   return dst_count;
 }
 \f
 static void
-print_symbols (abfd, syms, symcount)
+print_symbols (abfd, syms, symcount, archive_bfd)
      bfd *abfd;
      asymbol **syms;
      unsigned long symcount;
+     bfd *archive_bfd;
 {
   asymbol **sym = syms, **end = syms + symcount;
 
   for (; sym < end; ++sym) {
-    if (file_on_each_line) printf("%s:", bfd_get_filename(abfd));
+    if (file_on_each_line) {
+      if (archive_bfd)
+       printf("%s:", bfd_get_filename(archive_bfd));
+      printf("%s:", bfd_get_filename(abfd));
+    }
 
     if (undefined_only) {
-      if ((*sym)->flags & BSF_UNDEFINED)
+      if ((*sym)->section == &bfd_und_section)
        puts ((*sym)->name);
     }
     else {
@@ -373,7 +391,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));
+    }
   }
 }
This page took 0.036993 seconds and 4 git commands to generate.