home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!mcnc!rutgers!tut.cis.ohio-state.edu!cwjcc!hal!ncoast!allbery
- From: alex@umbc3.UUCP (Alex S. Crain)
- Newsgroups: comp.sources.misc
- Subject: v04i125: 680x0 COFF disassembler (1 of 2)
- Message-ID: <8810102102.AA05917@umbc3.UMD.EDU>
- Date: 14 Oct 88 23:38:01 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: alex@umbc3.UUCP (Alex S. Crain)
- Lines: 2414
- Approved: allbery@ncoast.UUCP
-
- 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
-