read the symbol table into malloc'd space instead of seeking
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Wed, 13 Feb 1991 14:57:51 +0000 (06:57 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Wed, 13 Feb 1991 14:57:51 +0000 (06:57 -0800)
(turns out to not really be a big win, but it does make some difference).

SCCS-vsn: usr.sbin/kvm_mkdb/nlist.c 5.2

usr/src/usr.sbin/kvm_mkdb/nlist.c

index 22cf5f7..4ed6838 100644 (file)
@@ -6,93 +6,98 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)nlist.c    5.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)nlist.c    5.2 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
-#include <errno.h>
+#include <fcntl.h>
 #include <limits.h>
 #include <ndbm.h>
 #include <a.out.h>
 #include <limits.h>
 #include <ndbm.h>
 #include <a.out.h>
-#include <kvm.h>
+#include <errno.h>
 #include <unistd.h>
 #include <unistd.h>
+#include <kvm.h>
 #include <stdio.h>
 #include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
 
 typedef struct nlist NLIST;
 #define        _strx   n_un.n_strx
 #define        _name   n_un.n_name
 
 
 typedef struct nlist NLIST;
 #define        _strx   n_un.n_strx
 #define        _name   n_un.n_name
 
-#define        BFLEN           1024
-#define        VRS             "_version"
-
 static char *kfile;
 
 create_knlist(name, db)
        char *name;
        DBM *db;
 {
 static char *kfile;
 
 create_knlist(name, db)
        char *name;
        DBM *db;
 {
-       register char *bp;
-       register int ch, len;
+       register int nsyms;
        struct exec ebuf;
        struct exec ebuf;
-       FILE *fstr, *fsym;
+       FILE *fp;
        NLIST nbuf;
        NLIST nbuf;
-       off_t string_off, symbol_off, symbol_size;
-       off_t rel_off, vers_off;
        datum key, data;
        datum key, data;
-       char sbuf[BFLEN];
+       int fd, nr, strsize;
+       char *strtab, buf[1024];
 
 
-       /* Two pointers, one for symbol table and one for string table. */
        kfile = name;
        kfile = name;
-       if ((fsym = fopen(name, "r")) == NULL ||
-           (fstr = fopen(name, "r")) == NULL)
+       if ((fd = open(name, O_RDONLY, 0)) < 0)
                error(name);
 
                error(name);
 
-       if (fread((char *)&ebuf, sizeof(struct exec), 1, fsym) != 1)
-               badfmt("no exec header");
+       /* Read in exec structure. */
+       nr = read(fd, (char *)&ebuf, sizeof(struct exec));
+       if (nr != sizeof(struct exec))
+               badfmt(nr, "no exec header");
+
+       /* Check magic number and symbol count. */
        if (N_BADMAG(ebuf))
                badfmt("bad magic number");
        if (N_BADMAG(ebuf))
                badfmt("bad magic number");
-               
-       symbol_size = ebuf.a_syms;
-       if (!symbol_size)
+       if (!ebuf.a_syms)
                badfmt("stripped");
 
                badfmt("stripped");
 
-       symbol_off = N_SYMOFF(ebuf);
-       string_off = symbol_off + symbol_size;
+       /* Seek to string table. */
+       if (lseek(fd, N_STROFF(ebuf), SEEK_SET) == -1)
+               badfmt("corrupted string table");
+
+       /* Read in the size of the symbol table. */
+       nr = read(fd, (char *)&strsize, sizeof(strsize));
+       if (nr != sizeof(strsize))
+               badread(nr, "no symbol table");
 
 
-       if (fseek(fsym, symbol_off, SEEK_SET) == -1)
-               badfmt("corrupted symbol table");
+       /* Read in the string table. */
+       strsize -= sizeof(strsize);
+       if (!(strtab = (char *)malloc(strsize)))
+               error(name);
+       if ((nr = read(fd, strtab, strsize)) != strsize)
+               badread(nr, "corrupted symbol table");
 
 
-       key.dptr = sbuf;
+       /* Seek to symbol table. */
+       if (!(fp = fdopen(fd, "r")))
+               error(name);
+       if (fseek(fp, N_SYMOFF(ebuf), SEEK_SET) == -1)
+               error(name);
+       
        data.dptr = (char *)&nbuf;
        data.dsize = sizeof(NLIST);
 
        data.dptr = (char *)&nbuf;
        data.dsize = sizeof(NLIST);
 
-       for (; symbol_size; symbol_size -= sizeof(NLIST)) {
-               if (fread((char *)&nbuf, sizeof (NLIST), 1, fsym) != 1)
-                       badfmt("corrupted symbol table");
-               if (!nbuf._strx || nbuf.n_type&N_STAB)
-                       continue;
-               if (fseek(fstr, string_off + nbuf._strx, SEEK_SET) == -1)
-                       badfmt("corrupted string table");
-
-               /* Read string. */
-               bp = sbuf;
-               for (len = 0; (ch = getc(fstr)) != EOF && ch != '\0';) {
-                       if (++len == BFLEN) {
-                               (void)fprintf(stderr,
-                                   "kvm_mkdb: symbol too long.");
-                               break;
-                       }
-                       *bp++ = ch;
+       /* Read each symbol and enter it into the database. */
+       nsyms = ebuf.a_syms / sizeof(struct nlist);
+       while (nsyms--) {
+               if (fread((char *)&nbuf, sizeof (NLIST), 1, fp) != 1) {
+                       if (feof(fp))
+                               badfmt("corrupted symbol table");
+                       error(name);
                }
                }
-               if (len == BFLEN)
+               if (!nbuf._strx || nbuf.n_type&N_STAB)
                        continue;
 
                        continue;
 
-               /* Store string. */
-               key.dsize = len;
+               key.dptr = strtab + nbuf._strx - sizeof(long);
+               key.dsize = strlen(key.dptr);
                if (dbm_store(db, key, data, DBM_INSERT) < 0)
                        error("dbm_store");
 
                if (dbm_store(db, key, data, DBM_INSERT) < 0)
                        error("dbm_store");
 
-               if (!strncmp(sbuf, VRS, sizeof(VRS) - 1)) {
+               if (!strncmp(key.dptr, VRS_SYM, sizeof(VRS_SYM) - 1)) {
+                       off_t cur_off, rel_off, vers_off;
+
                        /* Offset relative to start of text image in VM. */
 #ifdef hp300
                        rel_off = nbuf.n_value;
                        /* Offset relative to start of text image in VM. */
 #ifdef hp300
                        rel_off = nbuf.n_value;
@@ -113,7 +118,9 @@ create_knlist(name, db)
                         */
                        rel_off -= CLBYTES - (ebuf.a_text % CLBYTES);
                        vers_off = N_TXTOFF(ebuf) + rel_off;
                         */
                        rel_off -= CLBYTES - (ebuf.a_text % CLBYTES);
                        vers_off = N_TXTOFF(ebuf) + rel_off;
-                       if (fseek(fstr, vers_off, SEEK_SET) == -1)
+
+                       cur_off = ftell(fp);
+                       if (fseek(fp, vers_off, SEEK_SET) == -1)
                                badfmt("corrupted string table");
 
                        /*
                                badfmt("corrupted string table");
 
                        /*
@@ -121,27 +128,37 @@ create_knlist(name, db)
                         * This code assumes that a newline terminates the
                         * version line.
                         */
                         * This code assumes that a newline terminates the
                         * version line.
                         */
-                       if (fgets(sbuf, sizeof(sbuf), fstr) == NULL)
+                       if (fgets(buf, sizeof(buf), fp) == NULL)
                                badfmt("corrupted string table");
 
                                badfmt("corrupted string table");
 
-                       key.dptr = VERSION;
-                       key.dsize = sizeof(VERSION) - 1;
-                       data.dptr = sbuf;
-                       data.dsize = strlen(sbuf);
+                       key.dptr = VRS_KEY;
+                       key.dsize = sizeof(VRS_KEY) - 1;
+                       data.dptr = buf;
+                       data.dsize = strlen(buf);
                        if (dbm_store(db, key, data, DBM_INSERT) < 0)
                                error("dbm_store");
 
                        /* Restore to original values. */
                        if (dbm_store(db, key, data, DBM_INSERT) < 0)
                                error("dbm_store");
 
                        /* Restore to original values. */
-                       key.dptr = sbuf;
                        data.dptr = (char *)&nbuf;
                        data.dsize = sizeof(NLIST);
                        data.dptr = (char *)&nbuf;
                        data.dsize = sizeof(NLIST);
+                       if (fseek(fp, cur_off, SEEK_SET) == -1)
+                               badfmt("corrupted string table");
                }
        }
                }
        }
-       (void)fclose(fstr);
-       (void)fclose(fsym);
+       (void)fclose(fp);
+}
+
+badread(nr, p)
+       int nr;
+       char *p;
+{
+       if (nr < 0)
+               error(kfile);
+       badfmt(p);
 }
 
 badfmt(p)
 }
 
 badfmt(p)
+       char *p;
 {
        (void)fprintf(stderr,
            "symorder: %s: %s: %s\n", kfile, p, strerror(EFTYPE));
 {
        (void)fprintf(stderr,
            "symorder: %s: %s: %s\n", kfile, p, strerror(EFTYPE));