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.1 (Berkeley) 05/31/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 if (fread(strings, 1, symsize, f) != symsize) { 110 fprintf(stderr, "symorder: Truncated strings "); 111 perror(argv[2]); 112 exit(1); 113 } 114 115 newtab = (struct nlist *)malloc(n); 116 if (newtab == (struct nlist *)0) { 117 fprintf(stderr, 118 "symorder: Out of core, no space for new symtab\n"); 119 exit(1); 120 } 121 i = n / sizeof (struct nlist); 122 reorder(symtab, newtab, i); 123 free((char *)symtab); 124 symtab = newtab; 125 126 newstrings = malloc(symsize); 127 if (newstrings == (char *)0) { 128 fprintf(stderr, 129 "symorder: Out of core, no space for newstrings\n"); 130 exit(1); 131 } 132 ns = newstrings; 133 for (symp = symtab; --i >= 0; symp++) { 134 if (symp->n_un.n_strx == 0) 135 continue; 136 symp->n_un.n_strx -= sizeof (int); 137 if ((unsigned)symp->n_un.n_strx >= symsize) { 138 fprintf(stderr,"symorder: Corrupted string pointers\n"); 139 exit(1); 140 } 141 strcpy(ns, &strings[symp->n_un.n_strx]); 142 symp->n_un.n_strx = (ns - newstrings) + sizeof (int); 143 ns = index(ns, 0) + 1; 144 if (ns > &newstrings[symsize]) { 145 fprintf(stderr, "symorder: Strings grew longer!\n"); 146 exit(1); 147 } 148 } 149 150 lseek(o, sa, 0); 151 if (write(o, (char *)symtab, n) != n) { 152 fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 153 exit(1); 154 } 155 if (write(o, (char *)&symsize, sizeof (int)) != sizeof (int)) { 156 fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 157 exit(1); 158 } 159 if (write(o, newstrings, symsize) != symsize) { 160 fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 161 exit(1); 162 } 163 if ((i = nsym - symfound) > 0) { 164 fprintf(stderr, "symorder: %d symbol%s not found:\n", 165 i, i == 1 ? "" : "s"); 166 for (i = 0; i < nsym; i++) { 167 if (order[i].n_value == 0) 168 printf("%s\n", order[i].n_un.n_name); 169 } 170 } 171 exit(0); 172 } 173 174 reorder(st1, st2, n) 175 register struct nlist *st1, *st2; 176 register n; 177 { 178 register struct nlist *stp = st2 + nsym; 179 register i; 180 181 while (--n >= 0) { 182 i = inlist(st1); 183 if (i == -1) 184 *stp++ = *st1++; 185 else 186 st2[i] = *st1++; 187 } 188 } 189 190 inlist(p) 191 register struct nlist *p; 192 { 193 register char *nam; 194 register struct nlist *op; 195 196 if (p->n_type & N_STAB) 197 return (-1); 198 if (p->n_un.n_strx == 0) 199 return (-1); 200 201 nam = &strings[p->n_un.n_strx - sizeof(int)]; 202 if (nam >= &strings[symsize]) { 203 fprintf(stderr, "symorder: corrupt symtab\n"); 204 exit(1); 205 } 206 207 for (op = &order[nsym]; --op >= order; ) { 208 if (strcmp(op->n_un.n_name, nam) != 0) 209 continue; 210 if (op->n_value == 0) { 211 op->n_value++; 212 symfound++; 213 } 214 return (op - order); 215 } 216 return (-1); 217 } 218 219 #define NSAVETAB 4096 220 char *savetab; 221 int saveleft; 222 223 char * 224 savestr(cp) 225 register char *cp; 226 { 227 register int len; 228 229 len = strlen(cp) + 1; 230 if (len > saveleft) { 231 saveleft = NSAVETAB; 232 if (len > saveleft) 233 saveleft = len; 234 savetab = (char *)malloc(saveleft); 235 if (savetab == 0) { 236 fprintf(stderr, 237 "symorder: ran out of memory (savestr)\n"); 238 exit(1); 239 } 240 } 241 strncpy(savetab, cp, len); 242 cp = savetab; 243 savetab += len; 244 saveleft -= len; 245 return (cp); 246 } 247