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) 07/02/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 } 252