home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume4 / 68kdisasm / part01 next >
Encoding:
Internet Message Format  |  1989-02-03  |  52.5 KB

  1. Path: xanth!mcnc!rutgers!tut.cis.ohio-state.edu!cwjcc!hal!ncoast!allbery
  2. From: alex@umbc3.UUCP (Alex S. Crain)
  3. Newsgroups: comp.sources.misc
  4. Subject: v04i125: 680x0 COFF disassembler (1 of 2)
  5. Message-ID: <8810102102.AA05917@umbc3.UMD.EDU>
  6. Date: 14 Oct 88 23:38:01 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: alex@umbc3.UUCP (Alex S. Crain)
  9. Lines: 2414
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 4, Issue 125
  13. Submitted-by: "Alex S. Crain" <alex@umbc3.UUCP>
  14. Archive-name: 68kdisasm/Part1
  15.  
  16.     This is a dissassembler for 68K COFF machines, based on the unc 
  17. program that went out over the net awhile back. It works really well, and alot
  18. of people have shown an interest.
  19.  
  20. #!/bin/sh
  21. # shar:    Shell Archiver  (v1.22)
  22. #
  23. #    Run the following text with /bin/sh to create:
  24. #      iset.c
  25. #      libmtch.c
  26. #      robj.c
  27. #
  28. sed 's/^X//' << 'SHAR_EOF' > iset.c &&
  29. X/*
  30. X *    SCCS:    @(#)iset.c    1.2    11/2/84    14:18:23
  31. X *    Decode instructions.
  32. X *
  33. X ***********************************************************************
  34. X *    This software is copyright of
  35. X *
  36. X *        John M Collins
  37. X *        47 Cedarwood Drive
  38. X *        St Albans
  39. X *        Herts, AL4 0DN
  40. X *        England            +44 727 57267
  41. X *
  42. X *    and is released into the public domain on the following conditions:
  43. X *
  44. X *        1.  No free maintenance will be guaranteed.
  45. X *        2.  Nothing may be based on this software without
  46. X *            acknowledgement, including incorporation of this
  47. X *            notice.
  48. X *
  49. X *    Notwithstanding the above, the author welcomes correspondence and bug
  50. X *    fixes.
  51. X ***********************************************************************
  52. X */
  53. X
  54. X#include <stdio.h>
  55. X#include <a.out.h>
  56. X#include <ldfcn.h>
  57. X#include "unc.h"
  58. X
  59. Xef_fids    mainfile;
  60. Xlong    endt;
  61. X
  62. Xvoid    gette(), putte();
  63. Xvoid    mkdref();
  64. Xlong    gettw();
  65. Xsymbol    textlab();
  66. X
  67. Xint    l1(), l2(), el1(), lea(), lmove(), lcbch(), jj();
  68. Xint    limed(), lsbit(), lmvml(), lone(), loone(), lonew(), lonel();
  69. X
  70. Xint    pmove(), pcbch(), pdbcc(), pscc(), pcs(), pmovc(), pstop(), pexg();
  71. Xint    pimed(), pmovp(), psbit(), pdbit(), pcs2(), pone(), ppea();
  72. Xint    plea(), pdreg(), pmvml(), ptrap(), plink(), pareg(), podreg();
  73. Xint    pqu(), pmqu(), ptreg(), pcmpm(), pomode(), pmshf(), pshf();
  74. X
  75. Xstruct    opstr    {
  76. X    unsigned  short     mask;
  77. X    unsigned  short  match;
  78. X    int    (*opsize)();
  79. X    int    (*opprin)();
  80. X    char    *prarg;
  81. X} optab[] = {
  82. X    0xf000, 0x2000, lmove, pmove, ".l",
  83. X    0xf000, 0x3000, lmove, pmove, ".w",
  84. X    0xf000, 0x1000, lmove, pmove, ".b",
  85. X    0xf000, 0x6000, lcbch, pcbch, 0,
  86. X    0xffbf, 0x003c, l2,    pcs,   "or",
  87. X    0xff00, 0x0000, limed, pimed, "or",
  88. X    0xffbf, 0x023c, l2,    pcs,   "and",
  89. X    0xff00, 0x0200, limed, pimed, "and",
  90. X    0xff00, 0x0400, limed, pimed, "sub",
  91. X    0xff00, 0x0600, limed, pimed, "add",
  92. X    0xffbf, 0x0a3c, l2,    pcs,   "eor",
  93. X    0xff00, 0x0a00, limed, pimed, "eor",
  94. X    0xff00, 0x0c00, limed, pimed, "cmp",
  95. X    0xf138, 0x0108, l2,    pmovp, 0,
  96. X    0xff00, 0x0800, lsbit, psbit, 0,
  97. X    0xf100, 0x0100, lonew, pdbit, 0,
  98. X    0xffc0, 0x40c0, lonew, pcs2,  "sr",
  99. X    0xff00, 0x4000, lone,  pone,  "negx",
  100. X    0xff00, 0x4200, lone,  pone,  "clr",
  101. X    0xffc0, 0x44c0, lonew, pcs2,  "cc",
  102. X    0xff00, 0x4400, lone,  pone,  "neg",
  103. X    0xffc0, 0x46c0, lonew, pcs2,  "sr",
  104. X    0xff00, 0x4600, lone,  pone,  "not",
  105. X    0xffc0, 0x4800, lonew, ppea,  "nbcd",
  106. X    0xfff8, 0x4840, l1,    pdreg, "swap.w",
  107. X    0xffc0, 0x4840, lonel, ppea,  "pea",
  108. X    0xfff8, 0x4880, l1,    pdreg, "ext.w",
  109. X    0xfff8, 0x48c0, l1,    pdreg, "ext.l",
  110. X    0xfb80, 0x4880, lmvml, pmvml, 0,
  111. X    0xffc0, 0x4ac0, lonew, ppea,  "tas",
  112. X    0xff00, 0x4a00, lone,  pone,  "tst",
  113. X    0xfff0, 0x4e40, l1,    ptrap, 0,
  114. X    0xfff8, 0x4e50, l2,    plink, 0,
  115. X    0xfff8, 0x4e58, l1,    pareg, "unlk\t%s",
  116. X    0xfff8, 0x4e60, l1,    pareg, "mov.l\t%s,%%usp",
  117. X    0xfff8, 0x4e68, l1,    pareg, "mov.l\t%%usp,%s",
  118. X    0xffff, 0x4e70, l1,    pareg, "reset",
  119. X    0xffff, 0x4e71, l1,    pareg, "nop",
  120. X    0xffff, 0x4e72, l2,    pstop, 0,
  121. X    0xffff, 0x4e73, el1,   pareg, "rte",
  122. X    0xffff, 0x4e75, el1,   pareg, "rts",
  123. X    0xffff, 0x4e76, l1,    pareg, "trapv",
  124. X    0xffff, 0x4e77, el1,   pareg, "rtr",
  125. X    0xfffe, 0x4e7a, l2,    pmovc, 0,
  126. X    0xffc0, 0x4e80, jj,    ppea,  "jsr",
  127. X    0xffc0, 0x4ec0, jj,    ppea,  "jmp",
  128. X    0xf1c0, 0x4180, lonew, podreg,"chk",
  129. X    0xf1c0, 0x41c0, lonel, plea,  0,
  130. X    0xf0f8, 0x50c8, lcbch, pdbcc, 0,
  131. X    0xf0c0, 0x50c0, lonew, pscc,  0,
  132. X    0xf100, 0x5000, lone,  pqu,   "add",
  133. X    0xf100, 0x5100, lone,  pqu,   "sub",
  134. X    0xf100, 0x7000, l1,    pmqu,  0,
  135. X    0xf1c0, 0x80c0, lonew, podreg,"divu",
  136. X    0xf1c0, 0x81c0, lonew, podreg,"divs",
  137. X    0xf1f0, 0x8100, l1,    ptreg, "sbcd",
  138. X    0xf000, 0x8000, loone, pomode,"or",
  139. X    0xf1f0, 0x9100, l1,    ptreg, "subx.b",
  140. X    0xf1f0, 0x9140, l1,    ptreg, "subx.w",
  141. X    0xf1f0, 0x9180, l1,    ptreg, "subx.l",
  142. X    0xf000, 0x9000, loone, pomode,"sub",
  143. X    0xf1f8, 0xb108, l1,    pcmpm, "cmp.b",        /* CMPM    */
  144. X    0xf1f8, 0xb148, l1,    pcmpm, "cmp.w",        /* CMPM    */
  145. X    0xf1f8, 0xb188, l1,    pcmpm, "cmp.l",        /* CMPM    */
  146. X    0xf100, 0xb000, loone, pomode,"cmp",
  147. X    0xf1c0, 0xb1c0, loone, pomode,"cmp",
  148. X    0xf100, 0xb100, loone, pomode,"eor",
  149. X    0xf1c0, 0xc0c0, lonew, podreg,"mulu",
  150. X    0xf1c0, 0xc1c0, lonew, podreg,"muls",
  151. X    0xf1f0, 0xc100, l1,    ptreg, "abcd",
  152. X    0xf130, 0xc100, l1,    pexg,  0,
  153. X    0xf000, 0xc000, loone, pomode,"and",
  154. X    0xf1f0, 0xd100, l1,    ptreg, "addx.b",
  155. X    0xf1f0, 0xd140, l1,    ptreg, "addx.w",
  156. X    0xf1f0, 0xd180, l1,    ptreg, "addx.l",
  157. X    0xf000, 0xd000, loone, pomode,"add",
  158. X    0xf8c0, 0xe0c0, lonew, pmshf,  0,
  159. X    0xf000, 0xe000, l1,    pshf,   0,
  160. X    0
  161. X};
  162. X
  163. Xchar    *areg[] = { "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp"};
  164. Xchar    *cclist[] = { "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs",
  165. X            "pl", "mi", "ge", "lt", "gt", "le"};
  166. X    
  167. Xchar    *shtype[] = { "as", "ls", "rox", "ro" };
  168. Xchar    *bittyp[] = { "tst", "chg", "clr", "set" };
  169. X
  170. Xchar    *creg[] = { "%sfc", "%dfc", "%usp", "%vbr" };
  171. X
  172. Xint swbegflg = 0;
  173. X
  174. X/*
  175. X *    Length functions.
  176. X */
  177. X
  178. Xint    l1()
  179. X{
  180. X    return    1;
  181. X}
  182. X
  183. Xint    l2()
  184. X{
  185. X    return    2;
  186. X}
  187. X
  188. Xint    el1(te)
  189. Xt_entry    *te;
  190. X{
  191. X    te->t_bchtyp = T_UNBR;
  192. X    return    1;
  193. X}
  194. X
  195. Xint    lea(instr, size, pos)
  196. Xunsigned  instr, size;
  197. Xlong    pos;
  198. X{
  199. X    switch  ((instr >> 3) & 0x7)  {
  200. X    case  0:
  201. X    case  1:
  202. X    case  2:
  203. X    case  3:
  204. X    case  4:
  205. X        return    1;
  206. X    case  5:
  207. X    case  6:
  208. X        return    2;
  209. X    default:
  210. X        switch  (instr & 0x7)  {
  211. X        case  0:
  212. X        case  2:
  213. X        case  3:
  214. X            return    2;
  215. X        case  1:
  216. X            mkdref(pos, size);
  217. X            return    3;
  218. X        case  4:
  219. X            if  (size > 2)
  220. X                return    3;
  221. X            return    2;
  222. X        default:
  223. X            return    0;
  224. X        }
  225. X    }
  226. X}
  227. X
  228. X/*
  229. X *    Lengths of move instructions.
  230. X */
  231. X
  232. Xint    lmove(te, pos)
  233. Xt_entry    *te;
  234. Xlong    pos;
  235. X{
  236. X    register  unsigned  tc  =  te->t_contents;
  237. X    unsigned  sz  =  1;
  238. X    int    lng, lng2;
  239. X    
  240. X    lng  = tc & 0xf000;
  241. X    if  (lng == 0x3000)
  242. X        sz = 2;
  243. X    else  if  (lng == 0x2000)
  244. X        sz = 4;
  245. X    
  246. X    if  ((lng = lea(tc, sz, pos+2)) <= 0)
  247. X        return    0;
  248. X    lng2 = lea(((tc>>3) & 0x38) | ((tc>>9) & 0x7), sz, pos+lng+lng);
  249. X    if  (lng2 <= 0)
  250. X        return    0;
  251. X    return    lng + lng2 - 1;
  252. X}
  253. X
  254. X/*
  255. X *    Lengths for conditional branches and dbcc instructions.
  256. X */
  257. X
  258. Xint    lcbch(te, pos)
  259. Xt_entry    *te;
  260. Xlong    pos;
  261. X{
  262. X    unsigned  tc  =  te->t_contents;
  263. X    long    dest  =  pos + 2;
  264. X    int    res   =  2;
  265. X    
  266. X    if  ((tc & 0xf000) == 0x5000  ||  (tc & 0xff) == 0)
  267. X        dest += (short)gettw(&mainfile, pos+2, R_WORD);
  268. X    else  {
  269. X        dest += (char) tc;
  270. X        res = 1;
  271. X    }
  272. X     if ( dest < 0x290000 && (dest < mainfile.ef_tbase 
  273. X         || dest >= mainfile.ef_tbase+mainfile.ef_tsize 
  274. X         || (dest & 1) != 0 ))
  275. X         return 0;        /* Illegal branch destination */
  276. X    if  ((tc & 0xff00) == 0x6000)
  277. X        te->t_bchtyp = T_UNBR;
  278. X    else  if  ((tc & 0xff00) == 0x6100)
  279. X        te->t_bchtyp = T_JSR;
  280. X    else
  281. X        te->t_bchtyp = T_CONDBR;
  282. X
  283. X     if ( dest < 0x290000 && ((te->t_relsymb = textlab(dest, pos)) == NULL )) {
  284. X         te->t_bchtyp = T_NOBR;/* Branch to a continuation */
  285. X         return 0;
  286. X     }
  287. X    return    res;
  288. X}
  289. X
  290. Xint    jj(te, pos)
  291. Xt_entry    *te;
  292. Xlong    pos;
  293. X{
  294. X    unsigned  tc  =  te->t_contents;
  295. X    t_entry    nextl;
  296. X     long dest;
  297. X    
  298. X    te->t_bchtyp = (tc & 0x40)? T_UNBR: T_JSR;
  299. X    if ((tc & 0x3f) == 0x39) {
  300. X        gette(&mainfile, pos+2, &nextl);
  301. X        if  (nextl.t_relsymb == NULL)  {
  302. X             dest = gettw(&mainfile, pos + 2, R_LONG );
  303. X             if ( dest < 0x290000 && (dest < mainfile.ef_tbase
  304. X                 || dest >= mainfile.ef_tbase+mainfile.ef_tsize
  305. X                 || (dest & 1) != 0 ))
  306. X                 return 0;    /* Illegal branch destination */
  307. X             if ( dest < 0x290000 && ( nextl.t_relsymb = textlab(dest, pos) ) == NULL )
  308. X             return 0;    /* Branch to a continuation */
  309. X            putte(&mainfile, pos+2, &nextl);
  310. X        }
  311. X        te->t_relsymb = nextl.t_relsymb;    /*  Easy ref  */
  312. X    }
  313. X    else if ((tc & 0x3f) == 0x3a) {
  314. X        gette(&mainfile, pos+2, &nextl);
  315. X        if  (nextl.t_relsymb == NULL)  {
  316. X            dest = pos+2+ (int)((short) 
  317. X                gettw(&mainfile, pos + 2, R_WORD ));
  318. X             if ( dest < 0x290000 && (dest < mainfile.ef_tbase
  319. X                 || dest >= mainfile.ef_tbase+mainfile.ef_tsize
  320. X                 || (dest & 1) != 0 ))
  321. X            return    lea(tc, 4, pos+2);
  322. X             if (dest < 0x290000 && 
  323. X                (nextl.t_relsymb = textlab(dest, pos)) == NULL)
  324. X                 return 0;    /* Branch to a continuation */
  325. X            putte(&mainfile, pos+2, &nextl);
  326. X        }
  327. X        te->t_relsymb = nextl.t_relsymb;    /*  Easy ref  */
  328. X    }
  329. X    return    lea(tc, 4, pos+2);
  330. X}
  331. X
  332. Xint    limed(te, pos)
  333. Xt_entry    *te;
  334. Xlong    pos;
  335. X{
  336. X    unsigned  tc  =  te->t_contents;
  337. X    int    lng;
  338. X    
  339. X    /*
  340. X     *    Specifically exclude byte address register operands,
  341. X     *    and ones which have lengths of 3.
  342. X     */
  343. X
  344. X    if  ((tc & 0xf8) == 0x08)
  345. X        return  0;
  346. X    
  347. X    if  ((tc & 0xc0) >= 0x80)  {
  348. X        if  (tc & 0x40)
  349. X            return  0;
  350. X        lng = lea(tc, 4, pos+6);
  351. X        if  (lng > 0)
  352. X            lng += 2;
  353. X    }
  354. X    else  {
  355. X        lng = lea(tc, (unsigned)((tc & 0xc0)?2:1), pos+4);
  356. X        if  (lng > 0)
  357. X            lng++;
  358. X    }
  359. X    return    lng;
  360. X}
  361. X
  362. Xint    lsbit(te, pos)
  363. Xt_entry    *te;
  364. Xlong    pos;
  365. X{
  366. X    int    lng = lea(te->t_contents, 1, pos+4);
  367. X    
  368. X    if  (lng > 0)
  369. X        lng++;
  370. X    return    lng;
  371. X}
  372. X
  373. Xint    lmvml(te, pos)
  374. Xt_entry    *te;
  375. Xlong    pos;
  376. X{
  377. X    int    lng = lea(te->t_contents,
  378. X            (unsigned)(te->t_contents&0x40? 4:2), pos+4);
  379. X    
  380. X    if  (lng > 0)
  381. X        lng++;
  382. X    return    lng;
  383. X}
  384. X
  385. X/*
  386. X *    Length depends on bits 6 and 7 of instruction.
  387. X */
  388. X
  389. Xint    lone(te, pos)
  390. Xt_entry    *te;
  391. Xlong    pos;
  392. X{
  393. X    unsigned  tc  =  te->t_contents;
  394. X    
  395. X    return    lea(tc, 1 << ((tc >> 6) & 3), pos+2);
  396. X}
  397. X
  398. X/*
  399. X *    Length depends on bits 6-8 of instruction.
  400. X */
  401. X
  402. Xint    loone(te, pos)
  403. Xt_entry    *te;
  404. Xlong    pos;
  405. X{
  406. X    unsigned  tc  =  te->t_contents;
  407. X    
  408. X    switch  ((tc >> 6) & 7)  {
  409. X    case  0:
  410. X    case  4:
  411. X        return    lea(tc, 1, pos+2);
  412. X    case  1:
  413. X    case  3:
  414. X    case  5:
  415. X        return  lea(tc, 2, pos+2);
  416. X    case  2:
  417. X    case  6:
  418. X    case  7:
  419. X        return    lea(tc, 4, pos+2);
  420. X    }
  421. X    /*NOTREACHED*/
  422. X}
  423. X
  424. Xint    lonew(te, pos)
  425. Xt_entry    *te;
  426. Xlong    pos;
  427. X{
  428. X    if (te->t_contents == 0x4afc) { /* swbeg ... */
  429. X        swbegflg++;
  430. X        return (2 + gettw(&mainfile,pos+2,2));
  431. X    }
  432. X    return    lea(te->t_contents, 2, pos+2);
  433. X}
  434. X
  435. Xint    lonel(te, pos)
  436. Xt_entry    *te;
  437. Xlong    pos;
  438. X{
  439. X    return    lea(te->t_contents, 4, pos+2);
  440. X}
  441. X
  442. X/*
  443. X *    Print routines.
  444. X */
  445. X
  446. X/*
  447. X * print out small integers in decamil notation, all others in hex.
  448. X */
  449. X
  450. Xvoid prind(n)
  451. Xunsigned short n;
  452. X{
  453. X    if ((short) n > -128 && (short) n < 128)
  454. X        (void) printf("%d", (long) ((short) n));
  455. X    else
  456. X        (void) printf("0x%x",(unsigned long) n);
  457. X}
  458. X   
  459. Xint    findleng(tc)
  460. Xunsigned  tc;
  461. X{
  462. X    switch  ((tc >> 6) & 3)  {
  463. X    case  0:
  464. X        return    'b';
  465. X    case  1:
  466. X        return    'w';
  467. X    default:
  468. X        return    'l';
  469. X}
  470. X}
  471. X
  472. X/* print @(0x4,d0.l) */
  473. Xvoid    piword(reg,disp)
  474. Xchar * reg;
  475. Xunsigned  disp;
  476. X{
  477. Xint    szc;
  478. X
  479. X    (void) printf("%d(%s,", disp & 0xff, reg);
  480. X    if  (disp & 0x8000) {
  481. X        (void) fputs(areg[(disp >> 12) & 0x7]);
  482. X        (void) putchar('.');
  483. X    }
  484. X    else
  485. X        (void) printf("%%d%d.", (disp >> 12) & 0x7);
  486. X    (void) putchar((disp & (1 << 10)) ? 'l' :'w');
  487. X    (void) putchar(')');
  488. X}
  489. X
  490. Xextern struct    commit    abstab;
  491. X
  492. Xvoid    paddr(pos)
  493. Xlong    pos;
  494. X{
  495. X    t_entry    tent;
  496. X    symbol    symb;
  497. X
  498. X    gette(&mainfile, pos, &tent);
  499. X    if  (tent.t_relsymb != NULL)  {
  500. X        symb = tent.t_relsymb;
  501. X        if  (symb->s_lsymb != 0)
  502. X            (void) printf("L%%%u", symb->s_lsymb);
  503. X        else
  504. X            (void) fputs(symb->s_name, stdout);
  505. X        if  (tent.t_reldisp != 0)
  506. X            (void) printf("+0x%x", tent.t_reldisp);
  507. X        return;
  508. X    }
  509. X    if ((pos = gettw(&mainfile, pos, R_LONG)) >= 0x290000)
  510. X     {
  511. X        register int i;
  512. X        for (i=0; i < abstab.c_int; i++)
  513. X            if (abstab.c_symb[i]->s_value == pos)
  514. X         {         
  515. X            (void) fputs(abstab.c_symb[i]->s_name, stdout);
  516. X            return;
  517. X         }
  518. X     }
  519. X    (void) printf("0x%x", pos);
  520. X}
  521. X
  522. Xint    prea(ea, pos, sz)
  523. Xunsigned  ea, sz;
  524. Xlong    pos;            /*  Address of previous word to extn  */
  525. X{
  526. X    unsigned  reg  =  ea & 0x7;
  527. X    long    disp;
  528. X    t_entry    tent;
  529. X    
  530. X    pos += 2;
  531. X    
  532. X    switch  ((ea >> 3) & 0x7)  {
  533. X    case  0:
  534. X        (void) printf("%%d%d", reg);
  535. X        return    0;
  536. X    case  1:
  537. X        (void) fputs(areg[reg], stdout);
  538. X        return    0;
  539. X    case  2:
  540. X        (void) printf("(%s)", areg[reg]);
  541. X        return    0;
  542. X    case  3:
  543. X        (void) printf("(%s)+", areg[reg]);
  544. X        return    0;
  545. X    case  4:
  546. X        (void) printf("-(%s)", areg[reg]);
  547. X        return    0;
  548. X    case  5:
  549. X        disp = gettw(&mainfile, pos, R_WORD);
  550. X        (void) prind(disp);
  551. X        (void) printf("(%s)", areg[reg]);
  552. X        return    2;
  553. X    case  6:
  554. X        piword(areg[reg], (unsigned) gettw(&mainfile, pos, R_WORD));
  555. X        return    2;
  556. X    default:
  557. X        switch  (reg)  {
  558. X        case  0:
  559. X            disp = gettw(&mainfile, pos, R_WORD);
  560. X            (void) prind(disp);
  561. X            (void) putchar('.');
  562. X            (void) putchar('w');
  563. X            return    2;
  564. X        case  1:
  565. X            paddr(pos);
  566. X            return    4;
  567. X        case  2:{
  568. X            symbol symb;
  569. X            register int addr;
  570. X            disp = 
  571. X                ((short) gettw(&mainfile, pos, R_WORD));
  572. X              if ((addr=pos+disp) < 0  ||  
  573. X                addr-mainfile.ef_tbase > mainfile.ef_tsize ||
  574. X                (addr & 1) != 0)  
  575. X                goto skiplabs;
  576. X            gette(&mainfile, addr, &tent);
  577. X            if  (tent.t_relsymb != NULL)  {
  578. X                symb = tent.t_relsymb;
  579. X            }
  580. X            else if (tent.t_lab != NULL) {
  581. X                symb = tent.t_lab;
  582. X            }
  583. X            else {
  584. X        skiplabs:
  585. X                (void) prind(disp);
  586. X                (void) fputs("(%pc)", stdout);
  587. X                return    2;
  588. X            }
  589. X            if  (symb->s_lsymb != 0)
  590. X                (void) printf("L%%%u", symb->s_lsymb);
  591. X            else
  592. X                (void) fputs(symb->s_name, stdout);
  593. X            if  (tent.t_reldisp != 0)
  594. X                (void) printf("+0x%x", tent.t_reldisp);
  595. X            return 2;
  596. X            }
  597. X        case  3:
  598. X            piword("%pc", (unsigned)gettw(&mainfile, pos, R_WORD));
  599. X            return    2;
  600. X        case  4:
  601. X            (void) putchar('&');
  602. X            if  (sz < 4)
  603. X                (void) prind(gettw(&mainfile, pos, R_WORD));
  604. X            else
  605. X                paddr(pos);
  606. X            return    sz;
  607. X        default:
  608. X            (void) fprintf(stderr, "Funny mode\n");
  609. X            exit(220);
  610. X        }
  611. X    }
  612. X    /*NOTREACHED*/
  613. X}
  614. X    
  615. Xint    pmove(te, pos)
  616. Xt_entry    *te;
  617. Xlong    pos;
  618. X{
  619. X    unsigned  sz  =  2;
  620. X    unsigned  tc  =  te->t_contents;
  621. X    
  622. X    (void) printf("mov%s\t", optab[te->t_iindex].prarg);
  623. X    
  624. X    if  ((tc & 0xf000) == 0x2000)
  625. X        sz = 4;
  626. X    
  627. X    pos += prea(tc, pos, sz);
  628. X    (void) putchar(',');
  629. X    (void) prea(((tc >> 9) & 0x7) | ((tc >> 3) & 0x38), pos, sz);
  630. X}
  631. X
  632. Xint    pcbch(te)
  633. Xt_entry    *te;
  634. X{
  635. X    int    cc = ((te->t_contents >> 8) & 0xf) - 2;
  636. X    char    *msg;
  637. X    register  symbol  ts;
  638. X    
  639. X    if  (cc < 0)
  640. X        msg = cc < -1? "ra": "sr";
  641. X    else
  642. X        msg = cclist[cc];
  643. X    (void) printf("b%s", msg);
  644. X/* this specifically requests that 8 bit addressing be used, 
  645. X        but the unixpc assembler will do this automatically.    
  646. X    if  (te->t_lng < 2) {
  647. X        (void) putchar('.');
  648. X        (void) putchar('b');
  649. X    }
  650. X*/
  651. X    ts = te->t_relsymb;
  652. X    if  (ts->s_lsymb != 0)
  653. X        (void) printf("\tL%%%u", ts->s_lsymb);
  654. X    else
  655. X    {
  656. X        (void) putchar('\t');
  657. X        (void) fputs(ts->s_name, stdout);
  658. X    }
  659. X}
  660. X
  661. Xint    pdbcc(te)
  662. Xt_entry    *te;
  663. X{
  664. X    unsigned  tc  =  te->t_contents;
  665. X    int    cc = ((tc >> 8) & 0xf) - 2;
  666. X    char    *msg;
  667. X    register  symbol  ts;
  668. X    
  669. X    if  (cc < 0)
  670. X        msg = cc < -1? "t": "f";
  671. X    else
  672. X        msg = cclist[cc];
  673. X    ts = te->t_relsymb;
  674. X    (void) printf("db%s\t%%d%d,", msg, tc & 0x7);
  675. X    if  (ts->s_lsymb)
  676. X        (void) printf("L%%%u", ts->s_lsymb);
  677. X    else
  678. X        (void) fputs(ts->s_name, stdout);
  679. X}
  680. X
  681. Xint    pscc(te, pos)
  682. Xt_entry    *te;
  683. Xlong    pos;
  684. X{
  685. X    unsigned  tc  =  te->t_contents;
  686. X    int    cc = ((tc >> 8) & 0xf) - 2;
  687. X    char    *msg;
  688. X    
  689. X    if  (cc < 0)
  690. X        msg = cc < -1? "t": "f";
  691. X    else
  692. X        msg = cclist[cc];
  693. X    (void) printf("s%s\t", msg);
  694. X    (void) prea(tc, pos, 1);
  695. X}
  696. X
  697. Xint    pcs(te, pos)
  698. Xt_entry    *te;
  699. Xlong    pos;
  700. X{
  701. X    long    disp  =  gettw(&mainfile, pos+2, R_WORD);
  702. X    
  703. X    (void) fputs(optab[te->t_iindex].prarg, stdout);
  704. X    if  ((te->t_contents & 0xc0) == 0){
  705. X         (void) fputs(".b\t&", stdout);
  706. X        (void) prind(disp);
  707. X        (void) fputs(",%cc", stdout);
  708. X    }
  709. X    else {
  710. X        (void) fputs(".w\t&", stdout);
  711. X        (void) prind(disp);
  712. X        (void) fputs(",%sr", stdout);
  713. X    }
  714. X}
  715. X
  716. Xint    pmovc(te, pos)
  717. Xt_entry    *te;
  718. Xlong    pos;
  719. X{
  720. X    int    disp = gettw(&mainfile, pos+2, R_WORD);
  721. X    int    ctrl = ((disp >> 10) & 2) | (disp & 1);
  722. X
  723. X    (void) fputs("movc\t", stdout);
  724. X    if  ((te->t_contents & 1) == 0)
  725. X        (void) fputs(creg[ctrl], stdout);
  726. X    if  (disp & 0x8000)
  727. X    {
  728. X        (void) fputs(areg[(disp >> 12) & 7], stdout);
  729. X        (void) putchar(',');
  730. X    }
  731. X    else
  732. X        (void) printf("%%d%d,", disp >> 12);
  733. X    if  (te->t_contents & 1)
  734. X        (void) fputs(creg[ctrl], stdout);
  735. X}
  736. X
  737. Xint    pimed(te, pos)
  738. Xt_entry    *te;
  739. Xlong    pos;
  740. X{
  741. X    int    sz = findleng(te->t_contents);
  742. X
  743. X    /* we need to swith the operands to compare instrucions. */
  744. X    if (strcmp (optab[te->t_iindex].prarg, "cmp")) {
  745. X        (void) printf("%s.%c\t&", optab[te->t_iindex].prarg, sz);
  746. X        if  (sz == 'l')  {
  747. X            paddr(pos+2);
  748. X            (void) putchar(',');
  749. X            (void) prea(te->t_contents, pos+4, 4);
  750. X        }
  751. X        else  {
  752. X            (void) prind(gettw(&mainfile, pos+2, R_WORD));
  753. X            (void) putchar(',');
  754. X            (void) prea(te->t_contents, pos+2, 2);
  755. X        }
  756. X    }
  757. X    else {
  758. X        (void) printf("%s.%c\t", optab[te->t_iindex].prarg, sz);
  759. X        if  (sz == 'l')  {
  760. X            (void) prea(te->t_contents, pos+4, 4);
  761. X            (void) putchar(',');
  762. X            (void) putchar('&');
  763. X            paddr(pos+2);
  764. X        }
  765. X        else  {
  766. X            (void) prea(te->t_contents, pos+2, 2);
  767. X            (void) putchar(',');
  768. X            (void) putchar('&');
  769. X            (void) prind(gettw(&mainfile, pos+2, R_WORD));
  770. X        }
  771. X    }
  772. X}
  773. X
  774. Xint    pmovp(te, pos)
  775. Xt_entry    *te;
  776. Xlong    pos;
  777. X{
  778. X    unsigned  tc  =  te->t_contents;
  779. X    long    disp  =  gettw(&mainfile, pos+2, R_WORD);
  780. X    int    dreg = tc >> 9;
  781. X    char    *ar = areg[tc & 0x7];
  782. X    
  783. X    (void) fputs("movp.", stdout);
  784. X    if  (tc & (1 << 6))
  785. X        (void) putchar('l');
  786. X    else
  787. X        (void) putchar('w');
  788. X
  789. X    if  (tc & (1 << 7)) {
  790. X        (void) printf("\t%%d%d,", dreg);
  791. X        (void) prind(disp);
  792. X        (void) printf("(%s)", ar);
  793. X    }
  794. X    else {
  795. X        (void) putchar('\t');
  796. X        (void) prind(disp);
  797. X        (void) printf("(%s),%%d%d", ar, dreg);
  798. X    }
  799. X}
  800. X
  801. Xint    psbit(te, pos)
  802. Xt_entry    *te;
  803. Xlong    pos;
  804. X{
  805. X    unsigned  tc  =  te->t_contents;
  806. X    
  807. X    (void) printf("b%s\t&%d,", bittyp[(tc >> 6) & 0x3], gettw(&mainfile, pos+2, R_WORD));
  808. X    (void) prea(tc, pos+2, 1);
  809. X}
  810. X
  811. X/*ARGSUSED*/
  812. Xint    pstop(te, pos)
  813. Xt_entry    *te;
  814. Xlong    pos;
  815. X{
  816. X    (void) printf("stop\t&0x%x", gettw(&mainfile, pos+2, R_WORD));
  817. X}
  818. X
  819. Xint    pdbit(te, pos)
  820. Xt_entry    *te;
  821. Xlong    pos;
  822. X{
  823. X    unsigned  tc  =  te->t_contents;
  824. X    
  825. X    (void) printf("b%s\t%%d%d,", bittyp[(tc >> 6) & 0x3], (tc >> 9) & 0x7);
  826. X    (void) prea(tc, pos, 1);
  827. X}
  828. X
  829. Xint    pcs2(te, pos)
  830. Xt_entry    *te;
  831. Xlong    pos;
  832. X{
  833. X    unsigned  tc  =  te->t_contents;
  834. X    
  835. X    (void) fputs("movw\t", stdout);
  836. X    if  ((tc & 0xffc0) == 0x40c0)  {
  837. X        (void) fputs("%sr,", stdout);
  838. X        (void) prea(tc, pos, 2);
  839. X    }
  840. X    else  {
  841. X        (void) prea(tc, pos, 2);
  842. X        (void) putchar(',');
  843. X        (void) fputs(optab[te->t_iindex].prarg, stdout);
  844. X    }
  845. X}
  846. X
  847. Xint    pone(te, pos)
  848. Xt_entry    *te;
  849. Xlong    pos;
  850. X{
  851. X    unsigned  tc  =  te->t_contents;
  852. X    int    sz = findleng(tc);
  853. X    
  854. X    (void) printf("%s.%c\t", optab[te->t_iindex].prarg, sz);
  855. X    (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  856. X}
  857. X
  858. Xint    ppea(te, pos)    /*  nbcd, pea, tas, jmp, jsr  */
  859. Xt_entry    *te;
  860. Xlong    pos;
  861. X{
  862. X    if (! strncmp(optab[te->t_iindex].prarg, "tas") && 
  863. X        (te->t_contents & 0x3f) == 0x3c) {
  864. X        symbol symb;
  865. X        t_entry tstr;
  866. X        int counter = te->t_lng -2;
  867. X        int offset = (pos += 4);
  868. X        int dest;
  869. X        char * sw_label;
  870. X
  871. X        (void) printf("swbeg\t&%d\n", counter);
  872. X
  873. X        symb = textlab(pos, pos);
  874. X        printf("%s:\n", sw_label = symb->s_name);
  875. X
  876. X        while (counter--) {
  877. X            gette(&mainfile, pos, &tstr);
  878. X            dest = tstr.t_contents + offset;
  879. X             if (tstr.t_contents > 0 &&
  880. X                dest < 0x290000 && 
  881. X                ! (dest < mainfile.ef_tbase
  882. X                  || dest >= mainfile.ef_tbase+mainfile.ef_tsize
  883. X                  || (dest & 1) != 0 )) {
  884. X                if (symb = textlab(dest,offset))
  885. X                    printf("\tshort\t%s-%s\n", 
  886. X                        symb->s_name,sw_label);
  887. X                else
  888. X                    printf("\tshort\t0x%x\t# Can't label destination.\n", 
  889. X                            tstr.t_contents);
  890. X            }
  891. X            else 
  892. X                printf("\tshort\t0x%x\t# Illegal address\n", 
  893. X                        tstr.t_contents);
  894. X            pos += 2;
  895. X        }
  896. X    }
  897. X    else {
  898. X        (void) fputs(optab[te->t_iindex].prarg, stdout);
  899. X        (void) putchar('\t');
  900. X        (void) prea(te->t_contents, pos, (unsigned)(te->t_lng>2?4:2));
  901. X    }
  902. X}
  903. X
  904. X
  905. Xint    plea(te, pos)
  906. Xt_entry    *te;
  907. Xlong    pos;
  908. X{
  909. X    (void) fputs("lea\t", stdout);
  910. X    (void) prea(te->t_contents, pos, 4);
  911. X    (void) putchar(',');
  912. X    (void) fputs(areg[(te->t_contents >> 9) & 0x7], stdout);
  913. X}
  914. X
  915. Xint    pdreg(te)
  916. Xt_entry    *te;
  917. X{
  918. X    (void) printf("%s\t%%d%d", optab[te->t_iindex].prarg, te->t_contents & 7);
  919. X}
  920. X
  921. X
  922. Xint    pmvml(te, pos)
  923. Xt_entry    *te;
  924. Xlong    pos;
  925. X{
  926. X    unsigned  tc  =  te->t_contents;
  927. X    register  unsigned  dw  =  gettw(&mainfile, pos+2, R_WORD);
  928. X    unsigned  sz = 4;
  929. X    int    sc = 'l';
  930. X    register  int    i;
  931. X    register  unsigned  bit;
  932. X    
  933. X    (void) fputs("movm.", stdout);
  934. X    if  ((tc & 0x40) == 0)  {
  935. X        sc = 'w';
  936. X        sz = 2;
  937. X    }
  938. X
  939. X    (void) putchar(sc);    
  940. X    (void) putchar('\t');
  941. X
  942. X    if  (tc & 0x400)  {
  943. X        (void) prea(tc, pos+2, sz);
  944. X        (void) printf(",&0x%x", dw);
  945. X    }
  946. X    else  {
  947. X        (void) printf("&0x%x,", dw);
  948. X        (void) prea(tc, pos+2, sz);
  949. X    }
  950. X    
  951. X    (void) printf("\t#\t");
  952. X    
  953. X    if  ((tc & 0x38) == 0x20)  {
  954. X        bit = 0x8000;
  955. X        for  (i = 0;  i < 8;  i++)  {
  956. X            if  (dw & bit)
  957. X                (void) printf(" %%d%d", i);
  958. X            bit >>= 1;
  959. X        }
  960. X        for  (i = 0;  i < 8;  i++)  {
  961. X            if  (dw & bit) {
  962. X                    (void) putchar(' ');
  963. X                (void) fputs(areg[i], stdout);
  964. X            }
  965. X            bit >>= 1;
  966. X        }
  967. X    }
  968. X    else  {
  969. X        bit = 1;
  970. X        for  (i = 0;  i < 8;  i++)  {
  971. X            if  (dw & bit)
  972. X                (void) printf(" %%d%d", i);
  973. X            bit <<= 1;
  974. X        }
  975. X        for  (i = 0;  i < 8;  i++)  {
  976. X            if  (dw & bit) {
  977. X                (void) putchar(' ');
  978. X                (void) fputs(areg[i], stdout);
  979. X            }
  980. X            bit <<= 1;
  981. X        }
  982. X    }
  983. X}
  984. X
  985. Xint    ptrap(te)
  986. Xt_entry    *te;
  987. X{
  988. X    (void) printf("trap\t&%d", te->t_contents & 0xf);
  989. X}
  990. X
  991. Xint    plink(te, pos)
  992. Xt_entry    *te;
  993. Xlong    pos;
  994. X{
  995. X    (void) printf("link\t%s,&%d", areg[te->t_contents & 0x7],
  996. X                gettw(&mainfile, pos+2, R_WORD));
  997. X}
  998. X
  999. X
  1000. Xint    pareg(te)
  1001. Xt_entry    *te;
  1002. X{
  1003. X    (void) printf(optab[te->t_iindex].prarg, areg[te->t_contents & 0x7]);
  1004. X}
  1005. X
  1006. Xint    podreg(te, pos)
  1007. Xt_entry    *te;
  1008. Xlong    pos;
  1009. X{
  1010. X    unsigned  tc  =  te->t_contents;
  1011. X    
  1012. X    (void) printf("%s\t", optab[te->t_iindex].prarg);
  1013. X    (void) prea(tc, pos, 2);
  1014. X    (void) printf(",%%d%d", (tc >> 9) & 0x7);
  1015. X}
  1016. X
  1017. Xint    pqu(te, pos)
  1018. Xt_entry    *te;
  1019. Xlong    pos;
  1020. X{
  1021. X    unsigned  tc  =  te->t_contents;
  1022. X    int    sz  =  findleng(tc);
  1023. X    int    amt = (tc >> 9) & 0x7;
  1024. X    
  1025. X    if  (amt == 0)
  1026. X        amt = 8;
  1027. X    (void) printf("%s.%c\t&%d,", optab[te->t_iindex].prarg, sz, amt);
  1028. X    (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  1029. X}
  1030. X
  1031. Xint    pmqu(te)
  1032. Xt_entry    *te;
  1033. X{
  1034. X    unsigned  tc  =  te->t_contents;
  1035. X
  1036. X    (void) printf("mov.l\t&%d,%%d%d", (char)tc, (tc >> 9) & 0x7);
  1037. X}
  1038. X
  1039. Xint    ptreg(te)
  1040. Xt_entry    *te;
  1041. X{
  1042. X    register  unsigned  tc  =  te->t_contents;
  1043. X    int    rx = (tc >> 9) & 0x7;
  1044. X    int    ry = tc & 0x7;
  1045. X
  1046. X    (void) fputs(optab[te->t_iindex].prarg, stdout);
  1047. X    (void) putchar('\t');
  1048. X    if  (tc & 0x8)
  1049. X        (void) printf("-(%s),-(%s)", areg[ry], areg[rx]);
  1050. X    else
  1051. X        (void) printf("%%d%d,%%d%d", ry, rx);
  1052. X}
  1053. X
  1054. Xint    pcmpm(te)
  1055. Xt_entry    *te;
  1056. X{
  1057. X    register  unsigned  tc  =  te->t_contents;
  1058. X
  1059. X    (void) printf("%s\t(%s)+,(%s)+", optab[te->t_iindex].prarg,
  1060. X        areg[tc & 7], areg[(tc >> 9) & 7]);
  1061. X}
  1062. X
  1063. Xint    pomode(te, pos)
  1064. Xt_entry    *te;
  1065. Xlong    pos;
  1066. X{
  1067. X    unsigned  tc  =  te->t_contents;
  1068. X    char    buf[5];
  1069. X    int    sz;
  1070. X    int    reg = (tc >> 9) & 7;
  1071. X
  1072. X    buf[0] = '\0';
  1073. X    
  1074. X    switch  ((tc >> 6) & 7)  {
  1075. X    case  0:
  1076. X        sz = 'b';
  1077. X        goto  toreg;
  1078. X    case  1:
  1079. X        sz = 'w';
  1080. X        goto  toreg;
  1081. X    case  2:
  1082. X        sz = 'l';
  1083. X    toreg:
  1084. X         (void) sprintf(buf, "%%d%d", reg);
  1085. X        goto printaft;
  1086. X    case  3:
  1087. X        sz = 'w';
  1088. X        goto  toareg;
  1089. X    case  7:
  1090. X        sz = 'l';
  1091. X    toareg:
  1092. X        (void) sprintf(buf, "%s", areg[reg]);
  1093. X    printaft:
  1094. X        if (strcmp("cmp", optab[te->t_iindex].prarg)) {
  1095. X            (void) printf("%s.%c\t", optab[te->t_iindex].prarg,sz);
  1096. X            (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  1097. X            (void) putchar(',');
  1098. X            (void) fputs(buf, stdout);
  1099. X        }
  1100. X        else {
  1101. X            (void) printf("%s.%c\t%s,", optab[te->t_iindex].prarg,
  1102. X                            sz, buf);
  1103. X            (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  1104. X        }
  1105. X        break;
  1106. X    case  4:
  1107. X        sz = 'b';
  1108. X        goto  frreg;
  1109. X    case  5:
  1110. X        sz = 'w';
  1111. X        goto  frreg;
  1112. X    case  6:
  1113. X        sz = 'l';
  1114. X    frreg:
  1115. X        (void) sprintf(buf, "%%d%d", reg);
  1116. X        if (strcmp("cmp", optab[te->t_iindex].prarg)) {
  1117. X            (void) printf("%s.%c\t%s,", optab[te->t_iindex].prarg, 
  1118. X                    sz, buf);
  1119. X            (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  1120. X        }
  1121. X        else {
  1122. X            (void) printf("%s.%c\t", optab[te->t_iindex].prarg,sz);
  1123. X            (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  1124. X            (void) putchar(',');
  1125. X            (void) fputs(buf, stdout);
  1126. X        }
  1127. X    }
  1128. X}
  1129. X
  1130. Xint    pexg(te)
  1131. Xt_entry    *te;
  1132. X{
  1133. X    unsigned  tc  =  te->t_contents;
  1134. X    int    r1 = (tc >> 9) & 7, r2 = tc & 7;
  1135. X
  1136. X    (void) printf("exg\t");
  1137. X    
  1138. X    if  ((tc & 0x00f8) == 0x0048)
  1139. X    {
  1140. X        (void) fputs(areg[r1], stdout);
  1141. X        (void) putchar(',');
  1142. X    }
  1143. X    else
  1144. X        (void) printf("%%d%d,", r1);
  1145. X    if  (tc & 0x8)
  1146. X        (void) fputs(areg[r2], stdout);
  1147. X    else
  1148. X        (void) printf("%%d%d", r2);
  1149. X}
  1150. X    
  1151. Xint    pmshf(te, pos)
  1152. Xt_entry    *te;
  1153. Xlong    pos;
  1154. X{
  1155. X    unsigned  tc  =  te->t_contents;
  1156. X    
  1157. X    (void) printf("%s%c.w\t", shtype[(tc >> 9) & 3], tc & 0x100? 'l': 'r');
  1158. X    (void) prea(tc, pos, 2);
  1159. X}
  1160. X
  1161. Xint    pshf(te)
  1162. Xt_entry    *te;
  1163. X{
  1164. X    unsigned  tc  =  te->t_contents;
  1165. X    int    sz  =  findleng(tc);
  1166. X    int    disp = (tc >> 9) & 7;
  1167. X
  1168. X    (void) printf("%s%c.%c\t", shtype[(tc >> 3) & 3], tc & 0x100? 'l': 'r', sz);
  1169. X    if  (tc & 0x20)
  1170. X        (void) printf("%%d%d", disp);
  1171. X    else
  1172. X        (void) printf("&%d", disp == 0? 8: disp);
  1173. X    (void) printf(",%%d%d", tc & 7);
  1174. X}
  1175. X
  1176. X/*
  1177. X *    Find length etc of instruction.
  1178. X */
  1179. X
  1180. Xint    findinst(te, pos)
  1181. Xregister  t_entry  *te;
  1182. Xlong    pos;
  1183. X{
  1184. X    register  struct  opstr    *op;
  1185. X    unsigned  tc  =  te->t_contents;
  1186. X    int    lng = 0;
  1187. X    register  int    i;
  1188. X
  1189. X    te->t_type = T_BEGIN;
  1190. X    te->t_bchtyp = T_NOBR;
  1191. X    
  1192. X    for  (op = &optab[0];  op->mask;  op++)  {
  1193. X        if  ((tc & op->mask) == op->match)  {
  1194. X            te->t_iindex = op - optab;
  1195. X            lng = (op->opsize)(te, pos);
  1196. X            break;
  1197. X        }
  1198. X    }
  1199. X
  1200. X    for  (i = 1;  i < lng;  i++)  {
  1201. X        t_entry    ctent;
  1202. X        long    npos = pos+i+i;
  1203. X        
  1204. X        if  (npos >= endt)
  1205. X            goto  clearem;
  1206. X        gette(&mainfile, npos, &ctent);
  1207. X        if (swbegflg) {
  1208. X            ctent.t_type = T_UNKNOWN;
  1209. X            putte(&mainfile, npos, &ctent);
  1210. X        }
  1211. X        else {
  1212. X            if  (ctent.t_bdest || ctent.t_dref)  {
  1213. Xclearem:            for  (i--; i > 0; i--)  {
  1214. X                    npos = pos + i + i;
  1215. X                    gette(&mainfile, npos, &ctent);
  1216. X                    ctent.t_type = T_UNKNOWN;
  1217. X                    putte(&mainfile, npos, &ctent);
  1218. X                }
  1219. X                lng = 0;
  1220. X                goto  ginv;
  1221. X            }
  1222. X            ctent.t_type = T_CONT;
  1223. X            putte(&mainfile, npos, &ctent);
  1224. X        }
  1225. X    }
  1226. X    swbegflg = 0;
  1227. X
  1228. X    if  (lng <= 0)  {
  1229. Xginv:        te->t_vins = 0;
  1230. X        te->t_lng = 1;
  1231. X        te->t_type = T_UNKNOWN;
  1232. X        te->t_bchtyp = T_NOBR;
  1233. X    }
  1234. X    else
  1235. X        te->t_lng = lng;
  1236. X    return    lng;
  1237. X}
  1238. X
  1239. X/*
  1240. X *    Print instruction.
  1241. X */
  1242. X
  1243. Xvoid    prinst(te, pos)
  1244. Xt_entry    *te;
  1245. Xlong    pos;
  1246. X{
  1247. X    putchar('\t');
  1248. X    (optab[te->t_iindex].opprin)(te, pos);
  1249. X    putchar('\n');
  1250. X}
  1251. SHAR_EOF
  1252. chmod 0644 iset.c || echo "restore of iset.c fails"
  1253. sed 's/^X//' << 'SHAR_EOF' > libmtch.c &&
  1254. X/*
  1255. X *    SCCS:    @(#)libmtch.c    1.2    11/2/84    14:18:55
  1256. X *    Read library files.
  1257. X *
  1258. X ***********************************************************************
  1259. X *    This software is copyright of
  1260. X *
  1261. X *        John M Collins
  1262. X *        47 Cedarwood Drive
  1263. X *        St Albans
  1264. X *        Herts, AL4 0DN
  1265. X *        England            +44 727 57267
  1266. X *
  1267. X *    and is released into the public domain on the following conditions:
  1268. X *
  1269. X *        1.  No free maintenance will be guaranteed.
  1270. X *        2.  Nothing may be based on this software without
  1271. X *            acknowledgement, including incorporation of this
  1272. X *            notice.
  1273. X *
  1274. X *    Notwithstanding the above, the author welcomes correspondence and bug
  1275. X *    fixes.
  1276. X ***********************************************************************
  1277. X */
  1278. X
  1279. X#include <stdio.h>
  1280. X#include <fcntl.h>
  1281. X#include <string.h>
  1282. X#include <a.out.h>
  1283. X#include <ar.h>
  1284. X#include <setjmp.h>
  1285. X#include <ldfcn.h>
  1286. X#include "unc.h"
  1287. X
  1288. Xlong    atol();
  1289. Xlong    lseek();
  1290. Xvoid    bfopen(), bfclose(), nomem();
  1291. Xvoid    rrell2(), markmatch();
  1292. Xchar    *malloc();
  1293. Xint    matchup();
  1294. Xlong    findstart();
  1295. X
  1296. Xchar    verbose;        /*  Tell the world what we are doing  */
  1297. Xchar    *tfnam;
  1298. Xchar    *cfile;
  1299. Xef_fids    mainfile;
  1300. Xstruct    commit    dreltab;
  1301. Xint    donedrel, donebrel;
  1302. Xlong    trelpos, drelpos, brelpos;
  1303. Xstatic    struct    libit    currlib = {NULL, NULL, ""};
  1304. X
  1305. Xvoid    lclash(str)
  1306. Xchar    *str;
  1307. X{
  1308. X    (void) fprintf(stderr, "Library scan failure - %s\n", str);
  1309. X    (void) fprintf(stderr, "Searching %s\n", cfile);
  1310. X    if  (currlib.lf_name[0])
  1311. X        (void) fprintf(stderr, "Member is %s\n", currlib.lf_name);
  1312. X    exit(255);
  1313. X}
  1314. X
  1315. X/*
  1316. X *    Find next member.
  1317. X */
  1318. X
  1319. Xlong    nextmemb(filename,lfd)
  1320. Xchar *filename;
  1321. Xregister  struct  libit     *lfd;
  1322. X{
  1323. X    struct    ar_hdr    arbuf;
  1324. X    
  1325. X    ldaclose(lfd->ldptr2);
  1326. X    if (ldclose(lfd->ldptr != FAILURE))    /* end of archive */
  1327. X        return -1;
  1328. X    lfd->ldptr = ldopen(filename,lfd->ldptr);
  1329. X    ldahread(lfd->ldptr, (char *)&arbuf);
  1330. X    (void) strncpy(lfd->lf_name, arbuf.ar_name, sizeof(lfd->lf_name));
  1331. X    return 1;
  1332. X}
  1333. X
  1334. X/*
  1335. X *    Decode a file name thus -
  1336. X *
  1337. X *    -lxxx decode as /lib/libxxx.a /usr/lib/libxxx.a etc
  1338. X *    -Lxxx forget "lib" ".a" bit thus -Lcrt0.o
  1339. X *    or read LDPATH environment var to give list of directories as sh
  1340. X *    (default /lib:/usr/lib).
  1341. X *
  1342. X *    Alternatively treat as normal pathname.
  1343. X *
  1344. X *    File names may be followed by (membername) if the file is an archive,
  1345. X *    thus
  1346. X *
  1347. X *        -lc(printf.o)
  1348. X *
  1349. X *    in which case the specified module is fetched.
  1350. X */
  1351. X
  1352. Xstruct    libit    *getfnam(str)
  1353. Xchar    *str;    /* will be expanded to full path name if necessary */
  1354. X{
  1355. X    char    *bp, *ep = NULL, *pathb, *pathe, *fullpath = NULL;
  1356. X    static    char    *pathn;
  1357. X    extern    char    *getenv();
  1358. X     char    magic[8];
  1359. X    struct    ar_hdr    arhdr;
  1360. X    LDFILE *ldptr;
  1361. X
  1362. X     if  ((bp = strrchr(str, '(')) != NULL &&
  1363. X          (ep = strrchr(str, ')')) != NULL)
  1364. X        *ep = *bp = '\0';
  1365. X
  1366. X    if  (str[0] == '-'  &&  (str[1] == 'l' || str[1] == 'L'))  {
  1367. X        if  (pathn == NULL)  {
  1368. X            if  ((pathn = getenv("LDPATH")) == NULL)
  1369. X                pathn = "/lib:/usr/lib";
  1370. X        }
  1371. X        fullpath = malloc((unsigned)(strlen(pathn) + strlen(str) + 1));
  1372. X        if  (fullpath == NULL)
  1373. X            nomem();
  1374. X        pathb = pathn;
  1375. X        do  {
  1376. X             pathe = strchr(pathb, ':');
  1377. X            if  (*pathb == ':')
  1378. X                fullpath[0] = '\0';
  1379. X            else  {
  1380. X                if  (pathe != NULL)
  1381. X                    *pathe = '\0';
  1382. X                (void) strcpy(fullpath, pathb);
  1383. X                (void) strcat(fullpath, "/");
  1384. X                if  (pathe != NULL)
  1385. X                    *pathe = ':';
  1386. X            }
  1387. X            if  (str[1] == 'l')
  1388. X                (void) strcat(fullpath, "lib");
  1389. X            (void) strcat(fullpath, &str[2]);
  1390. X            if  (str[1] == 'l')
  1391. X                (void) strcat(fullpath, ".a");
  1392. X            if  ((ldptr = ldopen(fullpath, NULL)) != NULL)
  1393. X                goto  found;
  1394. X            pathb = pathe + 1;
  1395. X        }   while  (pathe != NULL);
  1396. X        
  1397. X        (void) fprintf(stderr, "Unable to locate lib%s.a in %s\n",
  1398. X            &str[2], pathn);
  1399. X        exit(101);
  1400. X    }
  1401. X    else  if  ((ldptr = ldopen(str, NULL)) == NULL)  {
  1402. X        (void) fprintf(stderr, "Cannot open %s\n", str);
  1403. X        exit(102);
  1404. X    }
  1405. X    
  1406. Xfound:
  1407. X
  1408. X    str = fullpath? fullpath: str;
  1409. X     if  (FREAD(magic, sizeof(magic),1,ldptr) != 1  ||
  1410. X         strcmp(magic, ARMAG) != 0)  {
  1411. X        if  (ep != NULL)  {
  1412. X            (void) fprintf(stderr, "%s is not library file\n", str);
  1413. X            exit(103);
  1414. X        }
  1415. X        currlib.ldptr = ldptr;
  1416. X        currlib.ldptr2 = ldaopen(str,ldptr);
  1417. X        currlib.lf_name[0] = '\0';
  1418. X        return  &currlib;
  1419. X    }
  1420. X    
  1421. X    /*
  1422. X     *    It appears to be a library file - see if we want a specific
  1423. X     *    one.
  1424. X     */
  1425. X    
  1426. X    if  (ep != NULL)  {
  1427. X         char *cp;
  1428. X        for  (;;)  {
  1429. X            if  (ldahread(ldptr,&arhdr) == FAILURE)  {
  1430. X                (void) fprintf(stderr, "Cannot find member %s in %s\n",
  1431. X                    bp+1, str);
  1432. X                exit(103);
  1433. X            }
  1434. X             for ( cp = arhdr.ar_name + sizeof(arhdr.ar_name) - 1;
  1435. X                 *cp == ' ';
  1436. X                 cp -- ) ;
  1437. X             if  (strncmp(bp+1, arhdr.ar_name, cp - arhdr.ar_name + 1) == 0)
  1438. X                break;
  1439. X
  1440. X            if (ldclose(ldptr) != FAILURE) {
  1441. X                (void) fprintf(stderr, "Cannot find member %s in %s\n",
  1442. X                    bp+1, str);
  1443. X                exit(103);
  1444. X            }
  1445. X            ldptr = ldopen(str,ldptr);
  1446. X        }
  1447. X        currlib.ldptr = ldptr;
  1448. X        currlib.ldptr2 = ldaopen(str,ldptr);
  1449. X        currlib.lf_name[0] = '\0';
  1450. X        *bp = '(';
  1451. X        *ep = ')';
  1452. X        return    &currlib;
  1453. X    }
  1454. X    
  1455. X    /*
  1456. X     *    Otherwise point to 1st member in library.
  1457. X     */
  1458. X    
  1459. X    if  (ldahread(ldptr, &arhdr) == FAILURE)  {
  1460. X        (void) fprintf(stderr, "Library %s empty\n", str);
  1461. X        exit(104);
  1462. X    }
  1463. X    currlib.ldptr = ldptr;
  1464. X    currlib.ldptr2 = ldaopen(str,ldptr);
  1465. X    (void) strncpy(currlib.lf_name, arhdr.ar_name, sizeof(currlib.lf_name));
  1466. X    return    &currlib;
  1467. X}
  1468. X
  1469. X/*
  1470. X *    Process library files.
  1471. X */
  1472. X
  1473. X#define    MINTEXT    6
  1474. X
  1475. Xvoid    lscan(nfiles, fnames)
  1476. Xint    nfiles;
  1477. Xchar    **fnames;
  1478. X{
  1479. X    ef_fids    libfile;
  1480. X    register  ef_fid  ll = &libfile;
  1481. X    register  struct  libit     *clf;
  1482. X    extern    symbol    dolsymb();
  1483. X    int    firstfile;
  1484. X    
  1485. X    for  (;  nfiles > 0;  fnames++, nfiles--)  {
  1486. X        clf = getfnam(*fnames);
  1487. X        cfile = *fnames;
  1488. X        firstfile = 1;
  1489. X        do  {
  1490. X            bfopen(tfnam, ll);
  1491. X
  1492. X            /*
  1493. X             *    If file is garbled, silently forget it and go
  1494. X             *    on to the next one.
  1495. X             */
  1496. X
  1497. X            if  (!rtext(clf->ldptr, ll))
  1498. X                goto  closeit;
  1499. X                
  1500. X            if  (ll->ef_tsize < MINTEXT)
  1501. X                goto  closeit;
  1502. X                
  1503. X            if  (!rdata(clf->ldptr, ll))
  1504. X                goto  closeit;
  1505. X                
  1506. X            if  (rrell1(clf->ldptr, ll) < 0)
  1507. X                goto  closeit;
  1508. X                
  1509. X            /*
  1510. X             *    If first file in library, find it from
  1511. X             *    beginning of main file.
  1512. X             */
  1513. X            
  1514. X            if  (firstfile)  {
  1515. X                if  ((trelpos = findstart(&mainfile, ll)) < 0)
  1516. X                    goto  closeit;
  1517. X                firstfile = 0;
  1518. X            }
  1519. X            else   if  (!matchup(&mainfile, ll, trelpos))
  1520. X                    goto  closeit;
  1521. X            
  1522. X            /*
  1523. X             *    Found a match.
  1524. X             */
  1525. X            
  1526. X            if  (!rsymb(clf->ldptr, dolsymb, ll))  {
  1527. X                (void) fprintf(stderr, "Corrupt file %s\n",
  1528. X                            *fnames);
  1529. X                exit(150);
  1530. X            }
  1531. X            
  1532. X            donedrel = 0;
  1533. X            donebrel = 0;
  1534. X            rrell2(clf->ldptr, clf->ldptr2, ll);
  1535. X            if  (verbose)  {
  1536. X                (void) fprintf(stderr, "Found: ");
  1537. X                if  (clf->lf_name[0])
  1538. X                    (void) fprintf(stderr, "%.14s in ",
  1539. X                            clf->lf_name);
  1540. X                (void) fprintf(stderr, "%s\n", *fnames);
  1541. X            }
  1542. X            if  (libfile.ef_stvec != NULL)  {
  1543. X                free(libfile.ef_stvec);
  1544. X                libfile.ef_stvec = NULL;
  1545. X                libfile.ef_stcnt = 0;
  1546. X            }
  1547. X            dreltab.c_int = 0;
  1548. X                
  1549. X            /*
  1550. X             *    Start looking next time round
  1551. X             *    where last one left off.
  1552. X             */
  1553. X            
  1554. X            markmatch(&mainfile, ll, trelpos);
  1555. X            trelpos += libfile.ef_tsize;
  1556. Xcloseit:
  1557. X            bfclose(ll);
  1558. X        }  while  (nextmemb(cfile,clf) >= 0);
  1559. X    }
  1560. X}
  1561. SHAR_EOF
  1562. chmod 0644 libmtch.c || echo "restore of libmtch.c fails"
  1563. sed 's/^X//' << 'SHAR_EOF' > robj.c &&
  1564. X/*
  1565. X *    SCCS:    @(#)robj.c    1.2    11/2/84    14:19:59
  1566. X *    Read object files.
  1567. X *
  1568. X ***********************************************************************
  1569. X *    This software is copyright of
  1570. X *
  1571. X *        John M Collins
  1572. X *        47 Cedarwood Drive
  1573. X *        St Albans
  1574. X *        Herts, AL4 0DN
  1575. X *        England            +44 727 57267
  1576. X *
  1577. X *    and is released into the public domain on the following conditions:
  1578. X *
  1579. X *        1.  No free maintenance will be guaranteed.
  1580. X *        2.  Nothing may be based on this software without
  1581. X *            acknowledgement, including incorporation of this
  1582. X *            notice.
  1583. X *
  1584. X *    Notwithstanding the above, the author welcomes correspondence and bug
  1585. X *    fixes.
  1586. X ***********************************************************************
  1587. X *
  1588. X *    This particular module will obviously have to be munged beyond
  1589. X *    recognition for another object format.
  1590. X */
  1591. X
  1592. X#include <stdio.h>
  1593. X#include <a.out.h>
  1594. X#include <ldfcn.h>
  1595. X#include <string.h>
  1596. X#include "unc.h"
  1597. X
  1598. Xvoid    gette(), getde(), setde(), putte(), putde();
  1599. Xlong    gettw(), getdw();
  1600. Xvoid    reallst(), lclash(), nomem(), unimpl();
  1601. Xvoid    addit();
  1602. Xchar    *malloc();
  1603. Xlong    lseek();
  1604. X
  1605. Xint    par_entry, par_round, nmods, donedrel, donebrel;
  1606. Xstruct    commit    abstab, comtab, dreltab;
  1607. Xlong    trelpos, drelpos, brelpos;
  1608. X
  1609. Xint *symord;    /* convert symbol index to symbol ordinal */
  1610. X
  1611. Xef_fids    mainfile;
  1612. X
  1613. Xsymbol    lookup(), inventsymb(), getnsymb();
  1614. X
  1615. X#define RWORD 1
  1616. X#define RLONG 2
  1617. X#define    DBSIZE    100
  1618. X#define    STINIT    20
  1619. X
  1620. X/*
  1621. X *    Read text segment.  Return 0 if not ok.
  1622. X */
  1623. X
  1624. Xint    rtext(ldptr, outf)
  1625. X  LDFILE *ldptr;        /*  a.out file (possibly in library)  */
  1626. X  ef_fid    outf;        /*  Output file descriptor  */
  1627. X{
  1628. X   t_entry        tstr;
  1629. X   struct    aouthdr    unixhdr;
  1630. X   struct  scnhdr  sect;
  1631. X   register  long    size;
  1632. X   register  int    i, l;
  1633. X   unsigned  short    inbuf[DBSIZE/2];
  1634. X   
  1635. X   /*
  1636. X    *    Initialise fields in structure.
  1637. X    */
  1638. X   
  1639. X   tstr.t_type = T_UNKNOWN;
  1640. X   tstr.t_vins = 1;        /*  For the moment  */
  1641. X   tstr.t_bdest = 0;
  1642. X   tstr.t_gbdest = 0;
  1643. X   tstr.t_lng = 1;
  1644. X   tstr.t_reloc = R_NONE;
  1645. X   tstr.t_rdisp = 0;
  1646. X   tstr.t_isrel = 0;
  1647. X   tstr.t_amap = 0;
  1648. X    tstr.t_dref = 0;
  1649. X    tstr.t_relsymb = NULL;
  1650. X    tstr.t_reldisp = 0;
  1651. X    tstr.t_lab = NULL;
  1652. X    tstr.t_lsymb = 0;
  1653. X    tstr.t_refhi = 0;
  1654. X    tstr.t_reflo = 0x7fffffff;
  1655. X    tstr.t_match = 0;
  1656. X    
  1657. X    /*
  1658. X     *    Read a.out header.
  1659. X     */
  1660. X
  1661. X    if (ldohseek(ldptr) == FAILURE) {    /* no optional header */
  1662. X
  1663. X        outf->ef_entry = 0;
  1664. X        ldshread(ldptr,1,§);        /* text header */
  1665. X        outf->ef_tbase = sect.s_vaddr;
  1666. X        outf->ef_tsize = sect.s_size;
  1667. X
  1668. X        ldshread(ldptr,2,§);        /* data header */
  1669. X        outf->ef_dbase = sect.s_vaddr;
  1670. X        outf->ef_dsize = sect.s_size;
  1671. X
  1672. X        ldshread(ldptr,3,§);        /* bss header */
  1673. X        outf->ef_bbase = sect.s_vaddr;
  1674. X        outf->ef_bsize = sect.s_size;
  1675. X        outf->ef_end = sect.s_vaddr + sect.s_size;
  1676. X    } else {
  1677. X        FREAD((char *)&unixhdr,sizeof(struct aouthdr),1,ldptr);
  1678. X    
  1679. X        if ( N_BADMAG(unixhdr) )
  1680. X        return    0;
  1681. X
  1682. X        outf->ef_entry = unixhdr.entry;
  1683. X        outf->ef_tbase = unixhdr.text_start;
  1684. X        outf->ef_dbase = unixhdr.data_start;
  1685. X        outf->ef_bbase = outf->ef_dbase + unixhdr.dsize;
  1686. X        outf->ef_end = outf->ef_bbase + unixhdr.bsize;
  1687. X
  1688. X        outf->ef_tsize = unixhdr.tsize;
  1689. X        outf->ef_dsize = unixhdr.dsize;
  1690. X        outf->ef_bsize = unixhdr.bsize;
  1691. X    }
  1692. X    
  1693. X    ldsseek(ldptr,1);    /* seek to text section */
  1694. X    
  1695. X    size = outf->ef_tsize;
  1696. X    
  1697. X    while  (size > 1)  {
  1698. X        l = size > DBSIZE? DBSIZE: size;
  1699. X        if  (FREAD((char *)inbuf,1,l,ldptr) != l)
  1700. X            return    0;
  1701. X        l /= 2;
  1702. X        for  (i = 0;  i < l;  i++)  {
  1703. X            tstr.t_contents = inbuf[i];
  1704. X            (void) write(outf->ef_t, (char *)&tstr, sizeof(tstr));
  1705. X        }
  1706. X        size -= l + l;
  1707. X    }
  1708. X    
  1709. X    /*
  1710. X     *    Extra one to cope with "etext".
  1711. X     */
  1712. X    
  1713. X    (void) write(outf->ef_t, (char *)&tstr, sizeof(tstr));
  1714. X    return    1;
  1715. X}
  1716. X/*
  1717. X *    Same sort of thing for the data segment.
  1718. X */
  1719. X
  1720. Xint    rdata(ldptr, outf)
  1721. XLDFILE *ldptr;        /*  a.out file (possibly in library)  */
  1722. Xef_fid    outf;        /*  Output file descriptor  */
  1723. X{
  1724. X    d_entry        dstr;
  1725. X    register  long    size;
  1726. X    register  int    i, l;
  1727. X    unsigned  char    inbuf[DBSIZE];
  1728. X
  1729. X    /*
  1730. X     *    Initialise fields in structure.
  1731. X     */
  1732. X    
  1733. X    dstr.d_type = D_BYTE;
  1734. X    dstr.d_reloc = R_NONE;
  1735. X    dstr.d_lng = 1;
  1736. X    dstr.d_relsymb = NULL;
  1737. X    dstr.d_reldisp = 0;
  1738. X    dstr.d_lab = NULL;
  1739. X    
  1740. X    ldsseek(ldptr,2);    /* seek to data section */
  1741. X    
  1742. X    size = outf->ef_dsize;
  1743. X    
  1744. X    while  (size > 0)  {
  1745. X        l = size > DBSIZE? DBSIZE: size;
  1746. X        if  (FREAD((char *)inbuf,1,l,ldptr) != l)
  1747. X            return    0;
  1748. X        for  (i = 0;  i < l;  i++)  {
  1749. X            dstr.d_contents = inbuf[i];
  1750. X            (void) write(outf->ef_d, (char *)&dstr, sizeof(dstr));
  1751. X        }
  1752. X        size -= l;
  1753. X    }
  1754. X    
  1755. X    /*
  1756. X     *    Repeat for BSS segment.
  1757. X     */
  1758. X
  1759. X    dstr.d_contents = 0;
  1760. X    for  (size = outf->ef_bsize;  size > 0;  size--)
  1761. X        (void) write(outf->ef_d, (char *)&dstr, sizeof(dstr));
  1762. X    
  1763. X    /*
  1764. X     *    Extra one to cope with "end".
  1765. X     */
  1766. X    
  1767. X    (void) write(outf->ef_d, (char *)&dstr, sizeof(dstr));
  1768. X    return    1;
  1769. X}
  1770. X
  1771. X/*
  1772. X *    Process symbol table segment.
  1773. X */
  1774. X
  1775. Xint    rsymb(ldptr, dproc, outf)
  1776. XLDFILE *ldptr;        /*  a.out file (possibly in library)  */
  1777. Xsymbol    (*dproc)();
  1778. Xregister  ef_fid  outf;    /*  Output file descriptor  */
  1779. X{
  1780. X#define SYMLENGTH 256
  1781. X    register  symbol  csym;
  1782. X     struct    syment    isym;
  1783. X    register  int   nsyms,symindex;
  1784. X    unsigned long   stroff;
  1785. X     char    inbuf[SYMLENGTH+1], *cp;
  1786. X    int ord;
  1787. X
  1788. X    nsyms = HEADER(ldptr).f_nsyms;
  1789. X    stroff = HEADER(ldptr).f_symptr + nsyms*sizeof(struct syment);
  1790. X
  1791. X    if  (nsyms <= 0)
  1792. X        nsyms = STINIT;
  1793. X
  1794. X    outf->ef_stvec = (symbol *) malloc(nsyms * sizeof(symbol));
  1795. X    symord = (int *) malloc(nsyms * sizeof(int));
  1796. X    if  (outf->ef_stvec == NULL)
  1797. X        nomem();
  1798. X
  1799. X    outf->ef_stcnt = 0;
  1800. X    outf->ef_stmax = nsyms;
  1801. X    ord = 0;
  1802. X    
  1803. X     for  (symindex=0; symindex<nsyms; symindex++)  {
  1804. X        ldtbread(ldptr,symindex,&isym);
  1805. X        if (isym.n_zeroes == 0) {    /* get from string table */
  1806. X            FSEEK(ldptr,stroff + isym.n_offset,0);
  1807. X            cp = inbuf;
  1808. X            do {
  1809. X             if (FREAD(cp,1,1,ldptr) != 1)/* Read symbol chars 1-by-1 */
  1810. X                 return 0;
  1811. X             if ( cp - inbuf >= SYMLENGTH )/* Check against buffer overflow */
  1812. X                 return 0;
  1813. X            } while (*cp++ != '\0');/* Terminate on null byte */
  1814. X        } else {            /* get from symbol field */
  1815. X            strncpy(inbuf,isym.n_name,8);
  1816. X            inbuf[8] = '\0';
  1817. X        }
  1818. X         csym = (*dproc)(lookup(inbuf), convtosun(&isym),
  1819. X                isym.n_value, outf);
  1820. X         if (outf->ef_stcnt >= outf->ef_stmax)
  1821. X            reallst(outf);
  1822. X        outf->ef_stvec[outf->ef_stcnt++] = csym;
  1823. X        symord[symindex] = ord++;        /* record ordinal */
  1824. X        symindex += isym.n_numaux;        /* skip aux entries */
  1825. X    }
  1826. X    return    1;
  1827. X}
  1828. X
  1829. X/*
  1830. X *    Process relocation stuff.  -1 error, 0 no relocation, 1 relocation.
  1831. X */
  1832. X
  1833. Xint    rrel(ldptr, ldptr2, outf)
  1834. XLDFILE *ldptr,*ldptr2;    /*  a.out file (possibly in library)  */
  1835. Xef_fid    outf;        /*  Output file descriptor  */
  1836. X{
  1837. X     struct    reloc    crel;
  1838. X    struct scnhdr tsect,dsect;
  1839. X    struct syment isym;
  1840. X    t_entry    tstr;
  1841. X    d_entry    dstr;
  1842. X    register  int    nreloc;
  1843. X    long    cont, pos;
  1844. X
  1845. X    ldshread(ldptr,1,&tsect);
  1846. X    ldshread(ldptr,2,&dsect);
  1847. X     if  (tsect.s_nreloc <= 0  &&  dsect.s_nreloc <= 0)
  1848. X        return    0;
  1849. X
  1850. X    nreloc = tsect.s_nreloc;
  1851. X
  1852. X    ldrseek(ldptr,1);
  1853. X     while  (nreloc-- > 0)  {
  1854. X        if  (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
  1855. X            return    -1;
  1856. X
  1857. X         pos = crel.r_vaddr;
  1858. X        gette(outf, pos, &tstr);
  1859. X        if (crel.r_type == R_ABS)
  1860. X            tstr.t_reloc = R_NONE;
  1861. X        else
  1862. X            tstr.t_reloc = R_LONG;    /* what about PC-relative? */
  1863. X        ldtbread(ldptr2,crel.r_symndx,&isym);
  1864. X        if (isym.n_sclass == C_EXT) {
  1865. X             tstr.t_relsymb = outf->ef_stvec[symord[crel.r_symndx]];
  1866. X             tstr.t_reldisp = gettw(outf, pos, (int)tstr.t_reloc);
  1867. X        }
  1868. X        else  {
  1869. X             cont = gettw(outf, pos, (int)tstr.t_reloc);
  1870. X             tstr.t_relsymb = getnsymb(outf, convtosun(&isym), cont);
  1871. X        }
  1872. X        tstr.t_relsymb->s_used++;
  1873. X        putte(outf, pos, &tstr);
  1874. X    }
  1875. X    
  1876. X    /*
  1877. X     *    And now repeat all that for data relocations.
  1878. X     */
  1879. X    
  1880. X    nreloc = dsect.s_nreloc;
  1881. X    
  1882. X    ldrseek(ldptr,2);
  1883. X     while  (nreloc-- > 0)  {
  1884. X        if (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
  1885. X            return    -1;
  1886. X
  1887. X         pos = crel.r_vaddr;
  1888. X        getde(outf, pos, &dstr);
  1889. X        if (crel.r_type == R_ABS)
  1890. X            dstr.d_reloc = R_NONE;
  1891. X        else
  1892. X            dstr.d_reloc = R_LONG;    /* what about PC-relative? */
  1893. X
  1894. X        ldtbread(ldptr2,crel.r_symndx,&isym);
  1895. X        if (isym.n_sclass == C_EXT) {
  1896. X             dstr.d_relsymb = outf->ef_stvec[symord[crel.r_symndx]];
  1897. X             dstr.d_reldisp = getdw(outf, pos, (int)dstr.d_reloc);
  1898. X        }
  1899. X        else  {
  1900. X             cont = getdw(outf, pos, (int)dstr.d_reloc);
  1901. X             dstr.d_relsymb = getnsymb(outf, convtosun(&isym), cont);
  1902. X             if  (dstr.d_relsymb->s_type == S_TEXT)  {
  1903. X                gette(outf, cont, &tstr);
  1904. X                tstr.t_dref = 1;
  1905. X                putte(outf, cont, &tstr);
  1906. X            }
  1907. X        }
  1908. X         switch  (dstr.d_reloc)  {
  1909. X        default:
  1910. X            unimpl("Data byte relocation");
  1911. X            break;
  1912. X        case  R_WORD:
  1913. X            unimpl("data word reloc");
  1914. X            dstr.d_type = D_WORD;
  1915. X            dstr.d_lng = 2;
  1916. X            setde(outf, pos+1, D_CONT, 1);
  1917. X            break;
  1918. X        case  R_LONG:
  1919. X            dstr.d_type = D_ADDR;
  1920. X            dstr.d_lng = 4;
  1921. X            setde(outf, pos+1, D_CONT, 1);
  1922. X            setde(outf, pos+2, D_CONT, 1);
  1923. X            setde(outf, pos+3, D_CONT, 1);
  1924. X            break;
  1925. X        }
  1926. X        dstr.d_relsymb->s_used++;
  1927. X        putde(outf, pos, &dstr);
  1928. X    }
  1929. X    return 1;
  1930. X}
  1931. X
  1932. X/*
  1933. X *    Process a symbol.
  1934. X */
  1935. X
  1936. Xsymbol    dosymb(sy, type, val, fid)
  1937. Xregister  symbol  sy;
  1938. Xint    type;
  1939. Xlong    val;
  1940. Xef_fid    fid;
  1941. X{
  1942. X    t_entry    tstr;
  1943. X    d_entry    dstr;
  1944. X    
  1945. X    if  (!sy->s_newsym)  {
  1946. X         if  (type & S_EXT)  {
  1947. X            (void) fprintf(stderr, "Duplicate symbol %s\n", sy->s_name);
  1948. X            /* exit(10);  temporary? */
  1949. X        }
  1950. X        if  (++sy->s_defs > nmods)
  1951. X            nmods = sy->s_defs;
  1952. X        sy = inventsymb("DUP");
  1953. X    }
  1954. X
  1955. X    sy->s_value = val;
  1956. X    
  1957. X    switch  (type)  {
  1958. X    default:
  1959. X        return    NULL;
  1960. X        
  1961. X     case  S_EXT|S_UNDF:
  1962. X        if  (val != 0)  {
  1963. X             sy->s_type = S_COMM;
  1964. X            addit(&comtab, sy);
  1965. X        }
  1966. X        else
  1967. X            sy->s_type = S_UNDF;
  1968. X        sy->s_glob = 1;
  1969. X        break;
  1970. X        
  1971. X     case  S_EXT|S_ABS:
  1972. X        sy->s_type = S_ABS;
  1973. X        sy->s_glob = 1;
  1974. X        addit(&abstab, sy);
  1975. X        break;
  1976. X        
  1977. X     case  S_ABS:
  1978. X        sy->s_type = S_ABS;
  1979. X        addit(&abstab, sy);
  1980. X        break;
  1981. X        
  1982. X     case  S_EXT|S_TEXT:
  1983. X     case  S_TEXT:
  1984. X        sy->s_type = S_TEXT;
  1985. X        gette(fid, val, &tstr);
  1986. X        tstr.t_bdest = 1;
  1987. X         if  (type & S_EXT)  {
  1988. X            tstr.t_gbdest = 1;
  1989. X            sy->s_glob = 1;
  1990. X        }
  1991. X        sy->s_link = tstr.t_lab;
  1992. X        tstr.t_lab = sy;
  1993. X        putte(fid, val, &tstr);
  1994. X        break;
  1995. X        
  1996. X     case  S_BSS:
  1997. X     case  S_EXT|S_BSS:
  1998. X        sy->s_type = S_BSS;
  1999. X        goto    datrest;
  2000. X     case  S_DATA:
  2001. X     case  S_EXT|S_DATA:
  2002. X        sy->s_type = S_DATA;
  2003. X    datrest:
  2004. X        getde(fid, val, &dstr);
  2005. X         if  (type & S_EXT)
  2006. X            sy->s_glob = 1;
  2007. X        sy->s_link = dstr.d_lab;
  2008. X        dstr.d_lab = sy;
  2009. X        putde(fid, val, &dstr);
  2010. X        break;
  2011. X    }
  2012. X    
  2013. X    sy->s_newsym = 0;
  2014. X    return    sy;
  2015. X}
  2016. X
  2017. X
  2018. X/*
  2019. X *    Process relocation stuff in putative library modules.
  2020. X *    The main function of all this is to mark which bits of the text
  2021. X *    not to look at as I compare the stuff.
  2022. X *
  2023. X *    As with "rrel", return -1 error, 0 no relocation, 1 relocation.
  2024. X */
  2025. X
  2026. Xint    rrell1(ldptr, outf)
  2027. XLDFILE *ldptr;        /*  a.out file (possibly in library)  */
  2028. Xef_fid    outf;        /*  Output file descriptor  */
  2029. X{
  2030. X     struct    reloc    crel;
  2031. X    struct scnhdr tsect,dsect;
  2032. X    t_entry    tstr;
  2033. X    register  int    nreloc;
  2034. X    long    pos;
  2035. X
  2036. X    ldshread(ldptr,1,&tsect);
  2037. X    ldshread(ldptr,2,&dsect);
  2038. X     if  (tsect.s_nreloc <= 0  &&  dsect.s_nreloc <= 0)
  2039. X        return    0;
  2040. X
  2041. X    nreloc = tsect.s_nreloc;
  2042. X
  2043. X    ldrseek(ldptr,1);
  2044. X     while  (nreloc-- > 0)  {
  2045. X        if  (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
  2046. X            return    -1;
  2047. X
  2048. X         pos = crel.r_vaddr;
  2049. X        gette(outf, pos, &tstr);
  2050. X        if (crel.r_type == R_ABS)
  2051. X            tstr.t_reloc = R_NONE;
  2052. X        else
  2053. X            tstr.t_reloc = R_LONG;    /* what about PC-relative? */
  2054. X        tstr.t_isrel = 1;
  2055. X        putte(outf, pos, &tstr);
  2056. X         if  (tstr.t_reloc == R_LONG)  {
  2057. X            gette(outf, pos+2, &tstr);
  2058. X            tstr.t_isrel = 1;
  2059. X            putte(outf, pos+2, &tstr);
  2060. X        }
  2061. X    }
  2062. X    
  2063. X    /*
  2064. X     *    Dont bother with data relocation at this stage. We'll
  2065. X     *    tie that up later.
  2066. X     */
  2067. X    
  2068. X    return 1;
  2069. X}
  2070. X
  2071. X/*
  2072. X *    Process a symbol in library file.  The extern variable trelpos gives
  2073. X *    the place in the main file where the library module is relocated.
  2074. X *    We don't know the data position until we do the final merge, perhaps
  2075. X *    not even then.
  2076. X */
  2077. X/* trelpos ??? */
  2078. X
  2079. Xsymbol    dolsymb(sy, type, val, fid)
  2080. Xregister  symbol  sy;
  2081. Xint    type;
  2082. Xlong    val;
  2083. Xef_fid    fid;
  2084. X{
  2085. X    t_entry    tstr;
  2086. X    
  2087. X    switch  (type)  {
  2088. X    default:
  2089. X        return    NULL;
  2090. X        
  2091. X     case  S_EXT|S_UNDF:
  2092. X        if  (!sy->s_newsym)
  2093. X            return    sy;
  2094. X        sy->s_value = val;
  2095. X        if  (val != 0)  {
  2096. X             sy->s_type = S_COMM;
  2097. X            addit(&dreltab, sy);
  2098. X        }
  2099. X        else
  2100. X            sy->s_type = S_UNDF;
  2101. X        sy->s_glob = 1;
  2102. X        break;
  2103. X        
  2104. X     case  S_EXT|S_ABS:
  2105. X        if  (!sy->s_newsym)  {
  2106. X            if  (sy->s_type != S_ABS || sy->s_value != val)
  2107. X                lclash("abs");
  2108. X        }
  2109. X        sy->s_type = S_ABS;
  2110. X        sy->s_value = val;
  2111. X        sy->s_glob = 1;
  2112. X        addit(&abstab, sy);
  2113. X        break;
  2114. X        
  2115. X     case  S_EXT|S_TEXT:
  2116. X        sy->s_type = S_TEXT;
  2117. X        val += trelpos - fid->ef_tbase;
  2118. X        if  (!sy->s_newsym)  {
  2119. X            if  (val != sy->s_value)
  2120. X                lclash("tsym");
  2121. X            return    sy;
  2122. X        }
  2123. X        sy->s_value = val;
  2124. X        gette(&mainfile, val, &tstr);
  2125. X        tstr.t_bdest = 1;
  2126. X        tstr.t_gbdest = 1;
  2127. X        sy->s_glob = 1;
  2128. X        sy->s_link = tstr.t_lab;
  2129. X        tstr.t_lab = sy;
  2130. X        putte(&mainfile, val, &tstr);
  2131. X        break;
  2132. X
  2133. X     case  S_EXT|S_BSS:
  2134. X        if  (!sy->s_newsym)
  2135. X            return    sy;
  2136. X        sy->s_type = S_BSS;
  2137. X        sy->s_value = val - fid->ef_bbase;
  2138. X        goto    datrest;
  2139. X
  2140. X     case  S_EXT|S_DATA:
  2141. X        if  (!sy->s_newsym)
  2142. X            return    sy;
  2143. X        sy->s_type = S_DATA;
  2144. X        sy->s_value = val - fid->ef_dbase;
  2145. X    datrest:
  2146. X        sy->s_glob = 1;
  2147. X        addit(&dreltab, sy);
  2148. X        break;
  2149. X    }
  2150. X    
  2151. X    sy->s_newsym = 0;
  2152. X    return    sy;
  2153. X}
  2154. X
  2155. X/*
  2156. X *    Change definition of undefined symbol as we define it.
  2157. X */
  2158. X
  2159. Xvoid    reassign(sy, val)
  2160. Xregister  symbol  sy;
  2161. Xlong    val;
  2162. X{
  2163. X    sy->s_value = val;
  2164. X
  2165. X    if  (val < mainfile.ef_tbase)  {
  2166. X        sy->s_type = S_ABS;
  2167. X        addit(&abstab, sy);
  2168. X    }
  2169. X    else  if  (val < mainfile.ef_dbase)  {
  2170. X        t_entry    tstr;
  2171. X        
  2172. X        sy->s_type = S_TEXT;
  2173. X        gette(&mainfile, val, &tstr);
  2174. X        tstr.t_bdest = 1;
  2175. X        tstr.t_gbdest = 1;
  2176. X        sy->s_glob = 1;
  2177. X        sy->s_link = tstr.t_lab;
  2178. X        tstr.t_lab = sy;
  2179. X        putte(&mainfile, val, &tstr);
  2180. X    }
  2181. X    else  {
  2182. X        d_entry dstr;
  2183. X        
  2184. X        sy->s_type = val < mainfile.ef_bbase? S_DATA: S_BSS;
  2185. X        getde(&mainfile, val, &dstr);
  2186. X        sy->s_link = dstr.d_lab;
  2187. X        dstr.d_lab = sy;
  2188. X        putde(&mainfile, val, &dstr);
  2189. X    }
  2190. X}
  2191. X
  2192. X/*
  2193. X *    When we discover where bss or data come, reallocate the table.
  2194. X */
  2195. X
  2196. Xvoid    zapdat(seg, inc)
  2197. Xint    seg;
  2198. Xlong    inc;
  2199. X{
  2200. X    register  int    i;
  2201. X    register  symbol  csymb;
  2202. X    d_entry    dent;
  2203. X    
  2204. X    for  (i = 0;  i < dreltab.c_int;  i++) {
  2205. X        csymb = dreltab.c_symb[i];
  2206. X        if  (csymb->s_type != seg)
  2207. X            continue;
  2208. X        csymb->s_value += inc;
  2209. X        getde(&mainfile, csymb->s_value, &dent);
  2210. X        csymb->s_link = dent.d_lab;
  2211. X        dent.d_lab = csymb;
  2212. X        putde(&mainfile, csymb->s_value, &dent);
  2213. X    }
  2214. X}
  2215. X
  2216. X/*
  2217. X *    Process relocation stuff in library module which we are inserting.
  2218. X *    Horrors if something goes wrong.
  2219. X */
  2220. X/* trelpos, drelpos ??? */
  2221. X
  2222. Xrrell2(ldptr, ldptr2, outf)
  2223. XLDFILE *ldptr,*ldptr2;    /*  a.out file (possibly in library)  */
  2224. Xef_fid    outf;        /*  Output file descriptor  */
  2225. X{
  2226. X     struct    reloc    crel;
  2227. X    t_entry    mtstr;
  2228. X    d_entry    mdstr;
  2229. X    struct scnhdr tsect,dsect;
  2230. X    struct syment isym;
  2231. X    int nreloc;
  2232. X    unsigned rtype;
  2233. X    register  long    size;
  2234. X    register  symbol  csymb;
  2235. X    long    pos, mpos, mval, lval;
  2236. X    int    dhere = 0;        /*  Mark whether bss done  */
  2237. X
  2238. X    ldshread(ldptr,1,&tsect);
  2239. X    ldshread(ldptr,2,&dsect);
  2240. X     if  (tsect.s_nreloc <= 0  &&  dsect.s_nreloc <= 0)
  2241. X        return    0;
  2242. X
  2243. X    nreloc = tsect.s_nreloc;
  2244. X
  2245. X    ldrseek(ldptr,1);
  2246. X     while  (nreloc-- > 0)  {
  2247. X        if  (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
  2248. X            lclash("rd trel");
  2249. X
  2250. X         pos = crel.r_vaddr;
  2251. X         mpos = crel.r_vaddr + trelpos;
  2252. X        gette(&mainfile, mpos, &mtstr);
  2253. X        if (crel.r_type == R_ABS)
  2254. X            rtype = R_NONE;
  2255. X        else
  2256. X            rtype = R_LONG;    /* what about PC-relative? */
  2257. X        ldtbread(ldptr2,crel.r_symndx,&isym);
  2258. X         lval = gettw(outf, pos, (int)rtype);
  2259. X         mval = gettw(&mainfile, mpos, (int)rtype);
  2260. X        
  2261. X        if ( isym.n_sclass != C_EXT ) {
  2262. X        switch (convtosun(&isym)) {
  2263. X         case  S_TEXT:
  2264. X            if  (lval + trelpos - outf->ef_tbase != mval)
  2265. X                lclash("Trel");
  2266. X            continue;
  2267. X         case  S_DATA:
  2268. X            if  (donedrel)  {
  2269. X                if  (lval + drelpos - outf->ef_dbase != mval)
  2270. X                    lclash("Drel");
  2271. X            }
  2272. X            else  {
  2273. X                donedrel++;
  2274. X                drelpos = mval - lval + outf->ef_dbase;
  2275. X            }
  2276. X            continue;
  2277. X         case  S_BSS:
  2278. X            if  (donebrel)  {
  2279. X                if  (lval + brelpos - outf->ef_bbase != mval)
  2280. X                    lclash("brel");
  2281. X            }
  2282. X            else  {
  2283. X                donebrel++;
  2284. X                brelpos = mval - lval + outf->ef_bbase;
  2285. X            }
  2286. X            continue;
  2287. X               }
  2288. X           } else {
  2289. X             if  (crel.r_symndx >= outf->ef_stcnt)
  2290. X                lclash("Bad sy no");
  2291. X             csymb = outf->ef_stvec[symord[crel.r_symndx]];
  2292. X            if  (csymb == NULL)
  2293. X                continue;
  2294. X            switch  (csymb->s_type)  {
  2295. X            case  S_UNDF:
  2296. X                reassign(csymb, mval - lval);
  2297. X                break;
  2298. X            case  S_ABS:
  2299. X                if  (lval + csymb->s_value != mval)
  2300. X                    lclash("abs rel");
  2301. X                break;
  2302. X            case  S_TEXT:
  2303. X                if  (lval + csymb->s_value != mval)
  2304. X                    lclash("text rel");
  2305. X                break;
  2306. X            case  S_DATA:
  2307. X                if  (lval + csymb->s_value != mval)
  2308. X                    lclash("data rel");
  2309. X                break;
  2310. X            case  S_BSS:
  2311. X                if  (lval + csymb->s_value != mval)
  2312. X                    lclash("bss rel");
  2313. X                break;
  2314. X             case  S_COMM:
  2315. X                reassign(csymb, mval - lval);
  2316. X                break;
  2317. X            }
  2318. X            mtstr.t_relsymb = csymb;
  2319. X            mtstr.t_reldisp = lval;
  2320. X        }
  2321. X    }
  2322. X    
  2323. X    /*
  2324. X     *    Relocate data and bss if possible.
  2325. X     */
  2326. X    
  2327. X    if  (donebrel)  {
  2328. X        zapdat(S_BSS, brelpos);
  2329. X        dhere++;
  2330. X    }
  2331. X    
  2332. X    if  (!donedrel)
  2333. X        return;
  2334. X        
  2335. X
  2336. X    zapdat(S_DATA, drelpos);
  2337. X    
  2338. X    /*
  2339. X     *    And now repeat all that for data relocations if possible
  2340. X     */
  2341. X    
  2342. X    nreloc = tsect.s_nreloc;
  2343. X
  2344. X    ldrseek(ldptr,2);
  2345. X    
  2346. X    while (nreloc-- > 0) {
  2347. X        if  (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
  2348. X            lclash("Rd drel");
  2349. X
  2350. X         if  (crel.r_type == R_ABS)
  2351. X            continue;
  2352. X
  2353. X         pos = crel.r_vaddr;
  2354. X         mpos = crel.r_vaddr + drelpos;
  2355. X        getde(&mainfile, mpos, &mdstr);
  2356. X        rtype = R_LONG;        /* what about PC-relative? */
  2357. X        ldtbread(ldptr2,crel.r_symndx,&isym);
  2358. X
  2359. X         lval = getdw(outf, pos, (int)rtype);
  2360. X         mval = getdw(&mainfile, mpos, (int)rtype);
  2361. X        if ( isym.n_sclass != C_EXT ) {
  2362. X        switch (convtosun(&isym)) {
  2363. X         case  S_TEXT:
  2364. X            if  (lval + trelpos - outf->ef_tbase != mval)
  2365. X                lclash("Trel-d");
  2366. X            continue;
  2367. X         case  S_DATA:
  2368. X            if  (lval + drelpos - outf->ef_dbase != mval)
  2369. X                lclash("Drel-d");
  2370. X            continue;
  2371. X         case  S_BSS:
  2372. X            if  (donebrel)  {
  2373. X                if  (lval + brelpos - outf->ef_bbase != mval)
  2374. X                    lclash("brel");
  2375. X            }
  2376. X            else  {
  2377. X                donebrel++;
  2378. X                brelpos = mval - lval + outf->ef_bbase;
  2379. X            }
  2380. X            continue;
  2381. X               }
  2382. X           } else { 
  2383. X             if  (crel.r_symndx >= outf->ef_stcnt)
  2384. X                lclash("Bad sy no");
  2385. X             csymb = outf->ef_stvec[symord[crel.r_symndx]];
  2386. X            if  (csymb == NULL)
  2387. X                continue;
  2388. X            switch  (csymb->s_type)  {
  2389. X            case  S_UNDF:
  2390. X                reassign(csymb, mval - lval);
  2391. X                break;
  2392. X            case  S_ABS:
  2393. X                if  (lval + csymb->s_value != mval)
  2394. X                    lclash("abs rel");
  2395. X                break;
  2396. X            case  S_TEXT:
  2397. X                if  (lval + csymb->s_value != mval)
  2398. X                    lclash("text rel");
  2399. X                break;
  2400. X            case  S_DATA:
  2401. X                if  (lval + csymb->s_value != mval)
  2402. X                    lclash("data rel");
  2403. X                break;
  2404. X            case  S_BSS:
  2405. X                if  (lval + csymb->s_value != mval)
  2406. X                    lclash("bss rel");
  2407. X                break;
  2408. X             case  S_COMM:
  2409. X                reassign(csymb, mval - lval);
  2410. X                break;
  2411. X            }
  2412. X            mtstr.t_relsymb = csymb;
  2413. X            mtstr.t_reldisp = lval;
  2414. X        }
  2415. X    }
  2416. X
  2417. X    if  (dhere || !donebrel)
  2418. X        return;
  2419. X
  2420. X    zapdat(S_BSS, brelpos);
  2421. X}
  2422. SHAR_EOF
  2423. chmod 0644 robj.c || echo "restore of robj.c fails"
  2424. exit 0
  2425.