alex@umbc3.UUCP (Alex S. Crain) (10/15/88)
Posting-number: Volume 4, Issue 125 Submitted-by: "Alex S. Crain" <alex@umbc3.UUCP> Archive-name: 68kdisasm/Part1 This is a dissassembler for 68K COFF machines, based on the unc program that went out over the net awhile back. It works really well, and alot of people have shown an interest. #!/bin/sh # shar: Shell Archiver (v1.22) # # Run the following text with /bin/sh to create: # iset.c # libmtch.c # robj.c # sed 's/^X//' << 'SHAR_EOF' > iset.c && X/* X * SCCS: @(#)iset.c 1.2 11/2/84 14:18:23 X * Decode instructions. X * X *********************************************************************** X * This software is copyright of X * X * John M Collins X * 47 Cedarwood Drive X * St Albans X * Herts, AL4 0DN X * England +44 727 57267 X * X * and is released into the public domain on the following conditions: X * X * 1. No free maintenance will be guaranteed. X * 2. Nothing may be based on this software without X * acknowledgement, including incorporation of this X * notice. X * X * Notwithstanding the above, the author welcomes correspondence and bug X * fixes. X *********************************************************************** X */ X X#include <stdio.h> X#include <a.out.h> X#include <ldfcn.h> X#include "unc.h" X Xef_fids mainfile; Xlong endt; X Xvoid gette(), putte(); Xvoid mkdref(); Xlong gettw(); Xsymbol textlab(); X Xint l1(), l2(), el1(), lea(), lmove(), lcbch(), jj(); Xint limed(), lsbit(), lmvml(), lone(), loone(), lonew(), lonel(); X Xint pmove(), pcbch(), pdbcc(), pscc(), pcs(), pmovc(), pstop(), pexg(); Xint pimed(), pmovp(), psbit(), pdbit(), pcs2(), pone(), ppea(); Xint plea(), pdreg(), pmvml(), ptrap(), plink(), pareg(), podreg(); Xint pqu(), pmqu(), ptreg(), pcmpm(), pomode(), pmshf(), pshf(); X Xstruct opstr { X unsigned short mask; X unsigned short match; X int (*opsize)(); X int (*opprin)(); X char *prarg; X} optab[] = { X 0xf000, 0x2000, lmove, pmove, ".l", X 0xf000, 0x3000, lmove, pmove, ".w", X 0xf000, 0x1000, lmove, pmove, ".b", X 0xf000, 0x6000, lcbch, pcbch, 0, X 0xffbf, 0x003c, l2, pcs, "or", X 0xff00, 0x0000, limed, pimed, "or", X 0xffbf, 0x023c, l2, pcs, "and", X 0xff00, 0x0200, limed, pimed, "and", X 0xff00, 0x0400, limed, pimed, "sub", X 0xff00, 0x0600, limed, pimed, "add", X 0xffbf, 0x0a3c, l2, pcs, "eor", X 0xff00, 0x0a00, limed, pimed, "eor", X 0xff00, 0x0c00, limed, pimed, "cmp", X 0xf138, 0x0108, l2, pmovp, 0, X 0xff00, 0x0800, lsbit, psbit, 0, X 0xf100, 0x0100, lonew, pdbit, 0, X 0xffc0, 0x40c0, lonew, pcs2, "sr", X 0xff00, 0x4000, lone, pone, "negx", X 0xff00, 0x4200, lone, pone, "clr", X 0xffc0, 0x44c0, lonew, pcs2, "cc", X 0xff00, 0x4400, lone, pone, "neg", X 0xffc0, 0x46c0, lonew, pcs2, "sr", X 0xff00, 0x4600, lone, pone, "not", X 0xffc0, 0x4800, lonew, ppea, "nbcd", X 0xfff8, 0x4840, l1, pdreg, "swap.w", X 0xffc0, 0x4840, lonel, ppea, "pea", X 0xfff8, 0x4880, l1, pdreg, "ext.w", X 0xfff8, 0x48c0, l1, pdreg, "ext.l", X 0xfb80, 0x4880, lmvml, pmvml, 0, X 0xffc0, 0x4ac0, lonew, ppea, "tas", X 0xff00, 0x4a00, lone, pone, "tst", X 0xfff0, 0x4e40, l1, ptrap, 0, X 0xfff8, 0x4e50, l2, plink, 0, X 0xfff8, 0x4e58, l1, pareg, "unlk\t%s", X 0xfff8, 0x4e60, l1, pareg, "mov.l\t%s,%%usp", X 0xfff8, 0x4e68, l1, pareg, "mov.l\t%%usp,%s", X 0xffff, 0x4e70, l1, pareg, "reset", X 0xffff, 0x4e71, l1, pareg, "nop", X 0xffff, 0x4e72, l2, pstop, 0, X 0xffff, 0x4e73, el1, pareg, "rte", X 0xffff, 0x4e75, el1, pareg, "rts", X 0xffff, 0x4e76, l1, pareg, "trapv", X 0xffff, 0x4e77, el1, pareg, "rtr", X 0xfffe, 0x4e7a, l2, pmovc, 0, X 0xffc0, 0x4e80, jj, ppea, "jsr", X 0xffc0, 0x4ec0, jj, ppea, "jmp", X 0xf1c0, 0x4180, lonew, podreg,"chk", X 0xf1c0, 0x41c0, lonel, plea, 0, X 0xf0f8, 0x50c8, lcbch, pdbcc, 0, X 0xf0c0, 0x50c0, lonew, pscc, 0, X 0xf100, 0x5000, lone, pqu, "add", X 0xf100, 0x5100, lone, pqu, "sub", X 0xf100, 0x7000, l1, pmqu, 0, X 0xf1c0, 0x80c0, lonew, podreg,"divu", X 0xf1c0, 0x81c0, lonew, podreg,"divs", X 0xf1f0, 0x8100, l1, ptreg, "sbcd", X 0xf000, 0x8000, loone, pomode,"or", X 0xf1f0, 0x9100, l1, ptreg, "subx.b", X 0xf1f0, 0x9140, l1, ptreg, "subx.w", X 0xf1f0, 0x9180, l1, ptreg, "subx.l", X 0xf000, 0x9000, loone, pomode,"sub", X 0xf1f8, 0xb108, l1, pcmpm, "cmp.b", /* CMPM */ X 0xf1f8, 0xb148, l1, pcmpm, "cmp.w", /* CMPM */ X 0xf1f8, 0xb188, l1, pcmpm, "cmp.l", /* CMPM */ X 0xf100, 0xb000, loone, pomode,"cmp", X 0xf1c0, 0xb1c0, loone, pomode,"cmp", X 0xf100, 0xb100, loone, pomode,"eor", X 0xf1c0, 0xc0c0, lonew, podreg,"mulu", X 0xf1c0, 0xc1c0, lonew, podreg,"muls", X 0xf1f0, 0xc100, l1, ptreg, "abcd", X 0xf130, 0xc100, l1, pexg, 0, X 0xf000, 0xc000, loone, pomode,"and", X 0xf1f0, 0xd100, l1, ptreg, "addx.b", X 0xf1f0, 0xd140, l1, ptreg, "addx.w", X 0xf1f0, 0xd180, l1, ptreg, "addx.l", X 0xf000, 0xd000, loone, pomode,"add", X 0xf8c0, 0xe0c0, lonew, pmshf, 0, X 0xf000, 0xe000, l1, pshf, 0, X 0 X}; X Xchar *areg[] = { "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp"}; Xchar *cclist[] = { "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs", X "pl", "mi", "ge", "lt", "gt", "le"}; X Xchar *shtype[] = { "as", "ls", "rox", "ro" }; Xchar *bittyp[] = { "tst", "chg", "clr", "set" }; X Xchar *creg[] = { "%sfc", "%dfc", "%usp", "%vbr" }; X Xint swbegflg = 0; X X/* X * Length functions. X */ X Xint l1() X{ X return 1; X} X Xint l2() X{ X return 2; X} X Xint el1(te) Xt_entry *te; X{ X te->t_bchtyp = T_UNBR; X return 1; X} X Xint lea(instr, size, pos) Xunsigned instr, size; Xlong pos; X{ X switch ((instr >> 3) & 0x7) { X case 0: X case 1: X case 2: X case 3: X case 4: X return 1; X case 5: X case 6: X return 2; X default: X switch (instr & 0x7) { X case 0: X case 2: X case 3: X return 2; X case 1: X mkdref(pos, size); X return 3; X case 4: X if (size > 2) X return 3; X return 2; X default: X return 0; X } X } X} X X/* X * Lengths of move instructions. X */ X Xint lmove(te, pos) Xt_entry *te; Xlong pos; X{ X register unsigned tc = te->t_contents; X unsigned sz = 1; X int lng, lng2; X X lng = tc & 0xf000; X if (lng == 0x3000) X sz = 2; X else if (lng == 0x2000) X sz = 4; X X if ((lng = lea(tc, sz, pos+2)) <= 0) X return 0; X lng2 = lea(((tc>>3) & 0x38) | ((tc>>9) & 0x7), sz, pos+lng+lng); X if (lng2 <= 0) X return 0; X return lng + lng2 - 1; X} X X/* X * Lengths for conditional branches and dbcc instructions. X */ X Xint lcbch(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X long dest = pos + 2; X int res = 2; X X if ((tc & 0xf000) == 0x5000 || (tc & 0xff) == 0) X dest += (short)gettw(&mainfile, pos+2, R_WORD); X else { X dest += (char) tc; X res = 1; X } X if ( dest < 0x290000 && (dest < mainfile.ef_tbase X || dest >= mainfile.ef_tbase+mainfile.ef_tsize X || (dest & 1) != 0 )) X return 0; /* Illegal branch destination */ X if ((tc & 0xff00) == 0x6000) X te->t_bchtyp = T_UNBR; X else if ((tc & 0xff00) == 0x6100) X te->t_bchtyp = T_JSR; X else X te->t_bchtyp = T_CONDBR; X X if ( dest < 0x290000 && ((te->t_relsymb = textlab(dest, pos)) == NULL )) { X te->t_bchtyp = T_NOBR;/* Branch to a continuation */ X return 0; X } X return res; X} X Xint jj(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X t_entry nextl; X long dest; X X te->t_bchtyp = (tc & 0x40)? T_UNBR: T_JSR; X if ((tc & 0x3f) == 0x39) { X gette(&mainfile, pos+2, &nextl); X if (nextl.t_relsymb == NULL) { X dest = gettw(&mainfile, pos + 2, R_LONG ); X if ( dest < 0x290000 && (dest < mainfile.ef_tbase X || dest >= mainfile.ef_tbase+mainfile.ef_tsize X || (dest & 1) != 0 )) X return 0; /* Illegal branch destination */ X if ( dest < 0x290000 && ( nextl.t_relsymb = textlab(dest, pos) ) == NULL ) X return 0; /* Branch to a continuation */ X putte(&mainfile, pos+2, &nextl); X } X te->t_relsymb = nextl.t_relsymb; /* Easy ref */ X } X else if ((tc & 0x3f) == 0x3a) { X gette(&mainfile, pos+2, &nextl); X if (nextl.t_relsymb == NULL) { X dest = pos+2+ (int)((short) X gettw(&mainfile, pos + 2, R_WORD )); X if ( dest < 0x290000 && (dest < mainfile.ef_tbase X || dest >= mainfile.ef_tbase+mainfile.ef_tsize X || (dest & 1) != 0 )) X return lea(tc, 4, pos+2); X if (dest < 0x290000 && X (nextl.t_relsymb = textlab(dest, pos)) == NULL) X return 0; /* Branch to a continuation */ X putte(&mainfile, pos+2, &nextl); X } X te->t_relsymb = nextl.t_relsymb; /* Easy ref */ X } X return lea(tc, 4, pos+2); X} X Xint limed(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X int lng; X X /* X * Specifically exclude byte address register operands, X * and ones which have lengths of 3. X */ X X if ((tc & 0xf8) == 0x08) X return 0; X X if ((tc & 0xc0) >= 0x80) { X if (tc & 0x40) X return 0; X lng = lea(tc, 4, pos+6); X if (lng > 0) X lng += 2; X } X else { X lng = lea(tc, (unsigned)((tc & 0xc0)?2:1), pos+4); X if (lng > 0) X lng++; X } X return lng; X} X Xint lsbit(te, pos) Xt_entry *te; Xlong pos; X{ X int lng = lea(te->t_contents, 1, pos+4); X X if (lng > 0) X lng++; X return lng; X} X Xint lmvml(te, pos) Xt_entry *te; Xlong pos; X{ X int lng = lea(te->t_contents, X (unsigned)(te->t_contents&0x40? 4:2), pos+4); X X if (lng > 0) X lng++; X return lng; X} X X/* X * Length depends on bits 6 and 7 of instruction. X */ X Xint lone(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X X return lea(tc, 1 << ((tc >> 6) & 3), pos+2); X} X X/* X * Length depends on bits 6-8 of instruction. X */ X Xint loone(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X X switch ((tc >> 6) & 7) { X case 0: X case 4: X return lea(tc, 1, pos+2); X case 1: X case 3: X case 5: X return lea(tc, 2, pos+2); X case 2: X case 6: X case 7: X return lea(tc, 4, pos+2); X } X /*NOTREACHED*/ X} X Xint lonew(te, pos) Xt_entry *te; Xlong pos; X{ X if (te->t_contents == 0x4afc) { /* swbeg ... */ X swbegflg++; X return (2 + gettw(&mainfile,pos+2,2)); X } X return lea(te->t_contents, 2, pos+2); X} X Xint lonel(te, pos) Xt_entry *te; Xlong pos; X{ X return lea(te->t_contents, 4, pos+2); X} X X/* X * Print routines. X */ X X/* X * print out small integers in decamil notation, all others in hex. X */ X Xvoid prind(n) Xunsigned short n; X{ X if ((short) n > -128 && (short) n < 128) X (void) printf("%d", (long) ((short) n)); X else X (void) printf("0x%x",(unsigned long) n); X} X Xint findleng(tc) Xunsigned tc; X{ X switch ((tc >> 6) & 3) { X case 0: X return 'b'; X case 1: X return 'w'; X default: X return 'l'; X} X} X X/* print @(0x4,d0.l) */ Xvoid piword(reg,disp) Xchar * reg; Xunsigned disp; X{ Xint szc; X X (void) printf("%d(%s,", disp & 0xff, reg); X if (disp & 0x8000) { X (void) fputs(areg[(disp >> 12) & 0x7]); X (void) putchar('.'); X } X else X (void) printf("%%d%d.", (disp >> 12) & 0x7); X (void) putchar((disp & (1 << 10)) ? 'l' :'w'); X (void) putchar(')'); X} X Xextern struct commit abstab; X Xvoid paddr(pos) Xlong pos; X{ X t_entry tent; X symbol symb; X X gette(&mainfile, pos, &tent); X if (tent.t_relsymb != NULL) { X symb = tent.t_relsymb; X if (symb->s_lsymb != 0) X (void) printf("L%%%u", symb->s_lsymb); X else X (void) fputs(symb->s_name, stdout); X if (tent.t_reldisp != 0) X (void) printf("+0x%x", tent.t_reldisp); X return; X } X if ((pos = gettw(&mainfile, pos, R_LONG)) >= 0x290000) X { X register int i; X for (i=0; i < abstab.c_int; i++) X if (abstab.c_symb[i]->s_value == pos) X { X (void) fputs(abstab.c_symb[i]->s_name, stdout); X return; X } X } X (void) printf("0x%x", pos); X} X Xint prea(ea, pos, sz) Xunsigned ea, sz; Xlong pos; /* Address of previous word to extn */ X{ X unsigned reg = ea & 0x7; X long disp; X t_entry tent; X X pos += 2; X X switch ((ea >> 3) & 0x7) { X case 0: X (void) printf("%%d%d", reg); X return 0; X case 1: X (void) fputs(areg[reg], stdout); X return 0; X case 2: X (void) printf("(%s)", areg[reg]); X return 0; X case 3: X (void) printf("(%s)+", areg[reg]); X return 0; X case 4: X (void) printf("-(%s)", areg[reg]); X return 0; X case 5: X disp = gettw(&mainfile, pos, R_WORD); X (void) prind(disp); X (void) printf("(%s)", areg[reg]); X return 2; X case 6: X piword(areg[reg], (unsigned) gettw(&mainfile, pos, R_WORD)); X return 2; X default: X switch (reg) { X case 0: X disp = gettw(&mainfile, pos, R_WORD); X (void) prind(disp); X (void) putchar('.'); X (void) putchar('w'); X return 2; X case 1: X paddr(pos); X return 4; X case 2:{ X symbol symb; X register int addr; X disp = X ((short) gettw(&mainfile, pos, R_WORD)); X if ((addr=pos+disp) < 0 || X addr-mainfile.ef_tbase > mainfile.ef_tsize || X (addr & 1) != 0) X goto skiplabs; X gette(&mainfile, addr, &tent); X if (tent.t_relsymb != NULL) { X symb = tent.t_relsymb; X } X else if (tent.t_lab != NULL) { X symb = tent.t_lab; X } X else { X skiplabs: X (void) prind(disp); X (void) fputs("(%pc)", stdout); X return 2; X } X if (symb->s_lsymb != 0) X (void) printf("L%%%u", symb->s_lsymb); X else X (void) fputs(symb->s_name, stdout); X if (tent.t_reldisp != 0) X (void) printf("+0x%x", tent.t_reldisp); X return 2; X } X case 3: X piword("%pc", (unsigned)gettw(&mainfile, pos, R_WORD)); X return 2; X case 4: X (void) putchar('&'); X if (sz < 4) X (void) prind(gettw(&mainfile, pos, R_WORD)); X else X paddr(pos); X return sz; X default: X (void) fprintf(stderr, "Funny mode\n"); X exit(220); X } X } X /*NOTREACHED*/ X} X Xint pmove(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned sz = 2; X unsigned tc = te->t_contents; X X (void) printf("mov%s\t", optab[te->t_iindex].prarg); X X if ((tc & 0xf000) == 0x2000) X sz = 4; X X pos += prea(tc, pos, sz); X (void) putchar(','); X (void) prea(((tc >> 9) & 0x7) | ((tc >> 3) & 0x38), pos, sz); X} X Xint pcbch(te) Xt_entry *te; X{ X int cc = ((te->t_contents >> 8) & 0xf) - 2; X char *msg; X register symbol ts; X X if (cc < 0) X msg = cc < -1? "ra": "sr"; X else X msg = cclist[cc]; X (void) printf("b%s", msg); X/* this specifically requests that 8 bit addressing be used, X but the unixpc assembler will do this automatically. X if (te->t_lng < 2) { X (void) putchar('.'); X (void) putchar('b'); X } X*/ X ts = te->t_relsymb; X if (ts->s_lsymb != 0) X (void) printf("\tL%%%u", ts->s_lsymb); X else X { X (void) putchar('\t'); X (void) fputs(ts->s_name, stdout); X } X} X Xint pdbcc(te) Xt_entry *te; X{ X unsigned tc = te->t_contents; X int cc = ((tc >> 8) & 0xf) - 2; X char *msg; X register symbol ts; X X if (cc < 0) X msg = cc < -1? "t": "f"; X else X msg = cclist[cc]; X ts = te->t_relsymb; X (void) printf("db%s\t%%d%d,", msg, tc & 0x7); X if (ts->s_lsymb) X (void) printf("L%%%u", ts->s_lsymb); X else X (void) fputs(ts->s_name, stdout); X} X Xint pscc(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X int cc = ((tc >> 8) & 0xf) - 2; X char *msg; X X if (cc < 0) X msg = cc < -1? "t": "f"; X else X msg = cclist[cc]; X (void) printf("s%s\t", msg); X (void) prea(tc, pos, 1); X} X Xint pcs(te, pos) Xt_entry *te; Xlong pos; X{ X long disp = gettw(&mainfile, pos+2, R_WORD); X X (void) fputs(optab[te->t_iindex].prarg, stdout); X if ((te->t_contents & 0xc0) == 0){ X (void) fputs(".b\t&", stdout); X (void) prind(disp); X (void) fputs(",%cc", stdout); X } X else { X (void) fputs(".w\t&", stdout); X (void) prind(disp); X (void) fputs(",%sr", stdout); X } X} X Xint pmovc(te, pos) Xt_entry *te; Xlong pos; X{ X int disp = gettw(&mainfile, pos+2, R_WORD); X int ctrl = ((disp >> 10) & 2) | (disp & 1); X X (void) fputs("movc\t", stdout); X if ((te->t_contents & 1) == 0) X (void) fputs(creg[ctrl], stdout); X if (disp & 0x8000) X { X (void) fputs(areg[(disp >> 12) & 7], stdout); X (void) putchar(','); X } X else X (void) printf("%%d%d,", disp >> 12); X if (te->t_contents & 1) X (void) fputs(creg[ctrl], stdout); X} X Xint pimed(te, pos) Xt_entry *te; Xlong pos; X{ X int sz = findleng(te->t_contents); X X /* we need to swith the operands to compare instrucions. */ X if (strcmp (optab[te->t_iindex].prarg, "cmp")) { X (void) printf("%s.%c\t&", optab[te->t_iindex].prarg, sz); X if (sz == 'l') { X paddr(pos+2); X (void) putchar(','); X (void) prea(te->t_contents, pos+4, 4); X } X else { X (void) prind(gettw(&mainfile, pos+2, R_WORD)); X (void) putchar(','); X (void) prea(te->t_contents, pos+2, 2); X } X } X else { X (void) printf("%s.%c\t", optab[te->t_iindex].prarg, sz); X if (sz == 'l') { X (void) prea(te->t_contents, pos+4, 4); X (void) putchar(','); X (void) putchar('&'); X paddr(pos+2); X } X else { X (void) prea(te->t_contents, pos+2, 2); X (void) putchar(','); X (void) putchar('&'); X (void) prind(gettw(&mainfile, pos+2, R_WORD)); X } X } X} X Xint pmovp(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X long disp = gettw(&mainfile, pos+2, R_WORD); X int dreg = tc >> 9; X char *ar = areg[tc & 0x7]; X X (void) fputs("movp.", stdout); X if (tc & (1 << 6)) X (void) putchar('l'); X else X (void) putchar('w'); X X if (tc & (1 << 7)) { X (void) printf("\t%%d%d,", dreg); X (void) prind(disp); X (void) printf("(%s)", ar); X } X else { X (void) putchar('\t'); X (void) prind(disp); X (void) printf("(%s),%%d%d", ar, dreg); X } X} X Xint psbit(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X X (void) printf("b%s\t&%d,", bittyp[(tc >> 6) & 0x3], gettw(&mainfile, pos+2, R_WORD)); X (void) prea(tc, pos+2, 1); X} X X/*ARGSUSED*/ Xint pstop(te, pos) Xt_entry *te; Xlong pos; X{ X (void) printf("stop\t&0x%x", gettw(&mainfile, pos+2, R_WORD)); X} X Xint pdbit(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X X (void) printf("b%s\t%%d%d,", bittyp[(tc >> 6) & 0x3], (tc >> 9) & 0x7); X (void) prea(tc, pos, 1); X} X Xint pcs2(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X X (void) fputs("movw\t", stdout); X if ((tc & 0xffc0) == 0x40c0) { X (void) fputs("%sr,", stdout); X (void) prea(tc, pos, 2); X } X else { X (void) prea(tc, pos, 2); X (void) putchar(','); X (void) fputs(optab[te->t_iindex].prarg, stdout); X } X} X Xint pone(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X int sz = findleng(tc); X X (void) printf("%s.%c\t", optab[te->t_iindex].prarg, sz); X (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2)); X} X Xint ppea(te, pos) /* nbcd, pea, tas, jmp, jsr */ Xt_entry *te; Xlong pos; X{ X if (! strncmp(optab[te->t_iindex].prarg, "tas") && X (te->t_contents & 0x3f) == 0x3c) { X symbol symb; X t_entry tstr; X int counter = te->t_lng -2; X int offset = (pos += 4); X int dest; X char * sw_label; X X (void) printf("swbeg\t&%d\n", counter); X X symb = textlab(pos, pos); X printf("%s:\n", sw_label = symb->s_name); X X while (counter--) { X gette(&mainfile, pos, &tstr); X dest = tstr.t_contents + offset; X if (tstr.t_contents > 0 && X dest < 0x290000 && X ! (dest < mainfile.ef_tbase X || dest >= mainfile.ef_tbase+mainfile.ef_tsize X || (dest & 1) != 0 )) { X if (symb = textlab(dest,offset)) X printf("\tshort\t%s-%s\n", X symb->s_name,sw_label); X else X printf("\tshort\t0x%x\t# Can't label destination.\n", X tstr.t_contents); X } X else X printf("\tshort\t0x%x\t# Illegal address\n", X tstr.t_contents); X pos += 2; X } X } X else { X (void) fputs(optab[te->t_iindex].prarg, stdout); X (void) putchar('\t'); X (void) prea(te->t_contents, pos, (unsigned)(te->t_lng>2?4:2)); X } X} X X Xint plea(te, pos) Xt_entry *te; Xlong pos; X{ X (void) fputs("lea\t", stdout); X (void) prea(te->t_contents, pos, 4); X (void) putchar(','); X (void) fputs(areg[(te->t_contents >> 9) & 0x7], stdout); X} X Xint pdreg(te) Xt_entry *te; X{ X (void) printf("%s\t%%d%d", optab[te->t_iindex].prarg, te->t_contents & 7); X} X X Xint pmvml(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X register unsigned dw = gettw(&mainfile, pos+2, R_WORD); X unsigned sz = 4; X int sc = 'l'; X register int i; X register unsigned bit; X X (void) fputs("movm.", stdout); X if ((tc & 0x40) == 0) { X sc = 'w'; X sz = 2; X } X X (void) putchar(sc); X (void) putchar('\t'); X X if (tc & 0x400) { X (void) prea(tc, pos+2, sz); X (void) printf(",&0x%x", dw); X } X else { X (void) printf("&0x%x,", dw); X (void) prea(tc, pos+2, sz); X } X X (void) printf("\t#\t"); X X if ((tc & 0x38) == 0x20) { X bit = 0x8000; X for (i = 0; i < 8; i++) { X if (dw & bit) X (void) printf(" %%d%d", i); X bit >>= 1; X } X for (i = 0; i < 8; i++) { X if (dw & bit) { X (void) putchar(' '); X (void) fputs(areg[i], stdout); X } X bit >>= 1; X } X } X else { X bit = 1; X for (i = 0; i < 8; i++) { X if (dw & bit) X (void) printf(" %%d%d", i); X bit <<= 1; X } X for (i = 0; i < 8; i++) { X if (dw & bit) { X (void) putchar(' '); X (void) fputs(areg[i], stdout); X } X bit <<= 1; X } X } X} X Xint ptrap(te) Xt_entry *te; X{ X (void) printf("trap\t&%d", te->t_contents & 0xf); X} X Xint plink(te, pos) Xt_entry *te; Xlong pos; X{ X (void) printf("link\t%s,&%d", areg[te->t_contents & 0x7], X gettw(&mainfile, pos+2, R_WORD)); X} X X Xint pareg(te) Xt_entry *te; X{ X (void) printf(optab[te->t_iindex].prarg, areg[te->t_contents & 0x7]); X} X Xint podreg(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X X (void) printf("%s\t", optab[te->t_iindex].prarg); X (void) prea(tc, pos, 2); X (void) printf(",%%d%d", (tc >> 9) & 0x7); X} X Xint pqu(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X int sz = findleng(tc); X int amt = (tc >> 9) & 0x7; X X if (amt == 0) X amt = 8; X (void) printf("%s.%c\t&%d,", optab[te->t_iindex].prarg, sz, amt); X (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2)); X} X Xint pmqu(te) Xt_entry *te; X{ X unsigned tc = te->t_contents; X X (void) printf("mov.l\t&%d,%%d%d", (char)tc, (tc >> 9) & 0x7); X} X Xint ptreg(te) Xt_entry *te; X{ X register unsigned tc = te->t_contents; X int rx = (tc >> 9) & 0x7; X int ry = tc & 0x7; X X (void) fputs(optab[te->t_iindex].prarg, stdout); X (void) putchar('\t'); X if (tc & 0x8) X (void) printf("-(%s),-(%s)", areg[ry], areg[rx]); X else X (void) printf("%%d%d,%%d%d", ry, rx); X} X Xint pcmpm(te) Xt_entry *te; X{ X register unsigned tc = te->t_contents; X X (void) printf("%s\t(%s)+,(%s)+", optab[te->t_iindex].prarg, X areg[tc & 7], areg[(tc >> 9) & 7]); X} X Xint pomode(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X char buf[5]; X int sz; X int reg = (tc >> 9) & 7; X X buf[0] = '\0'; X X switch ((tc >> 6) & 7) { X case 0: X sz = 'b'; X goto toreg; X case 1: X sz = 'w'; X goto toreg; X case 2: X sz = 'l'; X toreg: X (void) sprintf(buf, "%%d%d", reg); X goto printaft; X case 3: X sz = 'w'; X goto toareg; X case 7: X sz = 'l'; X toareg: X (void) sprintf(buf, "%s", areg[reg]); X printaft: X if (strcmp("cmp", optab[te->t_iindex].prarg)) { X (void) printf("%s.%c\t", optab[te->t_iindex].prarg,sz); X (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2)); X (void) putchar(','); X (void) fputs(buf, stdout); X } X else { X (void) printf("%s.%c\t%s,", optab[te->t_iindex].prarg, X sz, buf); X (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2)); X } X break; X case 4: X sz = 'b'; X goto frreg; X case 5: X sz = 'w'; X goto frreg; X case 6: X sz = 'l'; X frreg: X (void) sprintf(buf, "%%d%d", reg); X if (strcmp("cmp", optab[te->t_iindex].prarg)) { X (void) printf("%s.%c\t%s,", optab[te->t_iindex].prarg, X sz, buf); X (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2)); X } X else { X (void) printf("%s.%c\t", optab[te->t_iindex].prarg,sz); X (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2)); X (void) putchar(','); X (void) fputs(buf, stdout); X } X } X} X Xint pexg(te) Xt_entry *te; X{ X unsigned tc = te->t_contents; X int r1 = (tc >> 9) & 7, r2 = tc & 7; X X (void) printf("exg\t"); X X if ((tc & 0x00f8) == 0x0048) X { X (void) fputs(areg[r1], stdout); X (void) putchar(','); X } X else X (void) printf("%%d%d,", r1); X if (tc & 0x8) X (void) fputs(areg[r2], stdout); X else X (void) printf("%%d%d", r2); X} X Xint pmshf(te, pos) Xt_entry *te; Xlong pos; X{ X unsigned tc = te->t_contents; X X (void) printf("%s%c.w\t", shtype[(tc >> 9) & 3], tc & 0x100? 'l': 'r'); X (void) prea(tc, pos, 2); X} X Xint pshf(te) Xt_entry *te; X{ X unsigned tc = te->t_contents; X int sz = findleng(tc); X int disp = (tc >> 9) & 7; X X (void) printf("%s%c.%c\t", shtype[(tc >> 3) & 3], tc & 0x100? 'l': 'r', sz); X if (tc & 0x20) X (void) printf("%%d%d", disp); X else X (void) printf("&%d", disp == 0? 8: disp); X (void) printf(",%%d%d", tc & 7); X} X X/* X * Find length etc of instruction. X */ X Xint findinst(te, pos) Xregister t_entry *te; Xlong pos; X{ X register struct opstr *op; X unsigned tc = te->t_contents; X int lng = 0; X register int i; X X te->t_type = T_BEGIN; X te->t_bchtyp = T_NOBR; X X for (op = &optab[0]; op->mask; op++) { X if ((tc & op->mask) == op->match) { X te->t_iindex = op - optab; X lng = (op->opsize)(te, pos); X break; X } X } X X for (i = 1; i < lng; i++) { X t_entry ctent; X long npos = pos+i+i; X X if (npos >= endt) X goto clearem; X gette(&mainfile, npos, &ctent); X if (swbegflg) { X ctent.t_type = T_UNKNOWN; X putte(&mainfile, npos, &ctent); X } X else { X if (ctent.t_bdest || ctent.t_dref) { Xclearem: for (i--; i > 0; i--) { X npos = pos + i + i; X gette(&mainfile, npos, &ctent); X ctent.t_type = T_UNKNOWN; X putte(&mainfile, npos, &ctent); X } X lng = 0; X goto ginv; X } X ctent.t_type = T_CONT; X putte(&mainfile, npos, &ctent); X } X } X swbegflg = 0; X X if (lng <= 0) { Xginv: te->t_vins = 0; X te->t_lng = 1; X te->t_type = T_UNKNOWN; X te->t_bchtyp = T_NOBR; X } X else X te->t_lng = lng; X return lng; X} X X/* X * Print instruction. X */ X Xvoid prinst(te, pos) Xt_entry *te; Xlong pos; X{ X putchar('\t'); X (optab[te->t_iindex].opprin)(te, pos); X putchar('\n'); X} SHAR_EOF chmod 0644 iset.c || echo "restore of iset.c fails" sed 's/^X//' << 'SHAR_EOF' > libmtch.c && X/* X * SCCS: @(#)libmtch.c 1.2 11/2/84 14:18:55 X * Read library files. X * X *********************************************************************** X * This software is copyright of X * X * John M Collins X * 47 Cedarwood Drive X * St Albans X * Herts, AL4 0DN X * England +44 727 57267 X * X * and is released into the public domain on the following conditions: X * X * 1. No free maintenance will be guaranteed. X * 2. Nothing may be based on this software without X * acknowledgement, including incorporation of this X * notice. X * X * Notwithstanding the above, the author welcomes correspondence and bug X * fixes. X *********************************************************************** X */ X X#include <stdio.h> X#include <fcntl.h> X#include <string.h> X#include <a.out.h> X#include <ar.h> X#include <setjmp.h> X#include <ldfcn.h> X#include "unc.h" X Xlong atol(); Xlong lseek(); Xvoid bfopen(), bfclose(), nomem(); Xvoid rrell2(), markmatch(); Xchar *malloc(); Xint matchup(); Xlong findstart(); X Xchar verbose; /* Tell the world what we are doing */ Xchar *tfnam; Xchar *cfile; Xef_fids mainfile; Xstruct commit dreltab; Xint donedrel, donebrel; Xlong trelpos, drelpos, brelpos; Xstatic struct libit currlib = {NULL, NULL, ""}; X Xvoid lclash(str) Xchar *str; X{ X (void) fprintf(stderr, "Library scan failure - %s\n", str); X (void) fprintf(stderr, "Searching %s\n", cfile); X if (currlib.lf_name[0]) X (void) fprintf(stderr, "Member is %s\n", currlib.lf_name); X exit(255); X} X X/* X * Find next member. X */ X Xlong nextmemb(filename,lfd) Xchar *filename; Xregister struct libit *lfd; X{ X struct ar_hdr arbuf; X X ldaclose(lfd->ldptr2); X if (ldclose(lfd->ldptr != FAILURE)) /* end of archive */ X return -1; X lfd->ldptr = ldopen(filename,lfd->ldptr); X ldahread(lfd->ldptr, (char *)&arbuf); X (void) strncpy(lfd->lf_name, arbuf.ar_name, sizeof(lfd->lf_name)); X return 1; X} X X/* X * Decode a file name thus - X * X * -lxxx decode as /lib/libxxx.a /usr/lib/libxxx.a etc X * -Lxxx forget "lib" ".a" bit thus -Lcrt0.o X * or read LDPATH environment var to give list of directories as sh X * (default /lib:/usr/lib). X * X * Alternatively treat as normal pathname. X * X * File names may be followed by (membername) if the file is an archive, X * thus X * X * -lc(printf.o) X * X * in which case the specified module is fetched. X */ X Xstruct libit *getfnam(str) Xchar *str; /* will be expanded to full path name if necessary */ X{ X char *bp, *ep = NULL, *pathb, *pathe, *fullpath = NULL; X static char *pathn; X extern char *getenv(); X char magic[8]; X struct ar_hdr arhdr; X LDFILE *ldptr; X X if ((bp = strrchr(str, '(')) != NULL && X (ep = strrchr(str, ')')) != NULL) X *ep = *bp = '\0'; X X if (str[0] == '-' && (str[1] == 'l' || str[1] == 'L')) { X if (pathn == NULL) { X if ((pathn = getenv("LDPATH")) == NULL) X pathn = "/lib:/usr/lib"; X } X fullpath = malloc((unsigned)(strlen(pathn) + strlen(str) + 1)); X if (fullpath == NULL) X nomem(); X pathb = pathn; X do { X pathe = strchr(pathb, ':'); X if (*pathb == ':') X fullpath[0] = '\0'; X else { X if (pathe != NULL) X *pathe = '\0'; X (void) strcpy(fullpath, pathb); X (void) strcat(fullpath, "/"); X if (pathe != NULL) X *pathe = ':'; X } X if (str[1] == 'l') X (void) strcat(fullpath, "lib"); X (void) strcat(fullpath, &str[2]); X if (str[1] == 'l') X (void) strcat(fullpath, ".a"); X if ((ldptr = ldopen(fullpath, NULL)) != NULL) X goto found; X pathb = pathe + 1; X } while (pathe != NULL); X X (void) fprintf(stderr, "Unable to locate lib%s.a in %s\n", X &str[2], pathn); X exit(101); X } X else if ((ldptr = ldopen(str, NULL)) == NULL) { X (void) fprintf(stderr, "Cannot open %s\n", str); X exit(102); X } X Xfound: X X str = fullpath? fullpath: str; X if (FREAD(magic, sizeof(magic),1,ldptr) != 1 || X strcmp(magic, ARMAG) != 0) { X if (ep != NULL) { X (void) fprintf(stderr, "%s is not library file\n", str); X exit(103); X } X currlib.ldptr = ldptr; X currlib.ldptr2 = ldaopen(str,ldptr); X currlib.lf_name[0] = '\0'; X return &currlib; X } X X /* X * It appears to be a library file - see if we want a specific X * one. X */ X X if (ep != NULL) { X char *cp; X X for (;;) { X if (ldahread(ldptr,&arhdr) == FAILURE) { X (void) fprintf(stderr, "Cannot find member %s in %s\n", X bp+1, str); X exit(103); X } X for ( cp = arhdr.ar_name + sizeof(arhdr.ar_name) - 1; X *cp == ' '; X cp -- ) ; X if (strncmp(bp+1, arhdr.ar_name, cp - arhdr.ar_name + 1) == 0) X break; X X if (ldclose(ldptr) != FAILURE) { X (void) fprintf(stderr, "Cannot find member %s in %s\n", X bp+1, str); X exit(103); X } X ldptr = ldopen(str,ldptr); X } X currlib.ldptr = ldptr; X currlib.ldptr2 = ldaopen(str,ldptr); X currlib.lf_name[0] = '\0'; X *bp = '('; X *ep = ')'; X return &currlib; X } X X /* X * Otherwise point to 1st member in library. X */ X X if (ldahread(ldptr, &arhdr) == FAILURE) { X (void) fprintf(stderr, "Library %s empty\n", str); X exit(104); X } X currlib.ldptr = ldptr; X currlib.ldptr2 = ldaopen(str,ldptr); X (void) strncpy(currlib.lf_name, arhdr.ar_name, sizeof(currlib.lf_name)); X return &currlib; X} X X/* X * Process library files. X */ X X#define MINTEXT 6 X Xvoid lscan(nfiles, fnames) Xint nfiles; Xchar **fnames; X{ X ef_fids libfile; X register ef_fid ll = &libfile; X register struct libit *clf; X extern symbol dolsymb(); X int firstfile; X X for (; nfiles > 0; fnames++, nfiles--) { X clf = getfnam(*fnames); X cfile = *fnames; X firstfile = 1; X do { X bfopen(tfnam, ll); X X /* X * If file is garbled, silently forget it and go X * on to the next one. X */ X X if (!rtext(clf->ldptr, ll)) X goto closeit; X X if (ll->ef_tsize < MINTEXT) X goto closeit; X X if (!rdata(clf->ldptr, ll)) X goto closeit; X X if (rrell1(clf->ldptr, ll) < 0) X goto closeit; X X /* X * If first file in library, find it from X * beginning of main file. X */ X X if (firstfile) { X if ((trelpos = findstart(&mainfile, ll)) < 0) X goto closeit; X firstfile = 0; X } X else if (!matchup(&mainfile, ll, trelpos)) X goto closeit; X X /* X * Found a match. X */ X X if (!rsymb(clf->ldptr, dolsymb, ll)) { X (void) fprintf(stderr, "Corrupt file %s\n", X *fnames); X exit(150); X } X X donedrel = 0; X donebrel = 0; X rrell2(clf->ldptr, clf->ldptr2, ll); X if (verbose) { X (void) fprintf(stderr, "Found: "); X if (clf->lf_name[0]) X (void) fprintf(stderr, "%.14s in ", X clf->lf_name); X (void) fprintf(stderr, "%s\n", *fnames); X } X if (libfile.ef_stvec != NULL) { X free(libfile.ef_stvec); X libfile.ef_stvec = NULL; X libfile.ef_stcnt = 0; X } X dreltab.c_int = 0; X X /* X * Start looking next time round X * where last one left off. X */ X X markmatch(&mainfile, ll, trelpos); X trelpos += libfile.ef_tsize; Xcloseit: X bfclose(ll); X } while (nextmemb(cfile,clf) >= 0); X } X} SHAR_EOF chmod 0644 libmtch.c || echo "restore of libmtch.c fails" sed 's/^X//' << 'SHAR_EOF' > robj.c && X/* X * SCCS: @(#)robj.c 1.2 11/2/84 14:19:59 X * Read object files. X * X *********************************************************************** X * This software is copyright of X * X * John M Collins X * 47 Cedarwood Drive X * St Albans X * Herts, AL4 0DN X * England +44 727 57267 X * X * and is released into the public domain on the following conditions: X * X * 1. No free maintenance will be guaranteed. X * 2. Nothing may be based on this software without X * acknowledgement, including incorporation of this X * notice. X * X * Notwithstanding the above, the author welcomes correspondence and bug X * fixes. X *********************************************************************** X * X * This particular module will obviously have to be munged beyond X * recognition for another object format. X */ X X#include <stdio.h> X#include <a.out.h> X#include <ldfcn.h> X#include <string.h> X#include "unc.h" X Xvoid gette(), getde(), setde(), putte(), putde(); Xlong gettw(), getdw(); Xvoid reallst(), lclash(), nomem(), unimpl(); Xvoid addit(); Xchar *malloc(); Xlong lseek(); X Xint par_entry, par_round, nmods, donedrel, donebrel; Xstruct commit abstab, comtab, dreltab; Xlong trelpos, drelpos, brelpos; X Xint *symord; /* convert symbol index to symbol ordinal */ X Xef_fids mainfile; X Xsymbol lookup(), inventsymb(), getnsymb(); X X#define RWORD 1 X#define RLONG 2 X#define DBSIZE 100 X#define STINIT 20 X X/* X * Read text segment. Return 0 if not ok. X */ X Xint rtext(ldptr, outf) X LDFILE *ldptr; /* a.out file (possibly in library) */ X ef_fid outf; /* Output file descriptor */ X{ X t_entry tstr; X struct aouthdr unixhdr; X struct scnhdr sect; X register long size; X register int i, l; X unsigned short inbuf[DBSIZE/2]; X X /* X * Initialise fields in structure. X */ X X tstr.t_type = T_UNKNOWN; X tstr.t_vins = 1; /* For the moment */ X tstr.t_bdest = 0; X tstr.t_gbdest = 0; X tstr.t_lng = 1; X tstr.t_reloc = R_NONE; X tstr.t_rdisp = 0; X tstr.t_isrel = 0; X tstr.t_amap = 0; X tstr.t_dref = 0; X tstr.t_relsymb = NULL; X tstr.t_reldisp = 0; X tstr.t_lab = NULL; X tstr.t_lsymb = 0; X tstr.t_refhi = 0; X tstr.t_reflo = 0x7fffffff; X tstr.t_match = 0; X X /* X * Read a.out header. X */ X X if (ldohseek(ldptr) == FAILURE) { /* no optional header */ X X outf->ef_entry = 0; X ldshread(ldptr,1,§); /* text header */ X outf->ef_tbase = sect.s_vaddr; X outf->ef_tsize = sect.s_size; X X ldshread(ldptr,2,§); /* data header */ X outf->ef_dbase = sect.s_vaddr; X outf->ef_dsize = sect.s_size; X X ldshread(ldptr,3,§); /* bss header */ X outf->ef_bbase = sect.s_vaddr; X outf->ef_bsize = sect.s_size; X outf->ef_end = sect.s_vaddr + sect.s_size; X } else { X FREAD((char *)&unixhdr,sizeof(struct aouthdr),1,ldptr); X X if ( N_BADMAG(unixhdr) ) X return 0; X X outf->ef_entry = unixhdr.entry; X outf->ef_tbase = unixhdr.text_start; X outf->ef_dbase = unixhdr.data_start; X outf->ef_bbase = outf->ef_dbase + unixhdr.dsize; X outf->ef_end = outf->ef_bbase + unixhdr.bsize; X X outf->ef_tsize = unixhdr.tsize; X outf->ef_dsize = unixhdr.dsize; X outf->ef_bsize = unixhdr.bsize; X } X X ldsseek(ldptr,1); /* seek to text section */ X X size = outf->ef_tsize; X X while (size > 1) { X l = size > DBSIZE? DBSIZE: size; X if (FREAD((char *)inbuf,1,l,ldptr) != l) X return 0; X l /= 2; X for (i = 0; i < l; i++) { X tstr.t_contents = inbuf[i]; X (void) write(outf->ef_t, (char *)&tstr, sizeof(tstr)); X } X size -= l + l; X } X X /* X * Extra one to cope with "etext". X */ X X (void) write(outf->ef_t, (char *)&tstr, sizeof(tstr)); X return 1; X} X/* X * Same sort of thing for the data segment. X */ X Xint rdata(ldptr, outf) XLDFILE *ldptr; /* a.out file (possibly in library) */ Xef_fid outf; /* Output file descriptor */ X{ X d_entry dstr; X register long size; X register int i, l; X unsigned char inbuf[DBSIZE]; X X /* X * Initialise fields in structure. X */ X X dstr.d_type = D_BYTE; X dstr.d_reloc = R_NONE; X dstr.d_lng = 1; X dstr.d_relsymb = NULL; X dstr.d_reldisp = 0; X dstr.d_lab = NULL; X X ldsseek(ldptr,2); /* seek to data section */ X X size = outf->ef_dsize; X X while (size > 0) { X l = size > DBSIZE? DBSIZE: size; X if (FREAD((char *)inbuf,1,l,ldptr) != l) X return 0; X for (i = 0; i < l; i++) { X dstr.d_contents = inbuf[i]; X (void) write(outf->ef_d, (char *)&dstr, sizeof(dstr)); X } X size -= l; X } X X /* X * Repeat for BSS segment. X */ X X dstr.d_contents = 0; X for (size = outf->ef_bsize; size > 0; size--) X (void) write(outf->ef_d, (char *)&dstr, sizeof(dstr)); X X /* X * Extra one to cope with "end". X */ X X (void) write(outf->ef_d, (char *)&dstr, sizeof(dstr)); X return 1; X} X X/* X * Process symbol table segment. X */ X Xint rsymb(ldptr, dproc, outf) XLDFILE *ldptr; /* a.out file (possibly in library) */ Xsymbol (*dproc)(); Xregister ef_fid outf; /* Output file descriptor */ X{ X#define SYMLENGTH 256 X register symbol csym; X struct syment isym; X register int nsyms,symindex; X unsigned long stroff; X char inbuf[SYMLENGTH+1], *cp; X int ord; X X nsyms = HEADER(ldptr).f_nsyms; X stroff = HEADER(ldptr).f_symptr + nsyms*sizeof(struct syment); X X if (nsyms <= 0) X nsyms = STINIT; X X outf->ef_stvec = (symbol *) malloc(nsyms * sizeof(symbol)); X symord = (int *) malloc(nsyms * sizeof(int)); X if (outf->ef_stvec == NULL) X nomem(); X X outf->ef_stcnt = 0; X outf->ef_stmax = nsyms; X ord = 0; X X for (symindex=0; symindex<nsyms; symindex++) { X ldtbread(ldptr,symindex,&isym); X if (isym.n_zeroes == 0) { /* get from string table */ X FSEEK(ldptr,stroff + isym.n_offset,0); X cp = inbuf; X do { X if (FREAD(cp,1,1,ldptr) != 1)/* Read symbol chars 1-by-1 */ X return 0; X if ( cp - inbuf >= SYMLENGTH )/* Check against buffer overflow */ X return 0; X } while (*cp++ != '\0');/* Terminate on null byte */ X } else { /* get from symbol field */ X strncpy(inbuf,isym.n_name,8); X inbuf[8] = '\0'; X } X csym = (*dproc)(lookup(inbuf), convtosun(&isym), X isym.n_value, outf); X if (outf->ef_stcnt >= outf->ef_stmax) X reallst(outf); X outf->ef_stvec[outf->ef_stcnt++] = csym; X symord[symindex] = ord++; /* record ordinal */ X symindex += isym.n_numaux; /* skip aux entries */ X } X return 1; X} X X/* X * Process relocation stuff. -1 error, 0 no relocation, 1 relocation. X */ X Xint rrel(ldptr, ldptr2, outf) XLDFILE *ldptr,*ldptr2; /* a.out file (possibly in library) */ Xef_fid outf; /* Output file descriptor */ X{ X struct reloc crel; X struct scnhdr tsect,dsect; X struct syment isym; X t_entry tstr; X d_entry dstr; X register int nreloc; X long cont, pos; X X ldshread(ldptr,1,&tsect); X ldshread(ldptr,2,&dsect); X if (tsect.s_nreloc <= 0 && dsect.s_nreloc <= 0) X return 0; X X nreloc = tsect.s_nreloc; X X ldrseek(ldptr,1); X while (nreloc-- > 0) { X if (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1) X return -1; X X pos = crel.r_vaddr; X gette(outf, pos, &tstr); X if (crel.r_type == R_ABS) X tstr.t_reloc = R_NONE; X else X tstr.t_reloc = R_LONG; /* what about PC-relative? */ X ldtbread(ldptr2,crel.r_symndx,&isym); X if (isym.n_sclass == C_EXT) { X tstr.t_relsymb = outf->ef_stvec[symord[crel.r_symndx]]; X tstr.t_reldisp = gettw(outf, pos, (int)tstr.t_reloc); X } X else { X cont = gettw(outf, pos, (int)tstr.t_reloc); X tstr.t_relsymb = getnsymb(outf, convtosun(&isym), cont); X } X tstr.t_relsymb->s_used++; X putte(outf, pos, &tstr); X } X X /* X * And now repeat all that for data relocations. X */ X X nreloc = dsect.s_nreloc; X X ldrseek(ldptr,2); X while (nreloc-- > 0) { X if (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1) X return -1; X X pos = crel.r_vaddr; X getde(outf, pos, &dstr); X if (crel.r_type == R_ABS) X dstr.d_reloc = R_NONE; X else X dstr.d_reloc = R_LONG; /* what about PC-relative? */ X X ldtbread(ldptr2,crel.r_symndx,&isym); X if (isym.n_sclass == C_EXT) { X dstr.d_relsymb = outf->ef_stvec[symord[crel.r_symndx]]; X dstr.d_reldisp = getdw(outf, pos, (int)dstr.d_reloc); X } X else { X cont = getdw(outf, pos, (int)dstr.d_reloc); X dstr.d_relsymb = getnsymb(outf, convtosun(&isym), cont); X if (dstr.d_relsymb->s_type == S_TEXT) { X gette(outf, cont, &tstr); X tstr.t_dref = 1; X putte(outf, cont, &tstr); X } X } X switch (dstr.d_reloc) { X default: X unimpl("Data byte relocation"); X break; X case R_WORD: X unimpl("data word reloc"); X dstr.d_type = D_WORD; X dstr.d_lng = 2; X setde(outf, pos+1, D_CONT, 1); X break; X case R_LONG: X dstr.d_type = D_ADDR; X dstr.d_lng = 4; X setde(outf, pos+1, D_CONT, 1); X setde(outf, pos+2, D_CONT, 1); X setde(outf, pos+3, D_CONT, 1); X break; X } X dstr.d_relsymb->s_used++; X putde(outf, pos, &dstr); X } X return 1; X} X X/* X * Process a symbol. X */ X Xsymbol dosymb(sy, type, val, fid) Xregister symbol sy; Xint type; Xlong val; Xef_fid fid; X{ X t_entry tstr; X d_entry dstr; X X if (!sy->s_newsym) { X if (type & S_EXT) { X (void) fprintf(stderr, "Duplicate symbol %s\n", sy->s_name); X /* exit(10); temporary? */ X } X if (++sy->s_defs > nmods) X nmods = sy->s_defs; X sy = inventsymb("DUP"); X } X X sy->s_value = val; X X switch (type) { X default: X return NULL; X X case S_EXT|S_UNDF: X if (val != 0) { X sy->s_type = S_COMM; X addit(&comtab, sy); X } X else X sy->s_type = S_UNDF; X sy->s_glob = 1; X break; X X case S_EXT|S_ABS: X sy->s_type = S_ABS; X sy->s_glob = 1; X addit(&abstab, sy); X break; X X case S_ABS: X sy->s_type = S_ABS; X addit(&abstab, sy); X break; X X case S_EXT|S_TEXT: X case S_TEXT: X sy->s_type = S_TEXT; X gette(fid, val, &tstr); X tstr.t_bdest = 1; X if (type & S_EXT) { X tstr.t_gbdest = 1; X sy->s_glob = 1; X } X sy->s_link = tstr.t_lab; X tstr.t_lab = sy; X putte(fid, val, &tstr); X break; X X case S_BSS: X case S_EXT|S_BSS: X sy->s_type = S_BSS; X goto datrest; X case S_DATA: X case S_EXT|S_DATA: X sy->s_type = S_DATA; X datrest: X getde(fid, val, &dstr); X if (type & S_EXT) X sy->s_glob = 1; X sy->s_link = dstr.d_lab; X dstr.d_lab = sy; X putde(fid, val, &dstr); X break; X } X X sy->s_newsym = 0; X return sy; X} X X X/* X * Process relocation stuff in putative library modules. X * The main function of all this is to mark which bits of the text X * not to look at as I compare the stuff. X * X * As with "rrel", return -1 error, 0 no relocation, 1 relocation. X */ X Xint rrell1(ldptr, outf) XLDFILE *ldptr; /* a.out file (possibly in library) */ Xef_fid outf; /* Output file descriptor */ X{ X struct reloc crel; X struct scnhdr tsect,dsect; X t_entry tstr; X register int nreloc; X long pos; X X ldshread(ldptr,1,&tsect); X ldshread(ldptr,2,&dsect); X if (tsect.s_nreloc <= 0 && dsect.s_nreloc <= 0) X return 0; X X nreloc = tsect.s_nreloc; X X ldrseek(ldptr,1); X while (nreloc-- > 0) { X if (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1) X return -1; X X pos = crel.r_vaddr; X gette(outf, pos, &tstr); X if (crel.r_type == R_ABS) X tstr.t_reloc = R_NONE; X else X tstr.t_reloc = R_LONG; /* what about PC-relative? */ X tstr.t_isrel = 1; X putte(outf, pos, &tstr); X if (tstr.t_reloc == R_LONG) { X gette(outf, pos+2, &tstr); X tstr.t_isrel = 1; X putte(outf, pos+2, &tstr); X } X } X X /* X * Dont bother with data relocation at this stage. We'll X * tie that up later. X */ X X return 1; X} X X/* X * Process a symbol in library file. The extern variable trelpos gives X * the place in the main file where the library module is relocated. X * We don't know the data position until we do the final merge, perhaps X * not even then. X */ X/* trelpos ??? */ X Xsymbol dolsymb(sy, type, val, fid) Xregister symbol sy; Xint type; Xlong val; Xef_fid fid; X{ X t_entry tstr; X X switch (type) { X default: X return NULL; X X case S_EXT|S_UNDF: X if (!sy->s_newsym) X return sy; X sy->s_value = val; X if (val != 0) { X sy->s_type = S_COMM; X addit(&dreltab, sy); X } X else X sy->s_type = S_UNDF; X sy->s_glob = 1; X break; X X case S_EXT|S_ABS: X if (!sy->s_newsym) { X if (sy->s_type != S_ABS || sy->s_value != val) X lclash("abs"); X } X sy->s_type = S_ABS; X sy->s_value = val; X sy->s_glob = 1; X addit(&abstab, sy); X break; X X case S_EXT|S_TEXT: X sy->s_type = S_TEXT; X val += trelpos - fid->ef_tbase; X if (!sy->s_newsym) { X if (val != sy->s_value) X lclash("tsym"); X return sy; X } X sy->s_value = val; X gette(&mainfile, val, &tstr); X tstr.t_bdest = 1; X tstr.t_gbdest = 1; X sy->s_glob = 1; X sy->s_link = tstr.t_lab; X tstr.t_lab = sy; X putte(&mainfile, val, &tstr); X break; X X case S_EXT|S_BSS: X if (!sy->s_newsym) X return sy; X sy->s_type = S_BSS; X sy->s_value = val - fid->ef_bbase; X goto datrest; X X case S_EXT|S_DATA: X if (!sy->s_newsym) X return sy; X sy->s_type = S_DATA; X sy->s_value = val - fid->ef_dbase; X datrest: X sy->s_glob = 1; X addit(&dreltab, sy); X break; X } X X sy->s_newsym = 0; X return sy; X} X X/* X * Change definition of undefined symbol as we define it. X */ X Xvoid reassign(sy, val) Xregister symbol sy; Xlong val; X{ X sy->s_value = val; X X if (val < mainfile.ef_tbase) { X sy->s_type = S_ABS; X addit(&abstab, sy); X } X else if (val < mainfile.ef_dbase) { X t_entry tstr; X X sy->s_type = S_TEXT; X gette(&mainfile, val, &tstr); X tstr.t_bdest = 1; X tstr.t_gbdest = 1; X sy->s_glob = 1; X sy->s_link = tstr.t_lab; X tstr.t_lab = sy; X putte(&mainfile, val, &tstr); X } X else { X d_entry dstr; X X sy->s_type = val < mainfile.ef_bbase? S_DATA: S_BSS; X getde(&mainfile, val, &dstr); X sy->s_link = dstr.d_lab; X dstr.d_lab = sy; X putde(&mainfile, val, &dstr); X } X} X X/* X * When we discover where bss or data come, reallocate the table. X */ X Xvoid zapdat(seg, inc) Xint seg; Xlong inc; X{ X register int i; X register symbol csymb; X d_entry dent; X X for (i = 0; i < dreltab.c_int; i++) { X csymb = dreltab.c_symb[i]; X if (csymb->s_type != seg) X continue; X csymb->s_value += inc; X getde(&mainfile, csymb->s_value, &dent); X csymb->s_link = dent.d_lab; X dent.d_lab = csymb; X putde(&mainfile, csymb->s_value, &dent); X } X} X X/* X * Process relocation stuff in library module which we are inserting. X * Horrors if something goes wrong. X */ X/* trelpos, drelpos ??? */ X Xrrell2(ldptr, ldptr2, outf) XLDFILE *ldptr,*ldptr2; /* a.out file (possibly in library) */ Xef_fid outf; /* Output file descriptor */ X{ X struct reloc crel; X t_entry mtstr; X d_entry mdstr; X struct scnhdr tsect,dsect; X struct syment isym; X int nreloc; X unsigned rtype; X register long size; X register symbol csymb; X long pos, mpos, mval, lval; X int dhere = 0; /* Mark whether bss done */ X X ldshread(ldptr,1,&tsect); X ldshread(ldptr,2,&dsect); X if (tsect.s_nreloc <= 0 && dsect.s_nreloc <= 0) X return 0; X X nreloc = tsect.s_nreloc; X X ldrseek(ldptr,1); X while (nreloc-- > 0) { X if (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1) X lclash("rd trel"); X X pos = crel.r_vaddr; X mpos = crel.r_vaddr + trelpos; X gette(&mainfile, mpos, &mtstr); X if (crel.r_type == R_ABS) X rtype = R_NONE; X else X rtype = R_LONG; /* what about PC-relative? */ X ldtbread(ldptr2,crel.r_symndx,&isym); X lval = gettw(outf, pos, (int)rtype); X mval = gettw(&mainfile, mpos, (int)rtype); X X if ( isym.n_sclass != C_EXT ) { X switch (convtosun(&isym)) { X case S_TEXT: X if (lval + trelpos - outf->ef_tbase != mval) X lclash("Trel"); X continue; X case S_DATA: X if (donedrel) { X if (lval + drelpos - outf->ef_dbase != mval) X lclash("Drel"); X } X else { X donedrel++; X drelpos = mval - lval + outf->ef_dbase; X } X continue; X case S_BSS: X if (donebrel) { X if (lval + brelpos - outf->ef_bbase != mval) X lclash("brel"); X } X else { X donebrel++; X brelpos = mval - lval + outf->ef_bbase; X } X continue; X } X } else { X if (crel.r_symndx >= outf->ef_stcnt) X lclash("Bad sy no"); X csymb = outf->ef_stvec[symord[crel.r_symndx]]; X if (csymb == NULL) X continue; X switch (csymb->s_type) { X case S_UNDF: X reassign(csymb, mval - lval); X break; X case S_ABS: X if (lval + csymb->s_value != mval) X lclash("abs rel"); X break; X case S_TEXT: X if (lval + csymb->s_value != mval) X lclash("text rel"); X break; X case S_DATA: X if (lval + csymb->s_value != mval) X lclash("data rel"); X break; X case S_BSS: X if (lval + csymb->s_value != mval) X lclash("bss rel"); X break; X case S_COMM: X reassign(csymb, mval - lval); X break; X } X mtstr.t_relsymb = csymb; X mtstr.t_reldisp = lval; X } X } X X /* X * Relocate data and bss if possible. X */ X X if (donebrel) { X zapdat(S_BSS, brelpos); X dhere++; X } X X if (!donedrel) X return; X X X zapdat(S_DATA, drelpos); X X /* X * And now repeat all that for data relocations if possible X */ X X nreloc = tsect.s_nreloc; X X ldrseek(ldptr,2); X X while (nreloc-- > 0) { X if (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1) X lclash("Rd drel"); X X if (crel.r_type == R_ABS) X continue; X X pos = crel.r_vaddr; X mpos = crel.r_vaddr + drelpos; X getde(&mainfile, mpos, &mdstr); X rtype = R_LONG; /* what about PC-relative? */ X ldtbread(ldptr2,crel.r_symndx,&isym); X X lval = getdw(outf, pos, (int)rtype); X mval = getdw(&mainfile, mpos, (int)rtype); X if ( isym.n_sclass != C_EXT ) { X switch (convtosun(&isym)) { X case S_TEXT: X if (lval + trelpos - outf->ef_tbase != mval) X lclash("Trel-d"); X continue; X case S_DATA: X if (lval + drelpos - outf->ef_dbase != mval) X lclash("Drel-d"); X continue; X case S_BSS: X if (donebrel) { X if (lval + brelpos - outf->ef_bbase != mval) X lclash("brel"); X } X else { X donebrel++; X brelpos = mval - lval + outf->ef_bbase; X } X continue; X } X } else { X if (crel.r_symndx >= outf->ef_stcnt) X lclash("Bad sy no"); X csymb = outf->ef_stvec[symord[crel.r_symndx]]; X if (csymb == NULL) X continue; X switch (csymb->s_type) { X case S_UNDF: X reassign(csymb, mval - lval); X break; X case S_ABS: X if (lval + csymb->s_value != mval) X lclash("abs rel"); X break; X case S_TEXT: X if (lval + csymb->s_value != mval) X lclash("text rel"); X break; X case S_DATA: X if (lval + csymb->s_value != mval) X lclash("data rel"); X break; X case S_BSS: X if (lval + csymb->s_value != mval) X lclash("bss rel"); X break; X case S_COMM: X reassign(csymb, mval - lval); X break; X } X mtstr.t_relsymb = csymb; X mtstr.t_reldisp = lval; X } X } X X if (dhere || !donebrel) X return; X X zapdat(S_BSS, brelpos); X} SHAR_EOF chmod 0644 robj.c || echo "restore of robj.c fails" exit 0