/* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * Alternative ST symbol table lister. */ /* highly munged from above, VERY quick and dirty nm, just enough here to find _stksize for fixstk.c and printstk.c, may be useful for other stuff. WARNING: -g option will not work with gcc-ld produced a.out ++jrb */ /* * Modified to handle expanded, GST linker derived, format for symbols. * This format is produced with -G flag to a proper version of gcc-ld. * -g flag also will work if ld coached properly. * * --mj */ #ifdef atarist long _stksize = -1L; /* grab all memory you can get */ #endif #include #define A_LNAM 0x48 struct hdr { short magic; long tsize, dsize, bsize; long syms; long f1,f2; short f3; } h; struct sym { char name[8]; char flags; char xflags; long value; }; struct xsym { char name[8]; char flags; char xflags; long value; char tail[sizeof (struct sym)]; }; int gflag; int main(int argc, char **argv); int doopt(char *s); int cmp(struct xsym *s1, struct xsym *s2); void doname(char *s, int many); int dohdr(FILE *fd); void dosym(struct xsym *s); int not_glob(int x); void sflags(int x); main(argc, argv) char **argv; { int many; many = argc - 2; while (--argc) { argv++; if (*argv[0] == '-') many -= doopt(argv[0]); else doname(argv[0], many); } exit(0); } doopt(s) char *s; { while (*++s) switch (*s) { case 'g': gflag++; } return 1; /* return number of processed options */ } int cmp(s1, s2) struct xsym *s1, *s2; { return( s1->value - s2->value); } void doname(s, many) char *s; { FILE *fd, *fopen(); int i, count; fd = fopen(s, "r"); if (fd == NULL) { fprintf(stderr, "Can't open %s\n", s); return; } if (many) printf("\n%s:\n", s); if (i = dohdr(fd)) { register struct xsym *syms; register struct xsym *currsym; printf("%d slots mem %d\n", i, i*sizeof(struct sym)); if((syms = (struct xsym *)malloc(i*sizeof(struct xsym))) == NULL) { perror("Outa mem"); exit(1); } count = i; currsym = syms; while (count) { if(fread(currsym, sizeof(struct sym), 1, fd) != 1) { perror("reading syms"); exit(2); } if (--count) { if (A_LNAM == (currsym->xflags & A_LNAM)) { if(fread(&(currsym->tail), sizeof(struct sym), 1, fd) != 1) { perror("reading syms"); exit(2); } --i; --count; } } else /* object was partially stripped */ currsym->xflags &= ~A_LNAM; if (gflag && not_glob(currsym->flags)) --i; else currsym++; } fclose(fd); printf("%d %ssymbols\n", i, (gflag ? "global ": "")); qsort(syms, i, sizeof(struct xsym), cmp); while (i--) { dosym(syms); syms += 1; } free(syms); } } dohdr(fd) FILE *fd; { int i; long len; #if 0 fread(&h, 2, 1, fd); if (h.magic == ARMAG1) return -1; #endif i = fread((char *)&h , sizeof(h), 1, fd); if (i != 1 || h.magic != 0x601a) { printf("Bad header\n"); return 0; } len = h.tsize + h.dsize; fseek(fd, len, 1); return h.syms / sizeof(struct sym); } void dosym(s) struct xsym *s; { printf("%-8.8s", s->name); printf("%-14.14s", (A_LNAM == (s->xflags & A_LNAM) ? s->tail : "")); printf("\t%8lx ", s->value); sflags(s->flags); putchar('\n'); } #if 0 fill8(s) char *s; { int i; for (i=0; i<8; i++) if (s[i] == 0) putchar(' '); } #endif char *fname[] = { "?0?", " bss", " text", "?3?", " data", "?5?", "?6?", "?7?" }; char *Fname[] = { "?0?", "Bss", "Text", "?3?", "Data", "?5?", "?6?", "?7?" }; not_glob(x) { x &= 0xff; if (x & 0x20) return 0; x &= ~0x20; if (x == 0x88) return 0; return 1; } void sflags(x) { char **category; int lflag; if (0 != (lflag = not_glob(x))) category = fname; else category = Fname; x &= 0xff; if (x & 0xd8) { if (x & 0x08) printf (" external"); if (x & 0x50) { printf (" equ"); if (x & 0x10) printf (" reg"); } if (x & 0x08) printf (" abs"); if (!lflag) printf(" G"); } else { x &= 7; printf(category[x]); } }