1 /* 2 * Copyright (c) 1980 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)symorder.c 5.6 (Berkeley) 02/04/91"; 16 #endif /* not lint */ 17 18 /* 19 * symorder - reorder symbol table 20 */ 21 22 #include <sys/types.h> 23 #include <sys/stat.h> 24 #include <fcntl.h> 25 #include <errno.h> 26 #include <a.out.h> 27 #include <unistd.h> 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 32 #define SPACE 500 33 34 #define OKEXIT 0 35 #define NOTFOUNDEXIT 1 36 #define ERREXIT 2 37 38 struct nlist order[SPACE]; 39 40 struct exec exec; 41 struct stat stb; 42 struct nlist *newtab, *symtab; 43 off_t sa; 44 int nsym, strtabsize, symfound; 45 char *kfile, *newstrings, *strings, asym[BUFSIZ]; 46 47 main(argc, argv) 48 int argc; 49 char **argv; 50 { 51 register struct nlist *p, *symp; 52 register FILE *f; 53 register int i; 54 register char *start, *t; 55 int n, o; 56 57 if (argc != 3) { 58 (void)fprintf(stderr, "usage: symorder orderlist file\n"); 59 exit(ERREXIT); 60 } 61 if ((f = fopen(argv[1], "r")) == NULL) 62 error(argv[1]); 63 64 for (p = order; fgets(asym, sizeof(asym), f) != NULL;) { 65 for (t = asym; isspace(*t); ++t); 66 if (!*(start = t)) 67 continue; 68 while (*++t); 69 if (*--t == '\n') 70 *t = '\0'; 71 p->n_un.n_name = strdup(start); 72 ++p; 73 ++nsym; 74 } 75 (void)fclose(f); 76 77 kfile = argv[2]; 78 if ((f = fopen(kfile, "r")) == NULL) 79 error(kfile); 80 if ((o = open(kfile, O_WRONLY)) < 0) 81 error(kfile); 82 83 /* read exec header */ 84 if ((fread(&exec, sizeof(exec), 1, f)) != 1) 85 badfmt("no exec header"); 86 if (N_BADMAG(exec)) 87 badfmt("bad magic number"); 88 if (exec.a_syms == 0) 89 badfmt("stripped"); 90 (void)fstat(fileno(f), &stb); 91 if (stb.st_size < N_STROFF(exec) + sizeof(off_t)) 92 badfmt("no string table"); 93 94 /* seek to and read the symbol table */ 95 sa = N_SYMOFF(exec); 96 (void)fseek(f, sa, SEEK_SET); 97 n = exec.a_syms; 98 if (!(symtab = (struct nlist *)malloc(n))) 99 error((char *)NULL); 100 if (fread((char *)symtab, 1, n, f) != n) 101 badfmt("corrupted symbol table"); 102 103 /* read string table size and string table */ 104 if (fread((char *)&strtabsize, sizeof(int), 1, f) != 1 || 105 strtabsize <= 0) 106 badfmt("corrupted string table"); 107 strings = malloc(strtabsize); 108 if (strings == (char *)NULL) 109 error((char *)NULL); 110 /* 111 * Subtract four from strtabsize since strtabsize includes itself, 112 * and we've already read it. 113 */ 114 if (fread(strings, 1, strtabsize - sizeof(int), f) != 115 strtabsize - sizeof(int)) 116 badfmt("corrupted string table"); 117 118 newtab = (struct nlist *)malloc(n); 119 if (newtab == (struct nlist *)NULL) 120 error((char *)NULL); 121 122 i = n / sizeof(struct nlist); 123 reorder(symtab, newtab, i); 124 free((char *)symtab); 125 symtab = newtab; 126 127 newstrings = malloc(strtabsize); 128 if (newstrings == (char *)NULL) 129 error((char *)NULL); 130 t = newstrings; 131 for (symp = symtab; --i >= 0; symp++) { 132 if (symp->n_un.n_strx == 0) 133 continue; 134 symp->n_un.n_strx -= sizeof(int); 135 (void)strcpy(t, &strings[symp->n_un.n_strx]); 136 symp->n_un.n_strx = (t - newstrings) + sizeof(int); 137 t += strlen(t) + 1; 138 } 139 140 (void)lseek(o, sa, SEEK_SET); 141 if (write(o, (char *)symtab, n) != n) 142 error(kfile); 143 if (write(o, (char *)&strtabsize, sizeof(int)) != sizeof(int)) 144 error(kfile); 145 if (write(o, newstrings, strtabsize - sizeof(int)) != 146 strtabsize - sizeof(int)) 147 error(kfile); 148 if ((i = nsym - symfound) > 0) { 149 (void)printf("symorder: %d symbol%s not found:\n", 150 i, i == 1 ? "" : "s"); 151 for (i = 0; i < nsym; i++) 152 if (order[i].n_value == 0) 153 printf("%s\n", order[i].n_un.n_name); 154 exit(NOTFOUNDEXIT); 155 } 156 exit(OKEXIT); 157 } 158 159 reorder(st1, st2, entries) 160 register struct nlist *st1, *st2; 161 int entries; 162 { 163 register struct nlist *p; 164 register int i, n; 165 166 for (p = st1, n = entries; --n >= 0; ++p) 167 if (inlist(p) != -1) 168 ++symfound; 169 for (p = st2 + symfound, n = entries; --n >= 0; ++st1) { 170 i = inlist(st1); 171 if (i == -1) 172 *p++ = *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 if (p->n_un.n_strx >= strtabsize) 190 badfmt("corrupted symbol table"); 191 192 nam = &strings[p->n_un.n_strx - sizeof(int)]; 193 for (op = &order[nsym]; --op >= order; ) { 194 if (strcmp(op->n_un.n_name, nam) != 0) 195 continue; 196 op->n_value = 1; 197 return (op - order); 198 } 199 return (-1); 200 } 201 202 badfmt(why) 203 char *why; 204 { 205 (void)fprintf(stderr, 206 "symorder: %s: %s: %s\n", kfile, why, strerror(EFTYPE)); 207 exit(ERREXIT); 208 } 209 210 error(n) 211 char *n; 212 { 213 int sverr; 214 215 sverr = errno; 216 (void)fprintf(stderr, "symorder: "); 217 if (n) 218 (void)fprintf(stderr, "%s: ", n); 219 (void)fprintf(stderr, "%s\n", strerror(sverr)); 220 exit(ERREXIT); 221 } 222