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