121578Sdist /* 236196Sbostic * Copyright (c) 1980 The Regents of the University of California. 336196Sbostic * All rights reserved. 436196Sbostic * 5*42693Sbostic * %sccs.include.redist.c% 621578Sdist */ 721578Sdist 812674Ssam #ifndef lint 921578Sdist char copyright[] = 1036196Sbostic "@(#) Copyright (c) 1980 The Regents of the University of California.\n\ 1121578Sdist All rights reserved.\n"; 1236196Sbostic #endif /* not lint */ 1316667Sralph 1421578Sdist #ifndef lint 15*42693Sbostic static char sccsid[] = "@(#)symorder.c 5.4 (Berkeley) 06/01/90"; 1636196Sbostic #endif /* not lint */ 1721578Sdist 18623Sbill /* 19623Sbill * symorder - reorder symbol table 20623Sbill */ 2116667Sralph 22623Sbill #include <stdio.h> 23623Sbill #include <sys/types.h> 2413621Ssam #include <sys/stat.h> 25934Sbill #include <a.out.h> 26623Sbill 27623Sbill #define SPACE 100 28623Sbill 29623Sbill struct nlist order[SPACE]; 30623Sbill 3116667Sralph char *savestr(), *index(), *malloc(); 32623Sbill struct exec exec; 3316667Sralph off_t sa; 34623Sbill struct stat stb; 35623Sbill int nsym = 0; 36623Sbill int symfound = 0; 3716667Sralph char *strings; 3816667Sralph char *newstrings; 3916667Sralph struct nlist *symtab; 4016667Sralph struct nlist *newtab; 4116667Sralph int symsize; 42623Sbill char asym[BUFSIZ]; 43623Sbill 44623Sbill main(argc, argv) 45623Sbill char **argv; 46623Sbill { 4716667Sralph register char *ns; 4816667Sralph register struct nlist *symp; 4916667Sralph register struct nlist *p; 50623Sbill register FILE *f; 5116667Sralph register int i; 52623Sbill int n, o; 53623Sbill 5416667Sralph if (argc != 3) { 55623Sbill fprintf(stderr, "Usage: symorder orderlist file\n"); 56623Sbill exit(1); 57623Sbill } 5816667Sralph if ((f = fopen(argv[1], "r")) == NULL) { 59623Sbill perror(argv[1]); 60623Sbill exit(1); 61623Sbill } 6216667Sralph for (p = order; fgets(asym, sizeof asym, f) != NULL; p++, nsym++) { 6316667Sralph for (i = 0; asym[i] && asym[i] != '\n'; i++) 64623Sbill continue; 65623Sbill if (asym[i] == '\n') 66623Sbill asym[i] = 0; 67623Sbill p->n_un.n_name = savestr(asym); 68623Sbill } 69623Sbill fclose(f); 7016667Sralph if ((f = fopen(argv[2], "r")) == NULL) 71623Sbill perror(argv[2]), exit(1); 7216667Sralph if ((o = open(argv[2], 1)) < 0) 73623Sbill perror(argv[2]), exit(1); 7416667Sralph if ((fread(&exec, sizeof exec, 1, f)) != 1 || N_BADMAG(exec)) { 75623Sbill fprintf(stderr, "symorder: %s: bad format\n", argv[2]); 76623Sbill exit(1); 77623Sbill } 78623Sbill if (exec.a_syms == 0) { 79623Sbill fprintf(stderr, "symorder: %s is stripped\n", argv[2]); 80623Sbill exit(1); 81623Sbill } 82623Sbill fstat(fileno(f), &stb); 83623Sbill if (stb.st_size < N_STROFF(exec)+sizeof(off_t)) { 8416667Sralph fprintf(stderr, "symorder: %s is in old format or truncated\n", 8516667Sralph argv[2]); 86623Sbill exit(1); 87623Sbill } 88623Sbill sa = N_SYMOFF(exec); 89623Sbill fseek(f, sa, 0); 90623Sbill n = exec.a_syms; 9116667Sralph symtab = (struct nlist *)malloc(n); 9216667Sralph if (symtab == (struct nlist *)0) { 9316667Sralph fprintf(stderr, "symorder: Out of core, no space for symtab\n"); 9416667Sralph exit(1); 9516667Sralph } 9616667Sralph if (fread((char *)symtab, 1, n, f) != n) { 9716667Sralph fprintf(stderr, "symorder: Short file "); perror(argv[2]); 9816667Sralph exit(1); 9916667Sralph } 10016667Sralph if (fread((char *)&symsize, sizeof (int), 1, f) != 1 || 10116667Sralph symsize <= 0) { 10216667Sralph fprintf(stderr, "symorder: No strings "); perror(argv[2]); 10316667Sralph exit(1); 10416667Sralph } 10516667Sralph strings = malloc(symsize); 10616667Sralph if (strings == (char *)0) { 10716667Sralph fprintf(stderr,"symorder: Out of core, no space for strings\n"); 10816667Sralph exit(1); 10916667Sralph } 11023838Smckusick /* 11123838Smckusick * Need to subtract four from symsize here since 11223838Smckusick * symsize includes itself, and we've already read 11323838Smckusick * it. (6/30/85 chris@maryland) 11423838Smckusick */ 11523838Smckusick if (fread(strings, 1, symsize - 4, f) != symsize - 4) { 11616667Sralph fprintf(stderr, "symorder: Truncated strings "); 11716667Sralph perror(argv[2]); 11816667Sralph exit(1); 11916667Sralph } 12016667Sralph 12116667Sralph newtab = (struct nlist *)malloc(n); 12216667Sralph if (newtab == (struct nlist *)0) { 12316667Sralph fprintf(stderr, 12416667Sralph "symorder: Out of core, no space for new symtab\n"); 12516667Sralph exit(1); 12616667Sralph } 12716667Sralph i = n / sizeof (struct nlist); 12816667Sralph reorder(symtab, newtab, i); 12916667Sralph free((char *)symtab); 13016667Sralph symtab = newtab; 13116667Sralph 13216667Sralph newstrings = malloc(symsize); 13316667Sralph if (newstrings == (char *)0) { 13416667Sralph fprintf(stderr, 13516667Sralph "symorder: Out of core, no space for newstrings\n"); 13616667Sralph exit(1); 13716667Sralph } 13816667Sralph ns = newstrings; 13916667Sralph for (symp = symtab; --i >= 0; symp++) { 14016667Sralph if (symp->n_un.n_strx == 0) 14116667Sralph continue; 14216667Sralph symp->n_un.n_strx -= sizeof (int); 14316667Sralph if ((unsigned)symp->n_un.n_strx >= symsize) { 14416667Sralph fprintf(stderr,"symorder: Corrupted string pointers\n"); 145623Sbill exit(1); 146623Sbill } 14716667Sralph strcpy(ns, &strings[symp->n_un.n_strx]); 14816667Sralph symp->n_un.n_strx = (ns - newstrings) + sizeof (int); 14916667Sralph ns = index(ns, 0) + 1; 15016667Sralph if (ns > &newstrings[symsize]) { 15116667Sralph fprintf(stderr, "symorder: Strings grew longer!\n"); 15216667Sralph exit(1); 153623Sbill } 154623Sbill } 15516667Sralph 15616667Sralph lseek(o, sa, 0); 15716667Sralph if (write(o, (char *)symtab, n) != n) { 15816667Sralph fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 15916667Sralph exit(1); 16016667Sralph } 16116667Sralph if (write(o, (char *)&symsize, sizeof (int)) != sizeof (int)) { 16216667Sralph fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 16316667Sralph exit(1); 16416667Sralph } 16523838Smckusick if (write(o, newstrings, symsize - 4) != symsize - 4) { 16616667Sralph fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 16716667Sralph exit(1); 16816667Sralph } 16916667Sralph if ((i = nsym - symfound) > 0) { 17016667Sralph fprintf(stderr, "symorder: %d symbol%s not found:\n", 17116667Sralph i, i == 1 ? "" : "s"); 172623Sbill for (i = 0; i < nsym; i++) { 173623Sbill if (order[i].n_value == 0) 174623Sbill printf("%s\n", order[i].n_un.n_name); 175623Sbill } 176623Sbill } 17716667Sralph exit(0); 178623Sbill } 179623Sbill 18016667Sralph reorder(st1, st2, n) 18116667Sralph register struct nlist *st1, *st2; 18216667Sralph register n; 18316667Sralph { 18416667Sralph register struct nlist *stp = st2 + nsym; 18516667Sralph register i; 18616667Sralph 18716667Sralph while (--n >= 0) { 18816667Sralph i = inlist(st1); 18916667Sralph if (i == -1) 19016667Sralph *stp++ = *st1++; 19116667Sralph else 19216667Sralph st2[i] = *st1++; 19316667Sralph } 19416667Sralph } 19516667Sralph 19616667Sralph inlist(p) 19716667Sralph register struct nlist *p; 19816667Sralph { 19916667Sralph register char *nam; 20016667Sralph register struct nlist *op; 20116667Sralph 20216667Sralph if (p->n_type & N_STAB) 20316667Sralph return (-1); 20416667Sralph if (p->n_un.n_strx == 0) 20516667Sralph return (-1); 20616667Sralph 20716667Sralph nam = &strings[p->n_un.n_strx - sizeof(int)]; 20816667Sralph if (nam >= &strings[symsize]) { 20916667Sralph fprintf(stderr, "symorder: corrupt symtab\n"); 21016667Sralph exit(1); 21116667Sralph } 21216667Sralph 21316667Sralph for (op = &order[nsym]; --op >= order; ) { 21416667Sralph if (strcmp(op->n_un.n_name, nam) != 0) 21516667Sralph continue; 21616667Sralph if (op->n_value == 0) { 21716667Sralph op->n_value++; 21816667Sralph symfound++; 21916667Sralph } 22016667Sralph return (op - order); 22116667Sralph } 22216667Sralph return (-1); 22316667Sralph } 22416667Sralph 225623Sbill #define NSAVETAB 4096 226623Sbill char *savetab; 227623Sbill int saveleft; 228623Sbill 229623Sbill char * 230623Sbill savestr(cp) 231623Sbill register char *cp; 232623Sbill { 233623Sbill register int len; 234623Sbill 235623Sbill len = strlen(cp) + 1; 236623Sbill if (len > saveleft) { 237623Sbill saveleft = NSAVETAB; 238623Sbill if (len > saveleft) 239623Sbill saveleft = len; 240623Sbill savetab = (char *)malloc(saveleft); 241623Sbill if (savetab == 0) { 242623Sbill fprintf(stderr, 243623Sbill "symorder: ran out of memory (savestr)\n"); 244623Sbill exit(1); 245623Sbill } 246623Sbill } 247623Sbill strncpy(savetab, cp, len); 248623Sbill cp = savetab; 249623Sbill savetab += len; 250623Sbill saveleft -= len; 251623Sbill return (cp); 252623Sbill } 253