johan@nlgvax.UUCP (Johan Stevenson) (11/28/88)
This message contains a shar wrapping of the following files: $ crc * 62288 5727 anm.c 11740 4481 aoutdump.c 38682 1564 asize.c 12750 3239 astrip.c These files are the sources for four new utilities, manipulating the ACK object format files. The utilities anm, asize and astrip are equivalents of the normal UNIX utilities nm, size and strip. The utility aoutdump prints the contents of ACK object files in a slightly more structured way than od(1). Go to an empty directory, feed the lines following the cut mark to the shell, check the table above with the output of /usr/bin/crc and install as follows: $ cp * /usr/src/commands $ cd /usr/src/commands $ cc -O -DATARI_ST anm.c -o anm $ cp anm /usr/bin/anm $ cc -O -DATARI_ST aoutdump.c -o aoutdump $ cp aoutdump /usr/bin/aoutdump $ cc -O -DATARI_ST asize.c -o asize $ cp asize /usr/bin/asize $ cc -O -DATARI_ST astrip.c -o astrip $ cp astrip /usr/bin/astrip The resulting binaries have the following checksums: 21993 8588 anm 57602 5103 asize 56121 7273 astrip 17299 8299 aoutdump Good luck. -- Johan W. Stevenson johan@pcg.philips.nl Philips Research ------------------------------------------------------------------------ : This is a shar archive. Extract with sh, not csh. : This archive ends with exit, so do not worry about trailing junk. echo 'Extracting anm.c' sed 's/^X//' > anm.c << '+ END-OF-FILE anm.c' X/* @(#)anm.c 1.6 */ X/* X** print symbol tables for X** ACK object files X** X** anm [-gopruns] [name ...] X*/ X#define ushort unsigned short X X#include "out.h" X X#include <stdio.h> X#include <ctype.h> X Xint numsort_flg; Xint sectsort_flg; Xint undef_flg; Xint revsort_flg = 1; Xint globl_flg; Xint nosort_flg; Xint arch_flg; Xint prep_flg; Xstruct outhead hbuf; Xstruct outsect sbuf; XFILE *fi; Xlong off; Xchar *malloc(); Xchar *realloc(); Xlong s_base[S_MAX]; /* for specially encoded bases */ X Xmain(argc, argv) Xchar **argv; X{ X int narg; X int compare(); X X if (--argc>0 && argv[1][0]=='-' && argv[1][1]!=0) { X argv++; X while (*++*argv) switch (**argv) { X case 'n': /* sort numerically */ X numsort_flg++; X continue; X X case 's': /* sort in section order */ X sectsort_flg++; X continue; X X case 'g': /* globl symbols only */ X globl_flg++; X continue; X X case 'u': /* undefined symbols only */ X undef_flg++; X continue; X X case 'r': /* sort in reverse order */ X revsort_flg = -1; X continue; X X case 'p': /* don't sort -- symbol table order */ X nosort_flg++; X continue; X X case 'o': /* prepend a name to each line */ X prep_flg++; X continue; X X default: /* oops */ X fprintf(stderr, "anm: invalid argument -%c\n", *argv[0]); X exit(1); X } X argc--; X } X if (argc == 0) { X argc = 1; X argv[1] = "a.out"; X } X narg = argc; X X while(argc--) { X struct outname *nbufp = NULL; X struct outname nbuf; X char *cbufp; X long fi_to_co; X long n; X unsigned readcount; X int i,j; X X fi = fopen(*++argv,"r"); X if (fi == NULL) { X fprintf(stderr, "anm: cannot open %s\n", *argv); X continue; X } X X getofmt((char *)&hbuf, SF_HEAD, fi); X if (BADMAGIC(hbuf)) { X fprintf(stderr, "anm: %s-- bad format\n", *argv); X fclose(fi); X continue; X } X if (narg > 1) X printf("\n%s:\n", *argv); X X n = hbuf.oh_nname; X if (n == 0) { X fprintf(stderr, "anm: %s-- no name list\n", *argv); X fclose(fi); X continue; X } X X if (hbuf.oh_nchar == 0) { X fprintf(stderr, "anm: %s-- no names\n", *argv); X fclose(fi); X continue; X } X if ((readcount = hbuf.oh_nchar) != hbuf.oh_nchar) { X fprintf(stderr, "anm: string area too big in %s\n", *argv); X exit(2); X } X X /* store special section bases */ X if (hbuf.oh_flags & HF_8086) { X for (i=0; i<hbuf.oh_nsect; i++) { X getofmt((char *)&sbuf, SF_SECT, fi); X s_base[i+S_MIN] = X (sbuf.os_base>>12) & 03777760; X } X } X X if ((cbufp = (char *)malloc(readcount)) == NULL) { X fprintf(stderr, "anm: out of memory on %s\n", *argv); X exit(2); X } X fseek(fi, OFF_CHAR(hbuf), 0); X if (fread(cbufp, 1, readcount, fi) == 0) { X fprintf(stderr, "anm: read error on %s\n", *argv); X exit(2); X } X fi_to_co = (long)cbufp - OFF_CHAR(hbuf); X X fseek(fi, OFF_NAME(hbuf), 0); X i = 0; X while (--n >= 0) { X getofmt((char *)&nbuf, SF_NAME, fi); X X if (nbuf.on_foff == 0) X continue; /* skip entries without names */ X X if (globl_flg && (nbuf.on_type&S_EXT)==0) X continue; X X if (undef_flg X && X ((nbuf.on_type&S_TYP)!=S_UND || (nbuf.on_type&S_ETC)!=0)) X continue; X X nbuf.on_mptr = (char *)(nbuf.on_foff + fi_to_co); X X /* adjust value for specially encoded bases */ X if (hbuf.oh_flags & HF_8086) { X if (((nbuf.on_type&S_ETC) == 0) || X ((nbuf.on_type&S_ETC) == S_SCT)) { X j = nbuf.on_type&S_TYP; X if ((j>=S_MIN) && (j<=S_MAX)) X nbuf.on_valu += s_base[j]; X } X } X X if (nbufp == NULL) X nbufp = (struct outname *)malloc(sizeof(struct outname)); X else X nbufp = (struct outname *)realloc(nbufp, (i+1)*sizeof(struct outname)); X if (nbufp == NULL) { X fprintf(stderr, "anm: out of memory on %s\n", *argv); X exit(2); X } X nbufp[i++] = nbuf; X } X X if (nosort_flg==0) X qsort(nbufp, i, sizeof(struct outname), compare); X X for (n=0; n<i; n++) { X char cs1[4]; X char cs2[4]; X X if (prep_flg) X printf("%s:", *argv); X X switch(nbufp[n].on_type&S_ETC) { X case S_SCT: X sprintf(cs1, "%2d", (nbufp[n].on_type&S_TYP) - S_MIN); X sprintf(cs2, " S"); X break; X case S_FIL: X sprintf(cs1, " -"); X sprintf(cs2, " F"); X break; X case S_MOD: X sprintf(cs1, " -"); X sprintf(cs2, " M"); X break; X case 0: X if (nbufp[n].on_type&S_EXT) X sprintf(cs2, " E"); X else X sprintf(cs2, " -"); X X switch(nbufp[n].on_type&S_TYP) { X case S_UND: X sprintf(cs1, " U"); X break; X case S_ABS: X sprintf(cs1, " A"); X break; X default: X sprintf(cs1, "%2d", (nbufp[n].on_type&S_TYP) - S_MIN); X } X break; X default: X continue; X } X X printf("%8lx %s %s %s\n",nbufp[n].on_valu,cs1,cs2,nbufp[n].on_mptr); X } X X if (nbufp) X free((char *)nbufp); X if (cbufp) X free((char *)cbufp); X fclose(fi); X } X exit(0); X} X Xcompare(p1, p2) Xstruct outname *p1, *p2; X{ X int i; X X if (sectsort_flg) { X if ((p1->on_type&S_TYP) > (p2->on_type&S_TYP)) X return(revsort_flg); X if ((p1->on_type&S_TYP) < (p2->on_type&S_TYP)) X return(-revsort_flg); X } X X if (numsort_flg) { X if (p1->on_valu > p2->on_valu) X return(revsort_flg); X if (p1->on_valu < p2->on_valu) X return(-revsort_flg); X } X X i = strcmp(p1->on_mptr, p2->on_mptr); X X if (i > 0) X return(revsort_flg); X if (i < 0) X return(-revsort_flg); X X return(0); X} X Xgetofmt(p, s, f) Xregister char *p; Xregister char *s; Xregister FILE *f; X{ X register i; X register long l; X X for (;;) { X switch (*s++) { X/* case '0': p++; continue; */ X case '1': X *p++ = getc(f); X continue; X case '2': X i = getc(f); X i |= (getc(f) << 8); X *((short *)p) = i; p += sizeof(short); X continue; X case '4': X l = (long)getc(f); X l |= ((long)getc(f) << 8); X l |= ((long)getc(f) << 16); X l |= ((long)getc(f) << 24); X *((long *)p) = l; p += sizeof(long); X continue; X default: X case '\0': X break; X } X break; X } X} + END-OF-FILE anm.c chmod 644 anm.c echo 'CRC SENT: 62288 5727 anm.c' echo -n 'CRC RCVD: ' crc anm.c echo 'Extracting aoutdump.c' sed 's/^X//' > aoutdump.c << '+ END-OF-FILE aoutdump.c' X/* @(#)aoutdump.c 1.1 */ X#define ushort unsigned short X X#include <stdio.h> X#include "out.h" X Xstruct outhead outhead; Xstruct outsect outsect[S_MAX - S_MIN + 1]; Xstruct outrelo outrelo; Xstruct outname outname; X Xchar options[] = "111111"; Xchar *progname; X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X register char *filename = "a.out"; X X progname = argv[0]; X if (argc > 3) X error('f',"Usage: %s [filename [111111]]", progname); X if (argc > 1) X filename = argv[1]; X if (freopen(filename, "r", stdin) == NULL) X error('f',"Couldn't open %s for input",filename); X if (argc > 2) X strncpy(options,argv[2],6); X p_head(0); X p_sect(1); X p_fill(2); X p_relo(3); X p_name(4); X p_char(5); X} X Xp_head(part) X{ X getofmt((char *)&outhead, SF_HEAD, stdin); X if (options[part] != '1') X return; X printf("header:"); X printf("\toh_magic: 0x%04x\n", outhead.oh_magic); X printf("\toh_stamp: %d\n", outhead.oh_stamp); X printf("\toh_flags: 0x%04x\n", outhead.oh_flags); X printf("\toh_nsect: %d\n", outhead.oh_nsect); X printf("\toh_nrelo: %d\n", outhead.oh_nrelo); X printf("\toh_nname: %d\n", outhead.oh_nname); X printf("\toh_nemit: %ld\n", outhead.oh_nemit); X printf("\toh_nchar: %ld\n", outhead.oh_nchar); X} X Xp_sect(part) X{ X register struct outsect *sp; X register i = 0; X X for (sp = outsect; sp < &outsect[outhead.oh_nsect]; sp++,i++) { X getofmt((char *)sp, SF_SECT, stdin); X if (options[part] != '1') X continue; X printf("\nsection %d header:\n", i); X printf("\tos_base: 0x%lx\n", sp->os_base); X printf("\tos_size: %ld\n", sp->os_size); X printf("\tos_foff: %ld\n", sp->os_foff); X printf("\tos_flen: %ld\n", sp->os_flen); X printf("\tos_lign: %ld\n", sp->os_lign); X } X} X Xp_fill(part) X{ X register struct outsect *sp; X register i = 0; X register c; X register long l; X X for (sp = outsect; sp < &outsect[outhead.oh_nsect]; sp++,i++) { X if (ftell(stdin) != sp->os_foff) X error( X 'f', X "sp->os_foff (%ld) != ftell() (%ld)", X sp->os_foff, X ftell(stdin) X ); X if (options[part] != '1') { X fseek(stdin, sp->os_flen, 1); X return; X } X printf("\nsection %d filler:\n", i); X for (l = 0; l < sp->os_flen; l++) { X if ((l & 15) == 0) X printf("%06lx: ", l); X if ((c = getc(stdin)) == EOF) X error('f', "EOF"); X printf(" %02x", c & 0xFF); X if ((l & 15) == 15) X printf("\n"); X } X if ((l & 15) != 0) X printf("\n"); X } X} X Xp_relo(part) X{ X register i = 0; X X if (options[part] == '1') X printf("\nrelocation:\n"); X for (i = 0; i < outhead.oh_nrelo; i++) { X getofmt((char *)&outrelo, SF_RELO, stdin); X if (options[part] != '1') X return; X printf("%4d: t=%02x s=%02x i=%-5d a=%06lx\n", X i, X outrelo.or_type, X outrelo.or_sect, X outrelo.or_nami, X outrelo.or_addr X ); X } X} X Xp_name(part) X{ X register i = 0; X X if (options[part] == '1') X printf("\nsymbols:\n"); X for (i = 0; i < outhead.oh_nname; i++) { X getofmt((char *)&outname, SF_NAME, stdin); X if (options[part] != '1') X continue; X printf("%4d: o=%-6ld t=%04x d=%04x v=%ld\n", X i, X outname.on_foff, X outname.on_type, X outname.on_desc, X outname.on_valu X ); X } X} X Xp_char(part) X{ X register long off; X register i = 0; X register c = 0; X X off = ftell(stdin); X if (off != OFF_CHAR(outhead)) X error( X 'f', X "char off (%ld) != ftell() (%ld)", X OFF_CHAR(outhead), X off X ); X if (options[part] != '1') X return; X printf("\nstrings:\n"); X for (i = 0; i < outhead.oh_nchar; i++,off++) { X if (c == 0) X printf("%ld:\t", off); X c = getc(stdin); X if (c == EOF) X error('f', "EOF"); X if (c >= ' ' && c < 0177) X putchar(c); X else if (c == 0) X putchar('\n'); X else X printf("\\%03o", c); X } X} X X/* VARARGS2 */ Xerror(t,s,a,b,c,d,e,f,g,h,i,j) Xchar t; Xchar *s; X{ X fprintf(stderr,"%s: ",progname); X fprintf(stderr,s,a,b,c,d,e,f,g,h,i,j); X fprintf(stderr,"\n"); X switch (t) { X case 'w': X return; X case 'f': X exit(1); X case 'a': X abort(); X default: X error('w',"Illegal error type: '%c'",t); X } X} X Xgetofmt(p, s, f) Xregister char *p; Xregister char *s; Xregister FILE *f; X{ X register i; X register long l; X X while (i = *s++) { X switch (i) { X/* case '0': p++; break; */ X case '1': X *p++ = getc(f); X break; X case '2': X i = getc(f); X i |= (getc(f) << 8); X *((short *)p) = i; p += sizeof(short); X break; X case '4': X l = (long)getc(f); X l |= (long)(getc(f) << 8); X l |= ((long)getc(f) << 16); X l |= ((long)getc(f) << 24); X *((long *)p) = l; p += sizeof(long); X break; X default: X error('f', "bad getofmt string"); X } X } X if (feof(f) || ferror(f)) X error('f', "read error"); X} + END-OF-FILE aoutdump.c chmod 644 aoutdump.c echo 'CRC SENT: 11740 4481 aoutdump.c' echo -n 'CRC RCVD: ' crc aoutdump.c echo 'Extracting asize.c' sed 's/^X//' > asize.c << '+ END-OF-FILE asize.c' X/* @(#)asize.c 1.4 */ X#define ushort unsigned short X X#include <stdio.h> X#include "out.h" X X/* X asize -- determine object size X X*/ X Xmain(argc, argv) Xchar **argv; X{ X struct outhead buf; X struct outsect sbuf; X ushort nrsect; X long sum; X int gorp; X FILE *f; X X if (--argc == 0) { X argc = 1; X argv[1] = "a.out"; X } X gorp = argc; X X while(argc--) { X if ((f = fopen(*++argv, "r"))==NULL) { X fprintf(stderr, "asize: cannot open %s\n", *argv); X continue; X } X getofmt ((char *)&buf, SF_HEAD , f); X if(BADMAGIC(buf)) { X fprintf(stderr, "asize: %s-- bad format\n", *argv); X fclose(f); X continue; X } X nrsect = buf.oh_nsect; X if (nrsect == 0) { X fprintf(stderr, "asize: %s-- no sections\n", *argv); X fclose(f); X continue; X } X if (gorp > 1) X printf("%s: ", *argv); X X sum = 0; X while (nrsect-- > 0) { X getofmt ((char *)&sbuf, SF_SECT , f); X printf("%ld", sbuf.os_size); X sum += sbuf.os_size; X if (nrsect > 0) X putchar('+'); X } X printf(" = %ld = 0x%lx\n", sum, sum); X fclose(f); X } X} X Xgetofmt(p, s, f) Xregister char *p; Xregister char *s; Xregister FILE *f; X{ X register i; X register long l; X X for (;;) { X switch (*s++) { X/* case '0': p++; continue; */ X case '1': X *p++ = getc(f); X continue; X case '2': X i = getc(f); X i |= (getc(f) << 8); X *((short *)p) = i; p += sizeof(short); X continue; X case '4': X l = (long)getc(f); X l |= ((long)getc(f) << 8); X l |= ((long)getc(f) << 16); X l |= ((long)getc(f) << 24); X *((long *)p) = l; p += sizeof(long); X continue; X default: X case '\0': X break; X } X break; X } X} + END-OF-FILE asize.c chmod 644 asize.c echo 'CRC SENT: 38682 1564 asize.c' echo -n 'CRC RCVD: ' crc asize.c echo 'Extracting astrip.c' sed 's/^X//' > astrip.c << '+ END-OF-FILE astrip.c' X/* @(#)astrip.c 1.4 */ X#define ushort unsigned short X X#include "out.h" X#include <signal.h> X#include <stdio.h> X X/* X X astrip -- remove symbols and relocation bits X X*/ X Xchar *tname; Xchar *mktemp(); XFILE *fopen(); XFILE *tf; Xstruct outhead buf; X Xmain(argc, argv) Xchar **argv; X{ X int status; X X signal(SIGHUP, SIG_IGN); X signal(SIGINT, SIG_IGN); X signal(SIGQUIT, SIG_IGN); X tname = mktemp("/tmp/sXXXXX"); X while(--argc) { X if ((status = strip(argv[argc])) > 1) X break; X } X unlink(tname); X exit(status); X} X Xstrip(name) Xchar *name; X{ X long size; X FILE *f; X X if ((f = fopen(name,"r")) == NULL) { X fprintf(stderr, "astrip: cannot open %s\n", name); X return(1); X } X getofmt ((char *)&buf, SF_HEAD , f); X if(BADMAGIC(buf)) { X fprintf(stderr, "astrip: %s-- bad format\n", name); X fclose(f); X return(1); X } X size = OFF_RELO(buf) - SZ_HEAD; X buf.oh_flags &= ~HF_LINK; X buf.oh_nrelo = 0; X buf.oh_nname = 0; X buf.oh_nchar = 0; X X X if ((tf = fopen(tname,"w")) == NULL) { X fprintf(stderr, "astrip: cannot create temp file %s\n", tname); X fclose(f); X return(2); X } X fseek(tf, (long)0, 0); X putofmt((char *)&buf,SF_HEAD,tf,tname); X if(copy(name, tname, f, tf, size)) { X fclose(f); X fclose(tf); X return(1); X } X fclose(f); X fclose(tf); X size += SZ_HEAD; X if ((f = fopen(name,"w")) == NULL) { X fprintf(stderr, "astrip: cannot write %s\n", name); X return(1); X } X if ((tf = fopen(tname,"r")) == NULL) { X fprintf(stderr, "astrip: cannot read temp file %s\n", tname); X fclose(f); X return(2); X } X fseek(tf, (long)0, 0); X if(copy(tname, name, tf, f, size)) { X fclose(f); X fclose(tf); X return(2); X } X X fclose(f); X fclose(tf); X return(0); X} X Xcopy(fnam, tnam, fr, to, size) Xchar *fnam; Xchar *tnam; Xlong size; XFILE *fr,*to; X{ X register s, n; X char lbuf[512]; X X while(size != (long)0) { X s = 512; X if(size < 512) X s = (int) size; X n = fread(lbuf,1,s,fr); X if(n != s) { X fprintf(stderr, "astrip: unexpected eof on %s\n", fnam); X return(1); X } X n = fwrite(lbuf,1,s,to); X if(n != s) { X fprintf(stderr, "astrip: write error on %s\n", tnam); X return(1); X } X size -= (long)s; X } X return(0); X} X Xgetofmt(p, s, f) Xregister char *p; Xregister char *s; Xregister FILE *f; X{ X register i; X register long l; X X for (;;) { X switch (*s++) { X/* case '0': p++; continue; */ X case '1': X *p++ = getc(f); X continue; X case '2': X i = getc(f); X i |= (getc(f) << 8); X *((short *)p) = i; p += sizeof(short); X continue; X case '4': X l = (long)getc(f); X l |= ((long)getc(f) << 8); X l |= ((long)getc(f) << 16); X l |= ((long)getc(f) << 24); X *((long *)p) = l; p += sizeof(long); X continue; X default: X case '\0': X break; X } X break; X } X} X Xputofmt(p, s, f, fnam) Xregister char *p; Xregister char *s; Xregister FILE *f; Xchar *fnam; X{ X register i,j; X register long l; X X while (j = *s++) { X switch (j -= '0') { X/* case 0: p++; break; */ X case 1: X i = *p++; putc(i,f); X break; X case 2: X i = *((short *)p); p += sizeof(short); X putc(i,f); X i>>=8; putc(i,f); X break; X case 4: X l = *((long *)p); p += sizeof(long); X putc((int)l,f); X l >>=8; putc((int)l,f); X l >>=8; putc((int)l,f); X l >>=8; putc((int)l,f); X break; X default: X break; X } X if (ferror(f)) fprintf(stderr, "astrip: write error on %s\n", fnam); X } X} + END-OF-FILE astrip.c chmod 644 astrip.c echo 'CRC SENT: 12750 3239 astrip.c' echo -n 'CRC RCVD: ' crc astrip.c exit 0