1: /* 2: * Copyright (c) 1980 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #ifndef lint 8: char copyright[] = 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: #endif not lint 12: 13: #ifndef lint 14: static char sccsid[] = "@(#)symorder.c 5.2 (Berkeley) 7/2/85"; 15: #endif not lint 16: 17: /* 18: * symorder - reorder symbol table 19: */ 20: 21: #include <stdio.h> 22: #include <sys/types.h> 23: #include <sys/stat.h> 24: #include <a.out.h> 25: 26: #define SPACE 100 27: 28: struct nlist order[SPACE]; 29: 30: char *savestr(), *index(), *malloc(); 31: struct exec exec; 32: off_t sa; 33: struct stat stb; 34: int nsym = 0; 35: int symfound = 0; 36: char *strings; 37: char *newstrings; 38: struct nlist *symtab; 39: struct nlist *newtab; 40: int symsize; 41: char asym[BUFSIZ]; 42: 43: main(argc, argv) 44: char **argv; 45: { 46: register char *ns; 47: register struct nlist *symp; 48: register struct nlist *p; 49: register FILE *f; 50: register int i; 51: int n, o; 52: 53: if (argc != 3) { 54: fprintf(stderr, "Usage: symorder orderlist file\n"); 55: exit(1); 56: } 57: if ((f = fopen(argv[1], "r")) == NULL) { 58: perror(argv[1]); 59: exit(1); 60: } 61: for (p = order; fgets(asym, sizeof asym, f) != NULL; p++, nsym++) { 62: for (i = 0; asym[i] && asym[i] != '\n'; i++) 63: continue; 64: if (asym[i] == '\n') 65: asym[i] = 0; 66: p->n_un.n_name = savestr(asym); 67: } 68: fclose(f); 69: if ((f = fopen(argv[2], "r")) == NULL) 70: perror(argv[2]), exit(1); 71: if ((o = open(argv[2], 1)) < 0) 72: perror(argv[2]), exit(1); 73: if ((fread(&exec, sizeof exec, 1, f)) != 1 || N_BADMAG(exec)) { 74: fprintf(stderr, "symorder: %s: bad format\n", argv[2]); 75: exit(1); 76: } 77: if (exec.a_syms == 0) { 78: fprintf(stderr, "symorder: %s is stripped\n", argv[2]); 79: exit(1); 80: } 81: fstat(fileno(f), &stb); 82: if (stb.st_size < N_STROFF(exec)+sizeof(off_t)) { 83: fprintf(stderr, "symorder: %s is in old format or truncated\n", 84: argv[2]); 85: exit(1); 86: } 87: sa = N_SYMOFF(exec); 88: fseek(f, sa, 0); 89: n = exec.a_syms; 90: symtab = (struct nlist *)malloc(n); 91: if (symtab == (struct nlist *)0) { 92: fprintf(stderr, "symorder: Out of core, no space for symtab\n"); 93: exit(1); 94: } 95: if (fread((char *)symtab, 1, n, f) != n) { 96: fprintf(stderr, "symorder: Short file "); perror(argv[2]); 97: exit(1); 98: } 99: if (fread((char *)&symsize, sizeof (int), 1, f) != 1 || 100: symsize <= 0) { 101: fprintf(stderr, "symorder: No strings "); perror(argv[2]); 102: exit(1); 103: } 104: strings = malloc(symsize); 105: if (strings == (char *)0) { 106: fprintf(stderr,"symorder: Out of core, no space for strings\n"); 107: exit(1); 108: } 109: /* 110: * Need to subtract four from symsize here since 111: * symsize includes itself, and we've already read 112: * it. (6/30/85 chris@maryland) 113: */ 114: if (fread(strings, 1, symsize - 4, f) != symsize - 4) { 115: fprintf(stderr, "symorder: Truncated strings "); 116: perror(argv[2]); 117: exit(1); 118: } 119: 120: newtab = (struct nlist *)malloc(n); 121: if (newtab == (struct nlist *)0) { 122: fprintf(stderr, 123: "symorder: Out of core, no space for new symtab\n"); 124: exit(1); 125: } 126: i = n / sizeof (struct nlist); 127: reorder(symtab, newtab, i); 128: free((char *)symtab); 129: symtab = newtab; 130: 131: newstrings = malloc(symsize); 132: if (newstrings == (char *)0) { 133: fprintf(stderr, 134: "symorder: Out of core, no space for newstrings\n"); 135: exit(1); 136: } 137: ns = newstrings; 138: for (symp = symtab; --i >= 0; symp++) { 139: if (symp->n_un.n_strx == 0) 140: continue; 141: symp->n_un.n_strx -= sizeof (int); 142: if ((unsigned)symp->n_un.n_strx >= symsize) { 143: fprintf(stderr,"symorder: Corrupted string pointers\n"); 144: exit(1); 145: } 146: strcpy(ns, &strings[symp->n_un.n_strx]); 147: symp->n_un.n_strx = (ns - newstrings) + sizeof (int); 148: ns = index(ns, 0) + 1; 149: if (ns > &newstrings[symsize]) { 150: fprintf(stderr, "symorder: Strings grew longer!\n"); 151: exit(1); 152: } 153: } 154: 155: lseek(o, sa, 0); 156: if (write(o, (char *)symtab, n) != n) { 157: fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 158: exit(1); 159: } 160: if (write(o, (char *)&symsize, sizeof (int)) != sizeof (int)) { 161: fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 162: exit(1); 163: } 164: if (write(o, newstrings, symsize - 4) != symsize - 4) { 165: fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 166: exit(1); 167: } 168: if ((i = nsym - symfound) > 0) { 169: fprintf(stderr, "symorder: %d symbol%s not found:\n", 170: i, i == 1 ? "" : "s"); 171: for (i = 0; i < nsym; i++) { 172: if (order[i].n_value == 0) 173: printf("%s\n", order[i].n_un.n_name); 174: } 175: } 176: exit(0); 177: } 178: 179: reorder(st1, st2, n) 180: register struct nlist *st1, *st2; 181: register n; 182: { 183: register struct nlist *stp = st2 + nsym; 184: register i; 185: 186: while (--n >= 0) { 187: i = inlist(st1); 188: if (i == -1) 189: *stp++ = *st1++; 190: else 191: st2[i] = *st1++; 192: } 193: } 194: 195: inlist(p) 196: register struct nlist *p; 197: { 198: register char *nam; 199: register struct nlist *op; 200: 201: if (p->n_type & N_STAB) 202: return (-1); 203: if (p->n_un.n_strx == 0) 204: return (-1); 205: 206: nam = &strings[p->n_un.n_strx - sizeof(int)]; 207: if (nam >= &strings[symsize]) { 208: fprintf(stderr, "symorder: corrupt symtab\n"); 209: exit(1); 210: } 211: 212: for (op = &order[nsym]; --op >= order; ) { 213: if (strcmp(op->n_un.n_name, nam) != 0) 214: continue; 215: if (op->n_value == 0) { 216: op->n_value++; 217: symfound++; 218: } 219: return (op - order); 220: } 221: return (-1); 222: } 223: 224: #define NSAVETAB 4096 225: char *savetab; 226: int saveleft; 227: 228: char * 229: savestr(cp) 230: register char *cp; 231: { 232: register int len; 233: 234: len = strlen(cp) + 1; 235: if (len > saveleft) { 236: saveleft = NSAVETAB; 237: if (len > saveleft) 238: saveleft = len; 239: savetab = (char *)malloc(saveleft); 240: if (savetab == 0) { 241: fprintf(stderr, 242: "symorder: ran out of memory (savestr)\n"); 243: exit(1); 244: } 245: } 246: strncpy(savetab, cp, len); 247: cp = savetab; 248: savetab += len; 249: saveleft -= len; 250: return (cp); 251: }