386BSD 0.1 development
[unix-history] / usr / src / usr.bin / nm / nm.c
index 2f9b338..e72285b 100644 (file)
@@ -5,17 +5,33 @@
  * This code is derived from software contributed to Berkeley by
  * Hans Huebner.
  *
  * This code is derived from software contributed to Berkeley by
  * Hans Huebner.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
@@ -25,7 +41,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)nm.c       5.5 (Berkeley) %G%";
+static char sccsid[] = "@(#)nm.c       5.8 (Berkeley) 5/2/91";
 #endif /* not lint */
 
 #include <sys/types.h>
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -45,17 +61,19 @@ int print_only_external_symbols;
 int print_only_undefined_symbols;
 int print_all_symbols;
 int print_file_each_line;
 int print_only_undefined_symbols;
 int print_all_symbols;
 int print_file_each_line;
-int cmp_value(), cmp_name();
-int (*sort_func)() = cmp_name;
-
-enum { FORWARD, BACKWARD } sort_direction = FORWARD;
 int fcount;
 
 int fcount;
 
+int rev;
+int fname(), rname(), value();
+int (*sfunc)() = fname;
+
 /* some macros for symbol type (nlist.n_type) handling */
 #define        IS_DEBUGGER_SYMBOL(x)   ((x) & N_STAB)
 #define        IS_EXTERNAL(x)          ((x) & N_EXT)
 #define        SYMBOL_TYPE(x)          ((x) & (N_TYPE | N_STAB))
 
 /* some macros for symbol type (nlist.n_type) handling */
 #define        IS_DEBUGGER_SYMBOL(x)   ((x) & N_STAB)
 #define        IS_EXTERNAL(x)          ((x) & N_EXT)
 #define        SYMBOL_TYPE(x)          ((x) & (N_TYPE | N_STAB))
 
+void *emalloc();
+
 /*
  * main()
  *     parse command line, execute process_file() for each file
 /*
  * main()
  *     parse command line, execute process_file() for each file
@@ -77,16 +95,16 @@ main(argc, argv)
                        print_only_external_symbols = 1;
                        break;
                case 'n':
                        print_only_external_symbols = 1;
                        break;
                case 'n':
-                       sort_func = cmp_value;
+                       sfunc = value;
                        break;
                case 'o':
                        print_file_each_line = 1;
                        break;
                case 'p':
                        break;
                case 'o':
                        print_file_each_line = 1;
                        break;
                case 'p':
-                       sort_func = NULL;
+                       sfunc = NULL;
                        break;
                case 'r':
                        break;
                case 'r':
-                       sort_direction = BACKWARD;
+                       rev = 1;
                        break;
                case 'u':
                        print_only_undefined_symbols = 1;
                        break;
                case 'u':
                        print_only_undefined_symbols = 1;
@@ -102,6 +120,9 @@ main(argc, argv)
        fcount = argc - optind;
        argv += optind;
 
        fcount = argc - optind;
        argv += optind;
 
+       if (rev && sfunc == fname)
+               sfunc = rname;
+
        if (!fcount)
                errors = process_file("a.out");
        else {
        if (!fcount)
                errors = process_file("a.out");
        else {
@@ -173,8 +194,7 @@ show_archive(fname, fp)
        struct exec exec_head;
        int i, rval;
        long last_ar_off;
        struct exec exec_head;
        int i, rval;
        long last_ar_off;
-       char *p, *name, *emalloc();
-       long atol();
+       char *p, *name;
 
        name = emalloc(sizeof(ar_head.ar_name) + strlen(fname) + 3);
 
 
        name = emalloc(sizeof(ar_head.ar_name) + strlen(fname) + 3);
 
@@ -190,6 +210,13 @@ show_archive(fname, fp)
                        return(1);
                }
 
                        return(1);
                }
 
+               /* remember start position of current archive object */
+               last_ar_off = ftell(fp);
+
+               /* skip ranlib entries */
+               if (!strncmp(ar_head.ar_name, RANLIBMAG, sizeof(RANLIBMAG) - 1))
+                       goto skip;
+
                /*
                 * construct a name of the form "archive.a:obj.o:" for the
                 * current archive entry if the object name is to be printed
                /*
                 * construct a name of the form "archive.a:obj.o:" for the
                 * current archive entry if the object name is to be printed
@@ -203,9 +230,6 @@ show_archive(fname, fp)
                                *p++ = ar_head.ar_name[i];
                *p++ = '\0';
 
                                *p++ = ar_head.ar_name[i];
                *p++ = '\0';
 
-               /* remember start position of current archive object */
-               last_ar_off = ftell(fp);
-
                /* get and check current object's header */
                if (fread((char *)&exec_head, sizeof(exec_head),
                    (size_t)1, fp) != 1) {
                /* get and check current object's header */
                if (fread((char *)&exec_head, sizeof(exec_head),
                    (size_t)1, fp) != 1) {
@@ -213,27 +237,27 @@ show_archive(fname, fp)
                        (void)free(name);
                        return(1);
                }
                        (void)free(name);
                        return(1);
                }
