BSD 4 release
[unix-history] / usr / src / cmd / symorder.c
index b7e613d..d811b9b 100644 (file)
-/* symorder orderlist symbolfile
- *  orderlist is a file containing symbols to be found in symbolfile,
- *      1 symbol per line.
- *  symbolfile is updated in place to put the requested symbols first
- *      in the symbol table, in the order specified.  This is done
- *      by swapping the old symbols in the required spots with the
- *      new ones.  If all of the order symbols are not found, an
- *      error is generated.
- *
- *  Modelled after nlist.c the nlist subroutine, which has been
- *      modified to succeed as soon as all sought symbols are found.
- *
- *  This program was specifically designed to cut down on the read
- *      overhead of systat(ss) when getting symbols from /unix.
+static char *sccsid = "@(#)symorder.c  4.2 (Berkeley) 10/2/80";
+/*
+ * symorder - reorder symbol table
  */
  */
-
 #include <stdio.h>
 #include <stdio.h>
+#include <pagsiz.h>
+#include <sys/types.h>
+#include <stat.h>
 #include <a.out.h>
 #include <a.out.h>
-int a_magic[] = {A_MAGIC1, A_MAGIC2, A_MAGIC3, A_MAGIC4, 0};
+
 #define SPACE 100
 
 #define SPACE 100
 
+struct nlist order[SPACE];
+
+char   *savestr();
+struct nlist nl1, nl2;
+struct exec exec;
+FILE   *strf;
+off_t  sa, ss;
+struct stat stb;
+int    nsym = 0;
+int    symfound = 0;
+char   asym[BUFSIZ];
+
 main(argc, argv)
 main(argc, argv)
