112674Ssam #ifndef lint 2*16667Sralph static char *sccsid = "@(#)symorder.c 4.5 (Berkeley) 07/05/84"; 312674Ssam #endif 4*16667Sralph 5623Sbill /* 6623Sbill * symorder - reorder symbol table 7623Sbill */ 8*16667Sralph 9623Sbill #include <stdio.h> 10623Sbill #include <sys/types.h> 1113621Ssam #include <sys/stat.h> 12934Sbill #include <a.out.h> 13623Sbill 14623Sbill #define SPACE 100 15623Sbill 16623Sbill struct nlist order[SPACE]; 17623Sbill 18*16667Sralph char *savestr(), *index(), *malloc(); 19623Sbill struct exec exec; 20*16667Sralph off_t sa; 21623Sbill struct stat stb; 22623Sbill int nsym = 0; 23623Sbill int symfound = 0; 24*16667Sralph char *strings; 25*16667Sralph char *newstrings; 26*16667Sralph struct nlist *symtab; 27*16667Sralph struct nlist *newtab; 28*16667Sralph int symsize; 29623Sbill char asym[BUFSIZ]; 30623Sbill 31623Sbill main(argc, argv) 32623Sbill char **argv; 33623Sbill { 34*16667Sralph register char *ns; 35*16667Sralph register struct nlist *symp; 36*16667Sralph register struct nlist *p; 37623Sbill register FILE *f; 38*16667Sralph register int i; 39623Sbill int n, o; 40623Sbill 41*16667Sralph if (argc != 3) { 42623Sbill fprintf(stderr, "Usage: symorder orderlist file\n"); 43623Sbill exit(1); 44623Sbill } 45*16667Sralph if ((f = fopen(argv[1], "r")) == NULL) { 46623Sbill perror(argv[1]); 47623Sbill exit(1); 48623Sbill } 49*16667Sralph for (p = order; fgets(asym, sizeof asym, f) != NULL; p++, nsym++) { 50*16667Sralph for (i = 0; asym[i] && asym[i] != '\n'; i++) 51623Sbill continue; 52623Sbill if (asym[i] == '\n') 53623Sbill asym[i] = 0; 54623Sbill p->n_un.n_name = savestr(asym); 55623Sbill } 56623Sbill fclose(f); 57*16667Sralph if ((f = fopen(argv[2], "r")) == NULL) 58623Sbill perror(argv[2]), exit(1); 59*16667Sralph if ((o = open(argv[2], 1)) < 0) 60623Sbill perror(argv[2]), exit(1); 61*16667Sralph if ((fread(&exec, sizeof exec, 1, f)) != 1 || N_BADMAG(exec)) { 62623Sbill fprintf(stderr, "symorder: %s: bad format\n", argv[2]); 63623Sbill exit(1); 64623Sbill } 65623Sbill if (exec.a_syms == 0) { 66623Sbill fprintf(stderr, "symorder: %s is stripped\n", argv[2]); 67623Sbill exit(1); 68623Sbill } 69623Sbill fstat(fileno(f), &stb); 70623Sbill if (stb.st_size < N_STROFF(exec)+sizeof(off_t)) { 71*16667Sralph fprintf(stderr, "symorder: %s is in old format or truncated\n", 72*16667Sralph argv[2]); 73623Sbill exit(1); 74623Sbill } 75623Sbill sa = N_SYMOFF(exec); 76623Sbill fseek(f, sa, 0); 77623Sbill n = exec.a_syms; 78*16667Sralph symtab = (struct nlist *)malloc(n); 79*16667Sralph if (symtab == (struct nlist *)0) { 80*16667Sralph fprintf(stderr, "symorder: Out of core, no space for symtab\n"); 81*16667Sralph exit(1); 82*16667Sralph } 83*16667Sralph if (fread((char *)symtab, 1, n, f) != n) { 84*16667Sralph fprintf(stderr, "symorder: Short file "); perror(argv[2]); 85*16667Sralph exit(1); 86*16667Sralph } 87*16667Sralph if (fread((char *)&symsize, sizeof (int), 1, f) != 1 || 88*16667Sralph symsize <= 0) { 89*16667Sralph fprintf(stderr, "symorder: No strings "); perror(argv[2]); 90*16667Sralph exit(1); 91*16667Sralph } 92*16667Sralph strings = malloc(symsize); 93*16667Sralph if (strings == (char *)0) { 94*16667Sralph fprintf(stderr,"symorder: Out of core, no space for strings\n"); 95*16667Sralph exit(1); 96*16667Sralph } 97*16667Sralph if (fread(strings, 1, symsize, f) != symsize) { 98*16667Sralph fprintf(stderr, "symorder: Truncated strings "); 99*16667Sralph perror(argv[2]); 100*16667Sralph exit(1); 101*16667Sralph } 102*16667Sralph 103*16667Sralph newtab = (struct nlist *)malloc(n); 104*16667Sralph if (newtab == (struct nlist *)0) { 105*16667Sralph fprintf(stderr, 106*16667Sralph "symorder: Out of core, no space for new symtab\n"); 107*16667Sralph exit(1); 108*16667Sralph } 109*16667Sralph i = n / sizeof (struct nlist); 110*16667Sralph reorder(symtab, newtab, i); 111*16667Sralph free((char *)symtab); 112*16667Sralph symtab = newtab; 113*16667Sralph 114*16667Sralph newstrings = malloc(symsize); 115*16667Sralph if (newstrings == (char *)0) { 116*16667Sralph fprintf(stderr, 117*16667Sralph "symorder: Out of core, no space for newstrings\n"); 118*16667Sralph exit(1); 119*16667Sralph } 120*16667Sralph ns = newstrings; 121*16667Sralph for (symp = symtab; --i >= 0; symp++) { 122*16667Sralph if (symp->n_un.n_strx == 0) 123*16667Sralph continue; 124*16667Sralph symp->n_un.n_strx -= sizeof (int); 125*16667Sralph if ((unsigned)symp->n_un.n_strx >= symsize) { 126*16667Sralph fprintf(stderr,"symorder: Corrupted string pointers\n"); 127623Sbill exit(1); 128623Sbill } 129*16667Sralph strcpy(ns, &strings[symp->n_un.n_strx]); 130*16667Sralph symp->n_un.n_strx = (ns - newstrings) + sizeof (int); 131*16667Sralph ns = index(ns, 0) + 1; 132*16667Sralph if (ns > &newstrings[symsize]) { 133*16667Sralph fprintf(stderr, "symorder: Strings grew longer!\n"); 134*16667Sralph exit(1); 135623Sbill } 136623Sbill } 137*16667Sralph 138*16667Sralph lseek(o, sa, 0); 139*16667Sralph if (write(o, (char *)symtab, n) != n) { 140*16667Sralph fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 141*16667Sralph exit(1); 142*16667Sralph } 143*16667Sralph if (write(o, (char *)&symsize, sizeof (int)) != sizeof (int)) { 144*16667Sralph fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 145*16667Sralph exit(1); 146*16667Sralph } 147*16667Sralph if (write(o, newstrings, symsize) != symsize) { 148*16667Sralph fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 149*16667Sralph exit(1); 150*16667Sralph } 151*16667Sralph if ((i = nsym - symfound) > 0) { 152*16667Sralph fprintf(stderr, "symorder: %d symbol%s not found:\n", 153*16667Sralph i, i == 1 ? "" : "s"); 154623Sbill for (i = 0; i < nsym; i++) { 155623Sbill if (order[i].n_value == 0) 156623Sbill printf("%s\n", order[i].n_un.n_name); 157623Sbill } 158623Sbill } 159*16667Sralph exit(0); 160623Sbill } 161623Sbill 162*16667Sralph reorder(st1, st2, n) 163*16667Sralph register struct nlist *st1, *st2; 164*16667Sralph register n; 165*16667Sralph { 166*16667Sralph register struct nlist *stp = st2 + nsym; 167*16667Sralph register i; 168*16667Sralph 169*16667Sralph while (--n >= 0) { 170*16667Sralph i = inlist(st1); 171*16667Sralph if (i == -1) 172*16667Sralph *stp++ = *st1++; 173*16667Sralph else 174*16667Sralph st2[i] = *st1++; 175*16667Sralph } 176*16667Sralph } 177*16667Sralph 178*16667Sralph inlist(p) 179*16667Sralph register struct nlist *p; 180*16667Sralph { 181*16667Sralph register char *nam; 182*16667Sralph register struct nlist *op; 183*16667Sralph 184*16667Sralph if (p->n_type & N_STAB) 185*16667Sralph return (-1); 186*16667Sralph if (p->n_un.n_strx == 0) 187*16667Sralph return (-1); 188*16667Sralph 189*16667Sralph nam = &strings[p->n_un.n_strx - sizeof(int)]; 190*16667Sralph if (nam >= &strings[symsize]) { 191*16667Sralph fprintf(stderr, "symorder: corrupt symtab\n"); 192*16667Sralph exit(1); 193*16667Sralph } 194*16667Sralph 195*16667Sralph for (op = &order[nsym]; --op >= order; ) { 196*16667Sralph if (strcmp(op->n_un.n_name, nam) != 0) 197*16667Sralph continue; 198*16667Sralph if (op->n_value == 0) { 199*16667Sralph op->n_value++; 200*16667Sralph symfound++; 201*16667Sralph } 202*16667Sralph return (op - order); 203*16667Sralph } 204*16667Sralph return (-1); 205*16667Sralph } 206*16667Sralph 207623Sbill #define NSAVETAB 4096 208623Sbill char *savetab; 209623Sbill int saveleft; 210623Sbill 211623Sbill char * 212623Sbill savestr(cp) 213623Sbill register char *cp; 214623Sbill { 215623Sbill register int len; 216623Sbill 217623Sbill len = strlen(cp) + 1; 218623Sbill if (len > saveleft) { 219623Sbill saveleft = NSAVETAB; 220623Sbill if (len > saveleft) 221623Sbill saveleft = len; 222623Sbill savetab = (char *)malloc(saveleft); 223623Sbill if (savetab == 0) { 224623Sbill fprintf(stderr, 225623Sbill "symorder: ran out of memory (savestr)\n"); 226623Sbill exit(1); 227623Sbill } 228623Sbill } 229623Sbill strncpy(savetab, cp, len); 230623Sbill cp = savetab; 231623Sbill savetab += len; 232623Sbill saveleft -= len; 233623Sbill return (cp); 234623Sbill } 235