-               if (strcmp(name, RANLIBMAG))
-                       if (N_BADMAG(exec_head)) {
-                               if (!ignore_bad_archive_entries) {
-                                       (void)fprintf(stderr,
-                                           "nm: %s: bad format.\n", name);
-                                       rval = 1;
-                               }
-                       } else {
-                               (void)fseek(fp, (long)-sizeof(exec_head),
-                                   SEEK_CUR);
-                               if (!print_file_each_line)
-                                       (void)printf("\n%s:\n", name);
-                               rval |= show_objfile(name, fp);
+
+               if (N_BADMAG(exec_head)) {
+                       if (!ignore_bad_archive_entries) {
+                               (void)fprintf(stderr,
+                                   "nm: %s: bad format.\n", name);
+                               rval = 1;
                        }
                        }
+               } else {
+                       (void)fseek(fp, (long)-sizeof(exec_head),
+                           SEEK_CUR);
+                       if (!print_file_each_line)
+                               (void)printf("\n%s:\n", name);
+                       rval |= show_objfile(name, fp);
+               }
 
                /*
                 * skip to next archive object - it starts at the next
                 * even byte boundary
                 */
 #define even(x) (((x) + 1) & ~1)
 
                /*
                 * skip to next archive object - it starts at the next
                 * even byte boundary
                 */
 #define even(x) (((x) + 1) & ~1)
-               if (fseek(fp, last_ar_off + even(atol(ar_head.ar_size)),
+skip:          if (fseek(fp, last_ar_off + even(atol(ar_head.ar_size)),
                    SEEK_SET)) {
                        (void)fprintf(stderr,
                            "nm: %s: %s\n", fname, strerror(errno));
                    SEEK_SET)) {
                        (void)fprintf(stderr,
                            "nm: %s: %s\n", fname, strerror(errno));
@@ -259,7 +283,7 @@ show_objfile(objname, fp)
        register int i, nnames, nrawnames;
        struct exec head;
        long stabsize;
        register int i, nnames, nrawnames;
        struct exec head;
        long stabsize;
-       char *stab, *emalloc();
+       char *stab;
 
        /* read a.out header */
        if (fread((char *)&head, sizeof(head), (size_t)1, fp) != 1) {
 
        /* read a.out header */
        if (fread((char *)&head, sizeof(head), (size_t)1, fp) != 1) {
@@ -299,7 +323,7 @@ show_objfile(objname, fp)
        }
 
        /* get memory for the symbol table */
        }
 
        /* get memory for the symbol table */
-       names = (struct nlist *)emalloc((size_t)head.a_syms);
+       names = emalloc((size_t)head.a_syms);
        nrawnames = head.a_syms / sizeof(*names);
        if (fread((char *)names, (size_t)head.a_syms, (size_t)1, fp) != 1) {
                (void)fprintf(stderr,
        nrawnames = head.a_syms / sizeof(*names);
        if (fread((char *)names, (size_t)head.a_syms, (size_t)1, fp) != 1) {
                (void)fprintf(stderr,
@@ -368,8 +392,8 @@ show_objfile(objname, fp)
        }
 
        /* sort the symbol table if applicable */
        }
 
        /* sort the symbol table if applicable */
-       if (sort_func)
-               qsort((char *)names, (size_t)nnames, sizeof(*names), sort_func);
+       if (sfunc)
+               qsort((char *)names, (size_t)nnames, sizeof(*names), sfunc);
 
        /* print out symbols */
        for (np = names, i = 0; i < nnames; np++, i++)
 
        /* print out symbols */
        for (np = names, i = 0; i < nnames; np++, i++)
@@ -501,25 +525,23 @@ typeletter(type)
        return('?');
 }
 
        return('?');
 }
 
-/*
- * cmp_name()
- *     compare two symbols by their names
- */
-cmp_name(a0, b0)
+fname(a0, b0)
        void *a0, *b0;
 {
        struct nlist *a = a0, *b = b0;
 
        void *a0, *b0;
 {
        struct nlist *a = a0, *b = b0;
 
-       return(sort_direction == FORWARD ?
-           strcmp(a->n_un.n_name, b->n_un.n_name) :
-           strcmp(b->n_un.n_name, a->n_un.n_name));
+       return(strcmp(a->n_un.n_name, b->n_un.n_name));
 }
 
 }
 
-/*
- * cmp_value()
- *     compare two symbols by their values
- */
-cmp_value(a0, b0)
+rname(a0, b0)
+       void *a0, *b0;
+{
+       struct nlist *a = a0, *b = b0;
+
+       return(strcmp(b->n_un.n_name, a->n_un.n_name));
+}
+
+value(a0, b0)
        void *a0, *b0;
 {
        register struct nlist *a = a0, *b = b0;
        void *a0, *b0;
 {
        register struct nlist *a = a0, *b = b0;
@@ -531,24 +553,28 @@ cmp_value(a0, b0)
                        return(-1);
        else if (SYMBOL_TYPE(b->n_type) == N_UNDF)
                return(1);
                        return(-1);
        else if (SYMBOL_TYPE(b->n_type) == N_UNDF)
                return(1);
-       if (a->n_value == b->n_value)
-               return(cmp_name((void *)a, (void *)b));
-       return(sort_direction == FORWARD ? a->n_value > b->n_value :
-           a->n_value < b->n_value);
+       if (rev) {
+               if (a->n_value == b->n_value)
+                       return(rname(a0, b0));
+               return(b->n_value > a->n_value ? 1 : -1);
+       } else {
+               if (a->n_value == b->n_value)
+                       return(fname(a0, b0));
+               return(a->n_value > b->n_value ? 1 : -1);
+       }
 }
 
 }
 
-char *
+void *
 emalloc(size)
        size_t size;
 {
        char *p;
 
        /* NOSTRICT */
 emalloc(size)
        size_t size;
 {
        char *p;
 
        /* NOSTRICT */
-       if (!(p = malloc(size))) {
-               (void)fprintf(stderr, "nm: no more memory.\n");
-               exit(1);
-       }
-       return(p);
+       if (p = malloc(size))
+               return(p);
+       (void)fprintf(stderr, "nm: %s\n", strerror(errno));
+       exit(1);
 }
 
 usage()
 }
 
 usage()