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.5 (Berkeley) 02/01/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 struct nlist order[SPACE]; 35 36 struct exec exec; 37 struct stat stb; 38 struct nlist *newtab, *symtab; 39 off_t sa; 40 int nsym, strtabsize, symfound; 41 char *kfile, *newstrings, *strings, asym[BUFSIZ]; 42 43 main(argc, argv) 44 int argc; 45 char **argv; 46 { 47 register struct nlist *p, *symp; 48 register FILE *f; 49 register int i; 50 register char *start, *t; 51 int n, o; 52 53 if (argc != 3) { 54 (void)fprintf(stderr, "usage: symorder orderlist file\n"); 55 exit(1); 56 } 57 if ((f = fopen(argv[1], "r")) == NULL) 58 error(argv[1]); 59 60 for (p = order; fgets(asym, sizeof(asym), f) != NULL;) { 61 for (t = asym; isspace(*t); ++t); 62 if (!*(start = t)) 63 continue; 64 while (*++t); 65 if (*--t == '\n') 66 *t = '\0'; 67 p->n_un.n_name = strdup(start); 68 ++p; 69 ++nsym; 70 } 71 (void)fclose(f); 72 73 kfile = argv[2]; 74 if ((f = fopen(kfile, "r")) == NULL) 75 error(kfile); 76 if ((o = open(kfile, O_WRONLY)) < 0) 77 error(kfile); 78 79 /* read exec header */ 80 if ((fread(&exec, sizeof(exec), 1, f)) != 1) 81 badfmt("no exec header"); 82 if (N_BADMAG(exec)) 83 badfmt("bad magic number"); 84 if (exec.a_syms == 0) 85 badfmt("stripped"); 86 (void)fstat(fileno(f), &stb); 87 if (stb.st_size < N_STROFF(exec) + sizeof(off_t)) 88 badfmt("no string table"); 89 90 /* seek to and read the symbol table */ 91 sa = N_SYMOFF(exec); 92 (void)fseek(f, sa, SEEK_SET); 93 n = exec.a_syms; 94 if (!(symtab = (struct nlist *)malloc(n))) 95 error((char *)NULL); 96 if (fread((char *)symtab, 1, n, f) != n) 97 badfmt("corrupted symbol table"); 98 99 /* read string table size and string table */ 100 if (fread((char *)&strtabsize, sizeof(int), 1, f) != 1 || 101 strtabsize <= 0) 102 badfmt("corrupted string table"); 103 strings = malloc(strtabsize); 104 if (strings == (char *)NULL) 105 error((char *)NULL); 106 /* 107 * Subtract four from strtabsize since strtabsize includes itself, 108 * and we've already read it. 109 */ 110 if (fread(strings, 1, strtabsize - sizeof(int), f) != 111 strtabsize - sizeof(int)) 112 badfmt("corrupted string table"); 113 114 newtab = (struct nlist *)malloc(n); 115 if (newtab == (struct nlist *)NULL) 116 error((char *)NULL); 117 118 i = n / sizeof(struct nlist); 119 reorder(symtab, newtab, i); 120 free((char *)symtab); 121 symtab = newtab; 122 123 newstrings = malloc(strtabsize); 124 if (newstrings == (char *)NULL) 125 error((char *)NULL); 126 t = newstrings; 127 for (symp = symtab; --i >= 0; symp++) { 128 if (symp->n_un.n_strx == 0) 129 continue; 130 symp->n_un.n_strx -= sizeof(int); 131 (void)strcpy(t, &strings[symp->n_un.n_strx]); 132 symp->n_un.n_strx = (t - newstrings) + sizeof(int); 133 t += strlen(t) + 1; 134 } 135 136 (void)lseek(o, sa, SEEK_SET); 137 if (write(o, (char *)symtab, n) != n) 138 error(kfile); 139 if (write(o, (char *)&strtabsize, sizeof(int)) != sizeof(int)) 140 error(kfile); 141 if (write(o, newstrings, strtabsize - sizeof(int)) != 142 strtabsize - sizeof(int)) 143 error(kfile); 144 if ((i = nsym - symfound) > 0) { 145 (void)printf("symorder: %d symbol%s not found:\n", 146 i, i == 1 ? "" : "s"); 147 for (i = 0; i < nsym; i++) 148 if (order[i].n_value == 0) 149 printf("%s\n", order[i].n_un.n_name); 150 } 151 exit(0); 152 } 153 154 reorder(st1, st2, entries) 155 register struct nlist *st1, *st2; 156 int entries; 157 { 158 register struct nlist *p; 159 register int i, n; 160 161 for (p = st1, n = entries; --n >= 0; ++p) 162 if (inlist(p) != -1) 163 ++symfound; 164 for (p = st2 + symfound, n = entries; --n >= 0; ++st1) { 165 i = inlist(st1); 166 if (i == -1) 167 *p++ = *st1; 168 else 169 st2[i] = *st1; 170 } 171 } 172 173 inlist(p) 174 register struct nlist *p; 175 { 176 register char *nam; 177 register struct nlist *op; 178 179 if (p->n_type & N_STAB) 180 return (-1); 181 if (p->n_un.n_strx == 0) 182 return (-1); 183 184 if (p->n_un.n_strx >= strtabsize) 185 badfmt("corrupted symbol table"); 186 187 nam = &strings[p->n_un.n_strx - sizeof(int)]; 188 for (op = &order[nsym]; --op >= order; ) { 189 if (strcmp(op->n_un.n_name, nam) != 0) 190 continue; 191 op->n_value = 1; 192 return (op - order); 193 } 194 return (-1); 195 } 196 197 badfmt(why) 198 char *why; 199 { 200 (void)fprintf(stderr, 201 "symorder: %s: %s: %s\n", kfile, why, strerror(EFTYPE)); 202 exit(1); 203 } 204 205 error(n) 206 char *n; 207 { 208 int sverr; 209 210 sverr = errno; 211 (void)fprintf(stderr, "symorder: "); 212 if (n) 213 (void)fprintf(stderr, "%s: ", n); 214 (void)fprintf(stderr, "%s\n", strerror(sverr)); 215 exit(1); 216 } 217