unix-pc dissassembler (1 of 2)
Alex S. Crain
alex at umbc3.UMD.EDU
Thu Oct 6 13:10:03 AEST 1988
#!/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
--
:alex.
Systems Programmer
nerwin!alex at umbc3.umd.edu UMBC
alex at umbc3.umd.edu
More information about the Unix-pc.sources
mailing list