-char *argv[];
+       char **argv;
 {
        register struct nlist *p, *q;
        register FILE *f;
 {
        register struct nlist *p, *q;
        register FILE *f;
-       register int sa, na, i, j;
-       int nsym = 0, symfound = 0, n, o;
-       struct nlist nl1, nl2;
-       char buf[20];
-       struct nlist order[SPACE];
-       struct exec exec;
+       register int na, i, j;
+       int maxlen;
+       int n, o;
 
        if(argc != 3) {
                fprintf(stderr, "Usage: symorder orderlist file\n");
                exit(1);
        }
        if((f = fopen(argv[1], "r")) == NULL) {
 
        if(argc != 3) {
                fprintf(stderr, "Usage: symorder orderlist file\n");
                exit(1);
        }
        if((f = fopen(argv[1], "r")) == NULL) {
-               fprintf(stderr, "Can't open "); perror(argv[1]);
+               perror(argv[1]);
                exit(1);
        }
                exit(1);
        }
-       for(p = order; fgets(buf, sizeof buf, f) != NULL; p++, nsym++)
-               for(i = 0; i < 8 && buf[i] != '\n'; i++)
-                       p->n_name[i] = buf[i];
-       fclose(f);
-/***    for(i = 0; i < nsym; i++)                       ***/
-/***            printf("\"%.8s\"\n", order[i].n_name);  ***/
-/***    printf("--------\n");                           ***/
-       if((f = fopen(argv[2], "r")) == NULL) {
-               fprintf(stderr, "Can't open "); perror(argv[2]);
-               exit(1);
+       maxlen = 0;
+       for(p = order; fgets(asym, sizeof asym, f) != NULL; p++, nsym++) {
+               for(i = 0; asym[i] && asym[i] != '\n'; i++)
+                       continue;
+               if (asym[i] == '\n')
+                       asym[i] = 0;
+               p->n_un.n_name = savestr(asym);
+               if (maxlen < strlen(p->n_un.n_name))
+                       maxlen = strlen(p->n_un.n_name);
        }
        }
-       if((o = open(argv[2], 1)) < 0) {
-               fprintf(stderr, "Can't update "); perror(argv[2]);
+       fclose(f);
+       if((f = fopen(argv[2], "r")) == NULL)
+               perror(argv[2]), exit(1);
+       if((strf = fopen(argv[2], "r")) == NULL)
+               perror(argv[2]), exit(1);
+       if((o = open(argv[2], 1)) < 0)
+               perror(argv[2]), exit(1);
+       if((fread(&exec, sizeof exec, 1, f)) != 1 || N_BADMAG(exec)) {
+               fprintf(stderr, "symorder: %s: bad format\n", argv[2]);
                exit(1);
        }
                exit(1);
        }
-       if((fread(&exec, sizeof exec, 1, f)) != 1) {
-               fprintf(stderr, "Can't read "); perror(argv[2]);
+       if (exec.a_syms == 0) {
+               fprintf(stderr, "symorder: %s is stripped\n", argv[2]);
                exit(1);
        }
                exit(1);
        }
-       for(i=0; a_magic[i]; i++)
-               if(a_magic[i] == exec.a_magic) break;
-       if(a_magic[i] == 0){
-               fprintf(stderr, "Bad Header on %s\n", argv[2]);
+       fstat(fileno(f), &stb);
+       if (stb.st_size < N_STROFF(exec)+sizeof(off_t)) {
+               fprintf(stderr, "symorder: %s is in old format or truncated\n", argv[2]);
                exit(1);
        }
                exit(1);
        }
-       sa = exec.a_text + exec.a_data;
-       sa += exec.a_trsize + exec.a_drsize;
-       sa += sizeof exec;
+       sa = N_SYMOFF(exec);
        na = sa;
        na = sa;
+       ss = sa + exec.a_syms;
        fseek(f, sa, 0);
        n = exec.a_syms;
        fseek(f, sa, 0);
        n = exec.a_syms;
-
        while(n && symfound < nsym) {
                if(fread(&nl1, sizeof nl1, 1, f) != 1) {
                        fprintf(stderr, "Short file "); perror(argv[2]);
                        exit(1);
                }
        while(n && symfound < nsym) {
                if(fread(&nl1, sizeof nl1, 1, f) != 1) {
                        fprintf(stderr, "Short file "); perror(argv[2]);
                        exit(1);
                }
-/***    printf("\"%.8s\"\n", nl1.n_name);       ***/
                na += sizeof nl1;
                n -= sizeof nl1;
                na += sizeof nl1;
                n -= sizeof nl1;
-/***    printf("Trying ");                      ***/
+               if (nl1.n_un.n_strx == 0 || nl1.n_type & N_STAB)
+                       continue;
+               fseek(strf, ss+nl1.n_un.n_strx, 0);
+               fread(asym, maxlen+1, 1, strf);
                for(j = 0; j < nsym; j++) {
                for(j = 0; j < nsym; j++) {
-/***    printf("%s ", order[j].n_name);         ***/
-                       for(i = 0; i < 8; i++)
-                               if(nl1.n_name[i] != order[j].n_name[i])
+                       for(i = 0; asym[i]; i++)
+                               if(asym[i] != order[j].n_un.n_name[i])
                                        goto cont;
                                        goto cont;
-/***    printf("Found: %.8s\n", nl1.n_name);    ***/
+                       if (order[j].n_un.n_name[i])
+                               goto cont;
                        if (order[j].n_value)
                                goto cont;
                        order[j].n_value = 1;
                        fseek(f, (i = (sa+(j * sizeof nl1))), 0);
                        if(fread(&nl2, sizeof nl2, 1, f) != 1)
                        if (order[j].n_value)
                                goto cont;
                        order[j].n_value = 1;
                        fseek(f, (i = (sa+(j * sizeof nl1))), 0);
                        if(fread(&nl2, sizeof nl2, 1, f) != 1)
-                               printf("Read err on 2nd sym\n");
+                               printf("Read err on 2nd asym\n");
                        lseek(o, i, 0);
                        if(write(o, &nl1, sizeof nl1) == -1)
                                perror("write1");
                        lseek(o, i, 0);
                        if(write(o, &nl1, sizeof nl1) == -1)
                                perror("write1");
@@ -105,13 +110,41 @@ char *argv[];
        cont:           ;
 
                }
        cont:           ;
 
                }
-/***    printf("\n");                           ***/
        }
        if(symfound < nsym) {
        }
        if(symfound < nsym) {
-               fprintf(stderr, "%d Syms not found:\n", nsym - symfound);
+               fprintf(stderr, "%d symbol(s) not found:\n", nsym - symfound);
                for (i = 0; i < nsym; i++) {
                        if (order[i].n_value == 0)
                for (i = 0; i < nsym; i++) {
                        if (order[i].n_value == 0)
-                               printf("%.8s\n", order[i].n_name);
+                               printf("%s\n", order[i].n_un.n_name);
+               }
+       }
+}
+
+#define        NSAVETAB        4096
+char   *savetab;
+int    saveleft;
+
+char *
+savestr(cp)
+       register char *cp;
+{
+       register int len;
+
+       len = strlen(cp) + 1;
+       if (len > saveleft) {
+               saveleft = NSAVETAB;
+               if (len > saveleft)
+                       saveleft = len;
+               savetab = (char *)malloc(saveleft);
+               if (savetab == 0) {
+                       fprintf(stderr,
+                           "symorder: ran out of memory (savestr)\n");
+                       exit(1);
                }
        }
                }
        }
+       strncpy(savetab, cp, len);
+       cp = savetab;
+       savetab += len;
+       saveleft -= len;
+       return (cp);
 }
 }