1*21578Sdist /* 2*21578Sdist * Copyright (c) 1980 Regents of the University of California. 3*21578Sdist * All rights reserved. The Berkeley software License Agreement 4*21578Sdist * specifies the terms and conditions for redistribution. 5*21578Sdist */ 6*21578Sdist 712674Ssam #ifndef lint 8*21578Sdist char copyright[] = 9*21578Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10*21578Sdist All rights reserved.\n"; 11*21578Sdist #endif not lint 1216667Sralph 13*21578Sdist #ifndef lint 14*21578Sdist static char sccsid[] = "@(#)symorder.c 5.1 (Berkeley) 05/31/85"; 15*21578Sdist #endif not lint 16*21578Sdist 17623Sbill /* 18623Sbill * symorder - reorder symbol table 19623Sbill */ 2016667Sralph 21623Sbill #include <stdio.h> 22623Sbill #include <sys/types.h> 2313621Ssam #include <sys/stat.h> 24934Sbill #include <a.out.h> 25623Sbill 26623Sbill #define SPACE 100 27623Sbill 28623Sbill struct nlist order[SPACE]; 29623Sbill 3016667Sralph char *savestr(), *index(), *malloc(); 31623Sbill struct exec exec; 3216667Sralph off_t sa; 33623Sbill struct stat stb; 34623Sbill int nsym = 0; 35623Sbill int symfound = 0; 3616667Sralph char *strings; 3716667Sralph char *newstrings; 3816667Sralph struct nlist *symtab; 3916667Sralph struct nlist *newtab; 4016667Sralph int symsize; 41623Sbill char asym[BUFSIZ]; 42623Sbill 43623Sbill main(argc, argv) 44623Sbill char **argv; 45623Sbill { 4616667Sralph register char *ns; 4716667Sralph register struct nlist *symp; 4816667Sralph register struct nlist *p; 49623Sbill register FILE *f; 5016667Sralph register int i; 51623Sbill int n, o; 52623Sbill 5316667Sralph if (argc != 3) { 54623Sbill fprintf(stderr, "Usage: symorder orderlist file\n"); 55623Sbill exit(1); 56623Sbill } 5716667Sralph if ((f = fopen(argv[1], "r")) == NULL) { 58623Sbill perror(argv[1]); 59623Sbill exit(1); 60623Sbill } 6116667Sralph for (p = order; fgets(asym, sizeof asym, f) != NULL; p++, nsym++) { 6216667Sralph for (i = 0; asym[i] && asym[i] != '\n'; i++) 63623Sbill continue; 64623Sbill if (asym[i] == '\n') 65623Sbill asym[i] = 0; 66623Sbill p->n_un.n_name = savestr(asym); 67623Sbill } 68623Sbill fclose(f); 6916667Sralph if ((f = fopen(argv[2], "r")) == NULL) 70623Sbill perror(argv[2]), exit(1); 7116667Sralph if ((o = open(argv[2], 1)) < 0) 72623Sbill perror(argv[2]), exit(1); 7316667Sralph if ((fread(&exec, sizeof exec, 1, f)) != 1 || N_BADMAG(exec)) { 74623Sbill fprintf(stderr, "symorder: %s: bad format\n", argv[2]); 75623Sbill exit(1); 76623Sbill } 77623Sbill if (exec.a_syms == 0) { 78623Sbill fprintf(stderr, "symorder: %s is stripped\n", argv[2]); 79623Sbill exit(1); 80623Sbill } 81623Sbill fstat(fileno(f), &stb); 82623Sbill if (stb.st_size < N_STROFF(exec)+sizeof(off_t)) { 8316667Sralph fprintf(stderr, "symorder: %s is in old format or truncated\n", 8416667Sralph argv[2]); 85623Sbill exit(1); 86623Sbill } 87623Sbill sa = N_SYMOFF(exec); 88623Sbill fseek(f, sa, 0); 89623Sbill n = exec.a_syms; 9016667Sralph symtab = (struct nlist *)malloc(n); 9116667Sralph if (symtab == (struct nlist *)0) { 9216667Sralph fprintf(stderr, "symorder: Out of core, no space for symtab\n"); 9316667Sralph exit(1); 9416667Sralph } 9516667Sralph if (fread((char *)symtab, 1, n, f) != n) { 9616667Sralph fprintf(stderr, "symorder: Short file "); perror(argv[2]); 9716667Sralph exit(1); 9816667Sralph } 9916667Sralph if (fread((char *)&symsize, sizeof (int), 1, f) != 1 || 10016667Sralph symsize <= 0) { 10116667Sralph fprintf(stderr, "symorder: No strings "); perror(argv[2]); 10216667Sralph exit(1); 10316667Sralph } 10416667Sralph strings = malloc(symsize); 10516667Sralph if (strings == (char *)0) { 10616667Sralph fprintf(stderr,"symorder: Out of core, no space for strings\n"); 10716667Sralph exit(1); 10816667Sralph } 10916667Sralph if (fread(strings, 1, symsize, f) != symsize) { 11016667Sralph fprintf(stderr, "symorder: Truncated strings "); 11116667Sralph perror(argv[2]); 11216667Sralph exit(1); 11316667Sralph } 11416667Sralph 11516667Sralph newtab = (struct nlist *)malloc(n); 11616667Sralph if (newtab == (struct nlist *)0) { 11716667Sralph fprintf(stderr, 11816667Sralph "symorder: Out of core, no space for new symtab\n"); 11916667Sralph exit(1); 12016667Sralph } 12116667Sralph i = n / sizeof (struct nlist); 12216667Sralph reorder(symtab, newtab, i); 12316667Sralph free((char *)symtab); 12416667Sralph symtab = newtab; 12516667Sralph 12616667Sralph newstrings = malloc(symsize); 12716667Sralph if (newstrings == (char *)0) { 12816667Sralph fprintf(stderr, 12916667Sralph "symorder: Out of core, no space for newstrings\n"); 13016667Sralph exit(1); 13116667Sralph } 13216667Sralph ns = newstrings; 13316667Sralph for (symp = symtab; --i >= 0; symp++) { 13416667Sralph if (symp->n_un.n_strx == 0) 13516667Sralph continue; 13616667Sralph symp->n_un.n_strx -= sizeof (int); 13716667Sralph if ((unsigned)symp->n_un.n_strx >= symsize) { 13816667Sralph fprintf(stderr,"symorder: Corrupted string pointers\n"); 139623Sbill exit(1); 140623Sbill } 14116667Sralph strcpy(ns, &strings[symp->n_un.n_strx]); 14216667Sralph symp->n_un.n_strx = (ns - newstrings) + sizeof (int); 14316667Sralph ns = index(ns, 0) + 1; 14416667Sralph if (ns > &newstrings[symsize]) { 14516667Sralph fprintf(stderr, "symorder: Strings grew longer!\n"); 14616667Sralph exit(1); 147623Sbill } 148623Sbill } 14916667Sralph 15016667Sralph lseek(o, sa, 0); 15116667Sralph if (write(o, (char *)symtab, n) != n) { 15216667Sralph fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 15316667Sralph exit(1); 15416667Sralph } 15516667Sralph if (write(o, (char *)&symsize, sizeof (int)) != sizeof (int)) { 15616667Sralph fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 15716667Sralph exit(1); 15816667Sralph } 15916667Sralph if (write(o, newstrings, symsize) != symsize) { 16016667Sralph fprintf(stderr, "symorder: Write failed "); perror(argv[2]); 16116667Sralph exit(1); 16216667Sralph } 16316667Sralph if ((i = nsym - symfound) > 0) { 16416667Sralph fprintf(stderr, "symorder: %d symbol%s not found:\n", 16516667Sralph i, i == 1 ? "" : "s"); 166623Sbill for (i = 0; i < nsym; i++) { 167623Sbill if (order[i].n_value == 0) 168623Sbill printf("%s\n", order[i].n_un.n_name); 169623Sbill } 170623Sbill } 17116667Sralph exit(0); 172623Sbill } 173623Sbill 17416667Sralph reorder(st1, st2, n) 17516667Sralph register struct nlist *st1, *st2; 17616667Sralph register n; 17716667Sralph { 17816667Sralph register struct nlist *stp = st2 + nsym; 17916667Sralph register i; 18016667Sralph 18116667Sralph while (--n >= 0) { 18216667Sralph i = inlist(st1); 18316667Sralph if (i == -1) 18416667Sralph *stp++ = *st1++; 18516667Sralph else 18616667Sralph st2[i] = *st1++; 18716667Sralph } 18816667Sralph } 18916667Sralph 19016667Sralph inlist(p) 19116667Sralph register struct nlist *p; 19216667Sralph { 19316667Sralph register char *nam; 19416667Sralph register struct nlist *op; 19516667Sralph 19616667Sralph if (p->n_type & N_STAB) 19716667Sralph return (-1); 19816667Sralph if (p->n_un.n_strx == 0) 19916667Sralph return (-1); 20016667Sralph 20116667Sralph nam = &strings[p->n_un.n_strx - sizeof(int)]; 20216667Sralph if (nam >= &strings[symsize]) { 20316667Sralph fprintf(stderr, "symorder: corrupt symtab\n"); 20416667Sralph exit(1); 20516667Sralph } 20616667Sralph 20716667Sralph for (op = &order[nsym]; --op >= order; ) { 20816667Sralph if (strcmp(op->n_un.n_name, nam) != 0) 20916667Sralph continue; 21016667Sralph if (op->n_value == 0) { 21116667Sralph op->n_value++; 21216667Sralph symfound++; 21316667Sralph } 21416667Sralph return (op - order); 21516667Sralph } 21616667Sralph return (-1); 21716667Sralph } 21816667Sralph 219623Sbill #define NSAVETAB 4096 220623Sbill char *savetab; 221623Sbill int saveleft; 222623Sbill 223623Sbill char * 224623Sbill savestr(cp) 225623Sbill register char *cp; 226623Sbill { 227623Sbill register int len; 228623Sbill 229623Sbill len = strlen(cp) + 1; 230623Sbill if (len > saveleft) { 231623Sbill saveleft = NSAVETAB; 232623Sbill if (len > saveleft) 233623Sbill saveleft = len; 234623Sbill savetab = (char *)malloc(saveleft); 235623Sbill if (savetab == 0) { 236623Sbill fprintf(stderr, 237623Sbill "symorder: ran out of memory (savestr)\n"); 238623Sbill exit(1); 239623Sbill } 240623Sbill } 241623Sbill strncpy(savetab, cp, len); 242623Sbill cp = savetab; 243623Sbill savetab += len; 244623Sbill saveleft -= len; 245623Sbill return (cp); 246623Sbill } 247