home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 430_01 / m68kdis / dis.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-29  |  36.6 KB  |  1,692 lines

  1. /*
  2.  *                 Author:  Christopher G. Phillips
  3.  *              Copyright (C) 1994 All Rights Reserved
  4.  *
  5.  *                              NOTICE
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and
  8.  * its documentation for any purpose and without fee is hereby granted
  9.  * provided that the above copyright notice appear in all copies and
  10.  * that both the copyright notice and this permission notice appear in
  11.  * supporting documentation.
  12.  *
  13.  * The author makes no representations about the suitability of this
  14.  * software for any purpose.  This software is provided ``as is''
  15.  * without express or implied warranty.
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <ctype.h>
  22. #include "dis.h"
  23.  
  24. #define ISASCII(c)    (0x20 <= (c) && (c) <= 0x7e)
  25.  
  26. #ifdef DEBUG
  27. #define INITIAL        0x01
  28. #define DELETIONS    0x02
  29. #define TRY        0x04
  30. #define LASTTRY        0x08
  31. #define MAKEGOOD    0x10
  32. #define OVERLAPS    0x20
  33. #define LABELS        0x40
  34.  
  35. int    debug = 0;
  36. #endif
  37.  
  38. long        curoffset;    /* current offset into file */
  39. short        flags;        /* flags for current instruction */
  40. m68kaddr    required[3];    /* instructions that must be valid for current
  41.                    instruction to also be valid */
  42. int        pcrelative = 0;    /* used to signal that PC-relative addresses
  43.                    referenced by JMP and JSR instructions
  44.                    should be stored in ``required'' */
  45.  
  46. extern char    instbuf[];    /* used to store the nibbles of an
  47.                    instruction in hexadecimal */
  48. extern size_t    leninstbuf;    /* current length of string in instbuf */
  49.  
  50. struct inst    *insts;        /* instruction database */
  51. m68kaddr    maxoffset;    /* last offset that may hold an instruction */
  52.  
  53. /*
  54.  * These macros are used for convenience.  They do the following:
  55.  *
  56.  * NREQD(o)    returns the number of instructions instruction ``o'' depends on
  57.  * JUMP(o)    returns whether instruction ``o'' changes PC unconditionally
  58.  *        (modulo ``jfile'' instructions)
  59.  * FETCH(o,s)    returns whether instruction ``o'' is valid and has size ``s''
  60.  *        (for ``s'' positive)
  61.  * DELETE(o)    renders instruction ``o'' invalid
  62.  * SETLABEL(o)    marks instruction ``o'' as requiring a label in the output
  63.  */
  64. #define NREQD(o)    (insts[o].flags & 3)
  65. #define JUMP(o)        (insts[o].flags & (ISBRA | ISRTS | ISJMP | ISJSR))
  66. #define FETCH(o,s)    (/* (o) >= 0 && */ (o) <= maxoffset && \
  67.               ((s) == -1 && insts[o].size \
  68.               || insts[o].size == (s)))
  69. #define DELETE(o)    do { \
  70.                 free(insts[o].required); \
  71.                 insts[o].required = NULL; \
  72.                 insts[o].size = 0; \
  73.                 insts[o].flags = 0; \
  74.             } while (0);
  75. #define SETLABEL(o)    if ((o) >= initialpc && (o) <= initialpc + maxoffset) \
  76.                 insts[(o) - initialpc].flags |= ISLABEL
  77.  
  78. static short    longestinstsize;    /* max possible instruction length */
  79. static long    gfsize = 0;        /* file size */
  80. static m68kaddr    *notinsts = NULL;    /* array of values in ``nfile'' */
  81. static size_t    nnotinsts = 0;
  82. static m68kaddr    *breaks = NULL;        /* array of values in ``bfile'' */
  83. static size_t    nbreaks = 0;
  84. #ifndef NOBAD
  85. static m68kaddr    *bad;    /* addresses that cause instructions to be deleted */
  86. static m68kaddr    *good;    /* addresses that cause instructions to be accepted
  87.                in the final output */
  88. #endif
  89.  
  90. /*
  91.  * Free dynamically allocated memory
  92.  * and longjmp back to process the next object file.
  93.  */
  94. static void
  95. jumpfree(void)
  96. {
  97. #ifndef NOBAD
  98.     m68kaddr    offset;
  99.  
  100.     for (offset = 0; offset <= maxoffset; offset += (odd ? 1 : WORDSIZE)) {
  101.         if (dobad && insts[offset].size == 0)
  102.             fprintf(stderr,
  103. "%s: Instruction %lx: deleted because of %lx\n",
  104.               sfile, (long)(offset + initialpc), (long)bad[offset]);
  105.         if (insts[offset].flags & ISGOOD
  106.           && bad[offset])
  107.             fprintf(stderr,
  108. "%s: Instruction %lx: assumed good because of %lx, deleted because of %lx\n",
  109.               sfile, (long)(offset + initialpc), (long)good[offset],
  110.               (long)bad[offset]);
  111.     }
  112.     free(bad);
  113.     bad = NULL;
  114.     free(good);
  115.     good = NULL;
  116. #endif
  117.     while (gfsize--)
  118.         free(insts[gfsize].required);
  119.     free(insts);
  120.     insts = NULL;
  121.     gfsize = 0;
  122.     longjmp(jmp, 1);
  123. }
  124.  
  125. /*
  126.  * Search ``p'' for a string of at least ``minlen'' consecutive
  127.  * printable characters.  Return the index of the start of the string (or -1).
  128.  */
  129. static int
  130. findstring(size_t stored, const unsigned char *p)
  131. {
  132.     int    i;
  133.     int    inarow;
  134.  
  135.     for (inarow = i = 0; i < stored; i++, p++)
  136.         if (use_isprint && isprint(*p) || !use_isprint && ISASCII(*p)) {
  137.             if (++inarow >= minlen)
  138.                 return i - inarow + 1;
  139.         } else
  140.             inarow = 0;
  141.  
  142.     return -1;
  143. }
  144.  
  145. /*
  146.  * ``p'' contains the nibbles of a floating-point constant in hexadecimal.
  147.  * These nibbles are converted into longword values and passed to ``fpoint''
  148.  * which formats the floating-point value in ``s'' (in printable form).
  149.  */
  150. static int
  151. sfpoint(int type, const unsigned char *p, char *s)
  152. {
  153.     u32bit_t    longwords[3];
  154.     size_t        nlongwords;
  155.     size_t        i, j;
  156.  
  157.     switch (type) {
  158.     case SINGLE:    nlongwords = 1; break;
  159.     case DOUBLE:    nlongwords = 2; break;
  160.     case EXTENDED: case PACKED:
  161.             nlongwords = 3; break;
  162.     }
  163.  
  164.     /*
  165.      * Convert string to longs.
  166.      */
  167.     for (i = 0; i < nlongwords; i++) {
  168.         longwords[i] = 0;
  169.         for (j = 0; j < 2 * WORDSIZE; j++)
  170.             longwords[i] += (*p++)
  171.               << (CHAR_BIT * (2 * WORDSIZE - 1 - j));
  172.     }
  173.  
  174.     return fpoint(longwords, type, s);
  175. }
  176.  
  177. /*
  178.  * Output constants.  Return how many floating-point constants were output.
  179.  *
  180.  * todo        number of input bytes to output.
  181.  * p        nibbles of the constant(s) in hexadecimal.
  182.  * floattype    floating-point type expected (or 0).
  183.  * numforce    specifies how many floating-point constants should be output
  184.  *        regardless of value if ``floattype'' is nonzero, else specifies
  185.  *        that output must be forced if nonzero.
  186.  *
  187.  * Returns the number of bytes output.
  188.  */
  189. static size_t
  190. dcflush(size_t todo, const unsigned char *p, int floattype, int numforce)
  191. {
  192.     char        format[BUFSIZ];
  193.     int        i;
  194.     m68kaddr    value;
  195.     size_t        n;
  196.     size_t        j;
  197.     size_t        length;
  198.     int        lflags;
  199.     int        first = 1;
  200.     int        dofp;
  201.     size_t        total = todo;
  202.  
  203.     while (todo) {
  204.         lflags = ops2f(1);
  205.         if ((length = fsizeof(floattype)) == 0)
  206.             floattype = 0;
  207.  
  208.         /*
  209.          * Determine if a floating-point constant should be output.
  210.          * After forced constants are output, we stay with the
  211.          * same type until we get NaN or Denormalized.
  212.          */
  213.         dofp = 0;
  214.         if (floattype && length <= todo) {
  215.             if (sfpoint(floattype, p, format) != -1)
  216.                 dofp = 1;
  217.         }
  218.         if (floattype && --numforce >= 0 || dofp) {
  219.             dofp = 1;
  220.             lflags |= size2f(floattype);
  221.         } else if (floattype)
  222.             return total - todo;
  223.  
  224.         /*
  225.          * For integral constants, we do 2 words at a time.
  226.          * If the address is odd, we do the first byte by itself.
  227.          */
  228.         if (!dofp) {
  229.             length = 2 * WORDSIZE;
  230.             if (todo < length) {
  231.                 if (numforce)
  232.                     length = todo;
  233.                 else
  234.                     return total - todo;
  235.             }
  236.             if (first && (ppc & 1) && length != todo)
  237.                 length = 1;
  238.             if ((length % WORDSIZE) == 0) {
  239.                 lflags |= size2f(WORD);
  240.                 for (n = 0, i = 0; i < length / 2; i++) {
  241.                     for (value = 0, j = 0; j < WORDSIZE;
  242.                       j++)
  243.                         value += p[i * WORDSIZE + j]
  244.                           << (CHAR_BIT
  245.                           * (WORDSIZE - 1 - j));
  246.                         value = signextend(value, 16);
  247.                     if (i)
  248.                         n += sprintf(format + n, ",");
  249.                     n += sprintf(format + n, "#%d", value);
  250.                 }
  251.             } else {
  252.                 lflags |= size2f(BYTE);
  253.                 for (n = 0, i = 0; i < length; i++) {
  254.                     if (i)
  255.                         n += sprintf(format + n, ",");
  256.                     n += sprintf(format + n, "#%u", p[i]);
  257.                 }
  258.             }
  259.         }
  260.         leninstbuf = 0;
  261.         for (i = 0; i < length; i++)
  262.             leninstbuf += sprintf(instbuf + leninstbuf, "%02x",
  263.               p[i]);
  264.         pc += length;
  265.         instprint(lflags, "DC", format);
  266.         todo -= length;
  267.         p += length;
  268.         first = 0;
  269.     }
  270.  
  271.     return total - todo;
  272. }
  273.  
  274. /*
  275.  * Output a string.
  276.  * Return number of characters output.
  277.  */
  278. static size_t
  279. ascflush(size_t stored, const unsigned char *p, int force)
  280. {
  281.     char    format[BUFSIZ];
  282.     size_t    length;
  283.     size_t    i;
  284.     size_t    n;
  285.     size_t    left;
  286.     size_t    nbytes;
  287.  
  288.     for (length = 0; length < stored; length++)
  289.         if (use_isprint && !isprint(p[length])
  290.           || !use_isprint && !ISASCII(p[length]))
  291.             break;
  292.  
  293.     if (length == stored && !force)
  294.         return 0;
  295.  
  296.     format[0] = '\'';
  297.     left = length;
  298.  
  299.     while (left) {
  300.         n = 1;
  301.         leninstbuf = 0;
  302.  
  303.         nbytes = (left > slenprint) ? slenprint : left;
  304.  
  305.         for (i = length - left; i < length - left + nbytes; i++) {
  306.             leninstbuf += sprintf(instbuf + leninstbuf, "%02x",
  307.               p[i]);
  308.             n += sprintf(format + n, "%c", p[i]);
  309.  
  310.             /*
  311.              * Double single quotes in strings.
  312.              */
  313.             if (p[i] == '\'')
  314.                 format[n++] = '\'';
  315.         }
  316.         format[n++] = '\'';
  317.         format[n++] = '\0';
  318.         pc += nbytes;
  319.         instprint(ops2f(1) | size2f(BYTE), "DC", format);
  320.         left -= nbytes;
  321.     }
  322.  
  323.     return length;
  324. }
  325.  
  326. /*
  327.  * Convert a floating-point-label type to a floating-point type.
  328.  */
  329. static int
  330. fl2ftype(int lflags)
  331. {
  332.     if (lflags & ISLABEL) {
  333.         if (lflags & L_ISSINGLE)
  334.             return SINGLE;
  335.         if (lflags & L_ISDOUBLE)
  336.             return DOUBLE;
  337.         if (lflags & L_ISEXTENDED)
  338.             return EXTENDED;
  339.         if (lflags & L_ISPACKED)
  340.             return PACKED;
  341.     }
  342.  
  343.     return 0;
  344. }
  345.  
  346. /*
  347.  * Output the ``stored'' input bytes contained in ``consts''.
  348.  * If flags specifies a floating-point type, output floating-point
  349.  * constants of that type as long as the input looks like them.
  350.  * Output strings as appropriate.  Otherwise, output integral constants.
  351.  * Return number of input bytes *not* output.
  352.  */
  353. static size_t
  354. flush(size_t stored, const unsigned char *consts, int lflags, int force)
  355. {
  356.     size_t    length;
  357.     int    spos = -2;
  358.     int    labelfptype = fl2ftype(lflags);
  359.     int    labelfpsize = fsizeof(labelfptype);
  360.     int    first = 1;
  361.  
  362.     while (stored) {
  363.         spos = findstring(stored, consts);
  364.         if (first && labelfpsize && stored >= labelfpsize) {
  365.             if (spos == -1)
  366.                 length = stored / labelfpsize * labelfpsize;
  367.             else if (spos > labelfpsize)
  368.                 length = spos / labelfpsize * labelfpsize;
  369.             else
  370.                 length = labelfpsize;
  371.  
  372.             /*
  373.              * Force a floating-point constant.
  374.              */
  375.             length = dcflush(length, consts, labelfptype, 1);
  376.             stored -= length;
  377.             consts += length;
  378.             first = 0;
  379.             continue;
  380.         }
  381.         if (spos) {
  382.             int    lforce = 1;
  383.  
  384.             /*
  385.              * Output integral constant(s).
  386.              */
  387.             if (spos < 0) {
  388.                 if (force)
  389.                     length = stored;
  390.                 else {
  391.                     if (stored < minlen)
  392.                         return stored;
  393.                     length = stored - minlen + 1;
  394.                     lforce = 0;
  395.                 }
  396.             } else
  397.                 length = spos;
  398.             if (length > 0) {
  399.                 if ((length = dcflush(length, consts, 0,
  400.                   lforce)) == 0)
  401.                     return stored;
  402.                 stored -= length;
  403.                 consts += length;
  404.             } else
  405.                 return stored;
  406.         }
  407.         if (spos >= 0) {
  408.             /*
  409.              * Output string.
  410.              */
  411.             if ((length = ascflush(stored, consts, force)) == 0)
  412.                 return stored;
  413.             stored -= length;
  414.             consts += length;
  415.         }
  416.         first = 0;
  417.     }
  418.  
  419.     return 0;
  420. }
  421.  
  422. /*
  423.  * Read a word (and extension words as necessary) from the input file
  424.  * and determine if it is a possible instruction.
  425.  *
  426.  * ``valid'' is set to signal this.
  427.  */
  428. static int
  429. validinst(void)
  430. {
  431.     m68kword    inst;
  432.  
  433.     valid = 0;
  434.  
  435.     if (nextword(&inst) == 0) {
  436.         switch (inst >> 12) {
  437.         case 0:
  438.             bit_movep_immediate(inst);
  439.             break;
  440.         case 1:
  441.             movebyte(inst);
  442.             break;
  443.         case 2:
  444.             movelong(inst);
  445.             break;
  446.         case 3:
  447.             moveword(inst);
  448.             break;
  449.         case 4:
  450.             misc(inst);
  451.             break;
  452.         case 5:
  453.             addq_subq_scc_dbcc_trapcc(inst);
  454.             break;
  455.         case 6:
  456.             valid = bcc_bsr(inst);
  457.             break;
  458.         case 7:
  459.             moveq(inst);
  460.             break;
  461.         case 8:
  462.             or_div_sbcd(inst);
  463.             break;
  464.         case 9:
  465.             sub_subx(inst);
  466.             break;
  467.         case 10:
  468.             aline(inst);
  469.             break;
  470.         case 11:
  471.             cmp_eor(inst);
  472.             break;
  473.         case 12:
  474.             and_mul_abcd_exg(inst);
  475.             break;
  476.         case 13:
  477.             add_addx(inst);
  478.             break;
  479.         case 14:
  480.             shift_rotate_bitfield(inst);
  481.             break;
  482.         case 15:
  483.             coprocessor(inst);
  484.             if (!valid)
  485.                 fline(inst);
  486.             break;
  487.         }
  488.     }
  489.  
  490.     return valid;
  491. }
  492.  
  493. /*
  494.  * Now that we know where the constants are, make another pass
  495.  * to determine which of them are referenced using the PC-relative
  496.  * addressing mode.
  497.  */
  498. static void
  499. dcpass(void)
  500. {
  501.     m68kaddr    offset;
  502.  
  503.     pass = DCLABELSPASS;
  504.     if (fseek(infp, 0, SEEK_SET) == -1) {
  505.         perror("fseek");
  506.         jumpfree();
  507.     }
  508.     for (curoffset = offset = 0; offset <= maxoffset; )
  509.         if (insts[offset].size) {
  510.             if (curoffset != offset
  511.               && fseek(infp, curoffset = offset, SEEK_SET) == -1) {
  512.                 perror("fseek");
  513.                 jumpfree();
  514.             }
  515.             flags = 0;
  516.             pc = ppc = offset + initialpc;
  517.             leninstbuf = 0;
  518.             validinst();
  519.             offset += insts[offset].size;
  520.         } else if (odd)
  521.             offset++;
  522.         else
  523.             offset += WORDSIZE;
  524. }
  525.  
  526. /*
  527.  * Make a pass over the input, outputting things as we currently see them.
  528.  */
  529. static void
  530. printall(void)
  531. {
  532.     m68kaddr    offset;
  533.     unsigned char    consts[BUFSIZ];
  534.     size_t        stored = 0;
  535.  
  536.     if (fseek(infp, 0, SEEK_SET) == -1) {
  537.         perror("fseek");
  538.         jumpfree();
  539.     }
  540.     pc = ppc = initialpc;
  541.     leninstbuf = 0;
  542.     pass = DEBUGPASS;
  543.     for (curoffset = offset = 0; offset < gfsize /* = maxoffset */;
  544.       offset += (odd ? 1 : WORDSIZE)) {
  545.         /*
  546.          * Determine if there might be a valid instruction
  547.          * which has the bytes at ``offset'' as operands.
  548.          */
  549.         if (insts[offset].size == 0) {
  550.             int    i = 0;
  551.             size_t    size;
  552.  
  553.             for (size = odd ? 1 : WORDSIZE; size <= longestinstsize
  554.               && size <= offset; size += (odd ? 1 : WORDSIZE))
  555.                 if (size < insts[offset - size].size) {
  556.                     i = 1;
  557.                     break;
  558.                 }
  559.             if (i)
  560.                 continue;
  561.         }
  562.  
  563.         if (curoffset != offset
  564.           && fseek(infp, curoffset = offset, SEEK_SET) == -1) {
  565.             perror("fseek");
  566.             jumpfree();
  567.         }
  568.         flags = 0;
  569.         if (insts[offset].size) {
  570.             if (stored) {
  571.                 flush(stored, consts, 0, 1);
  572.                 stored = 0;
  573.             }
  574.  
  575.             pc = ppc = initialpc + offset;
  576.             leninstbuf = 0;
  577.             validinst();
  578.         } else {
  579.             size_t    i;
  580.  
  581.             if (stored == 0)
  582.                 pc = ppc = initialpc + offset;
  583.             for (i = 0; i < WORDSIZE; i++)
  584.                 if (fread(consts + stored, 1, 1, infp) == 1)
  585.                     if (++stored >= sizeof consts) {
  586.                         stored = flush(stored, consts,
  587.                           0, 0);
  588.                         memmove(consts, consts
  589.                           + sizeof consts - stored,
  590.                           stored);
  591.                     }
  592.  
  593.         }
  594.     }
  595.  
  596.     if (stored)
  597.         flush(stored, consts, 0, 1);
  598.  
  599.     fflush(NULL);
  600. }
  601.  
  602. /*
  603.  * Make the first pass over the input.
  604.  * Gather references to other addresses.
  605.  */
  606. void
  607. pass1(void)
  608. {
  609.     m68kaddr    offset;
  610.  
  611.     pass = FIRSTPASS;
  612.     for (curoffset = offset = 0; offset <= maxoffset;
  613.       offset += (odd ? 1 : WORDSIZE)) {
  614.         if (curoffset != offset
  615.           && fseek(infp, curoffset = offset, SEEK_SET) == -1) {
  616.             perror("fseek");
  617.             jumpfree();
  618.         }
  619.         flags = 0;
  620.         pc = ppc = offset + initialpc;
  621.         leninstbuf = 0;
  622.         if (validinst()) {
  623.             /*
  624.              * It's a potential instruction.
  625.              */
  626.             insts[offset].size = curoffset - offset;
  627.             insts[offset].flags = flags;
  628.             if (flags & 3) {
  629.                 m68kaddr    *reqd;
  630.  
  631.                 if ((reqd = malloc((flags & 3) * sizeof(*reqd)))
  632.                   == NULL) {
  633.                     perror("malloc");
  634.                     jumpfree();
  635.                 }
  636.                 switch (flags & 3) {
  637.                 case 3:    reqd[2] = required[2];
  638.                 case 2:    reqd[1] = required[1];
  639.                 case 1:    reqd[0] = required[0];
  640.                 }
  641.                 insts[offset].required = reqd;
  642.             } else
  643.                 insts[offset].required = NULL;
  644. #ifdef DEBUG
  645.             if (debug & INITIAL) {
  646.                 int    i;
  647.  
  648.                 fprintf(outfp,
  649.                   "Writing offset = %lx, size = %d, flags = %d",
  650.                   (long)offset, insts[offset].size,
  651.                   insts[offset].flags);
  652.                 for (i = 0; i < (insts[offset].flags & 3); i++)
  653.                     fprintf(outfp, ", reqd = %lx",
  654.                       (long)insts[offset].required[i]);
  655.                 fprintf(outfp, "\n");
  656.             }
  657. #endif
  658.         }
  659.         else {
  660. #ifndef NOBAD
  661.             bad[offset] = offset + initialpc;
  662. #endif
  663. #ifdef DEBUG
  664.             if (debug & DELETIONS)
  665.                 fprintf(outfp, "0. Deleting offset %lx\n",
  666.                   (long)offset);
  667. #endif
  668.         }
  669.     }
  670.  
  671. #if !defined(NOBAD) || defined(DEBUG)
  672.     for (offset = maxoffset + (odd ? 1 : WORDSIZE);
  673.       offset <= maxoffset + longestinstsize;
  674.       offset += (odd ? 1 : WORDSIZE)) {
  675. #ifndef NOBAD
  676.         if (offset <= maxoffset)
  677.             bad[offset] = offset + initialpc;
  678. #endif
  679. #ifdef DEBUG
  680.         if (debug & DELETIONS)
  681.             fprintf(outfp, "0. Deleting offset %lx\n",
  682.               (long)offset);
  683. #endif
  684.     }
  685. #endif
  686. }
  687.  
  688. /*
  689.  * Make a pass over the instruction database, checking for consistency.
  690.  */
  691. void
  692. findbadrefs(void)
  693. {
  694.     long    offset;        /* must be signed */
  695.     long    offset2;    /* must be signed */
  696.     int    i;
  697.     size_t    size;
  698.     int    changes;
  699.     int    try = 0;
  700. #if 0
  701.     int totalchanges = 0;
  702. #endif
  703.  
  704. #ifdef DEBUG
  705.     if (debug & TRY) {
  706.         printall();
  707.         fprintf(outfp, "\n\n\n");
  708.     }
  709. #endif
  710.  
  711.     /*
  712.      * Instructions that don't set PC
  713.      * must be followed by a valid instruction.
  714.      */
  715.     do {
  716.         changes = 0;
  717.         try++;
  718.         for (offset = maxoffset + longestinstsize; offset >= 0;
  719.           offset -= (odd ? 1 : WORDSIZE)) {
  720.             /*
  721.              * Back up to a possible instruction.
  722.              * We do this to jump over a large data section.
  723.              */
  724.             for (offset2 = offset; offset2 >= 0
  725.               && insts[offset2].size == 0;
  726.               offset2 -= (odd ? 1 : WORDSIZE))
  727.                 ;
  728.             if (offset2 < 0)
  729.                 break;
  730.             if (offset2 + longestinstsize < offset)
  731.                 offset = offset2 + longestinstsize;
  732.  
  733.             if (!linkfallthrough && (insts[offset].flags & ISLINK)
  734.               || !FETCH(offset, -1)) {
  735.                 /*
  736.                  * We've found an invalid instruction.
  737.                  * See if any instructions advance PC here
  738.                  * based on the size of the instruction
  739.                  * and its operands.
  740.                  */
  741.                 for (size = odd ? 1 : WORDSIZE;
  742.                   size <= longestinstsize && size <= offset;
  743.                   size += (odd ? 1 : WORDSIZE))
  744.                     if (FETCH(offset - size, size)
  745.                       && !JUMP(offset - size)) {
  746. #ifndef NOBAD
  747.                         if (!linkfallthrough
  748.                           && (insts[offset].flags
  749.                           & ISLINK))
  750.                             bad[offset - size]
  751.                               = offset + initialpc;
  752.                         else
  753.                             bad[offset - size]
  754.                               = bad[offset];
  755. #endif
  756. #ifdef DEBUG
  757.                         if (debug & DELETIONS)
  758. fprintf(outfp,
  759.   "1. Deleting offset %lx, size %d, flags = %d\n", (long)(offset - size),
  760.   size, insts[offset - size].flags);
  761. #endif
  762.                         DELETE(offset - size);
  763.                         changes++;
  764.                     }
  765.             }
  766.         }
  767.  
  768.         /*
  769.          * See if any instructions require
  770.          * an invalid instruction to be valid.
  771.          */
  772.         for (offset2 = 0; offset2 <= maxoffset;
  773.           offset2 += (odd ? 1 : WORDSIZE)) {
  774.             if (insts[offset2].size == 0)
  775.                 continue;
  776.             for (i = 0; i < NREQD(offset2); i++)
  777.                 if (insts[offset2].required[i] >= initialpc
  778.                   && insts[offset2].required[i] <= initialpc
  779.                   + maxoffset
  780.                   && !FETCH(insts[offset2].required[i]
  781.                   - initialpc, -1)) {
  782. #ifndef NOBAD
  783.                     bad[offset2]
  784.                       = bad[insts[offset2].required[i]
  785.                       - initialpc];
  786. #endif
  787. #ifdef DEBUG
  788.                     if (debug & DELETIONS)
  789. fprintf(outfp, "2. Deleting offset %lx, size %d because %lx is not valid\n",
  790. (long)offset2, insts[offset2].size, (long)insts[offset2].required[i]);
  791. #endif
  792.                     DELETE(offset2);
  793.                     changes++;
  794.                     break;
  795.                 }
  796.         }
  797.  
  798. #ifdef DEBUG
  799.         if (debug & TRY) {
  800.             fprintf(outfp,
  801.               "TRY %d ###############################\n", try);
  802.             printall();
  803.             fprintf(outfp, "\n\n\n");
  804.         }
  805. #endif
  806. #if 0
  807.         totalchanges += changes;
  808. #endif
  809.     } while (changes);
  810.  
  811. #if 0
  812.     printf("Tries = %d\n", (int)try);
  813.     printf("Changes = %d\n", (int)totalchanges);
  814. #endif
  815.  
  816. #ifdef DEBUG
  817.     if (debug & LASTTRY) {
  818.         fprintf(outfp, "TRY %d ###############################\n",
  819.           try - 1);
  820.         printall();
  821.         fprintf(outfp, "\n\n\n");
  822.     }
  823. #endif
  824. }
  825.  
  826. struct queue {
  827.     m68kaddr    address;
  828.     struct queue    *next;
  829. };
  830.  
  831. /*
  832.  * The ``writeq'' and ``readq'' functions
  833.  * maintain a queue of addresses for ``makegood''.
  834.  */
  835.  
  836. static struct queue    head = { 0, NULL };
  837.  
  838. /*
  839.  * Add to the queue.
  840.  */
  841. static void
  842. writeq(m68kaddr address)
  843. {
  844.     struct queue    *tail;
  845.     struct queue    *newq;
  846.  
  847.     if ((newq = malloc(sizeof(*newq))) == NULL) {
  848.         perror("malloc");
  849.         jumpfree();
  850.     }
  851.     newq->address = address;
  852.  
  853. #ifdef DEBUG
  854.     if (debug & MAKEGOOD)
  855.         fprintf(outfp, "Wrote offset = %lx\n", (long)address);
  856. #endif
  857.  
  858.     newq->next = NULL;
  859.  
  860.     for (tail = &head; tail->next; tail = tail->next)
  861.         ;
  862.     tail->next = newq;
  863. }
  864.  
  865. /*
  866.  * Read (and delete) from the queue.
  867.  */
  868. static struct queue *
  869. readq(void)
  870. {
  871.     struct queue    *result;
  872.  
  873.     if (head.next) {
  874.         result = head.next;
  875.         head.next = head.next->next;
  876.  
  877. #ifdef DEBUG
  878.         if (debug & MAKEGOOD)
  879.             fprintf(outfp, "Read offset = %lx\n",
  880.               (long)result->address);
  881. #endif
  882.     } else
  883.         result = NULL;
  884.  
  885.     return result;
  886. }
  887.  
  888. /*
  889.  * Mark ``offset'' as an instruction to be included in the final output.
  890.  * Recursively mark as good all instructions that reference it.
  891.  * Delete instructions that contradict those marked good.
  892.  * Return the number off offsets deleted.
  893.  */
  894. static unsigned
  895. makegood(m68kaddr offset)
  896. {
  897.     size_t        size;
  898.     struct queue    *qptr = NULL;
  899.     m68kaddr    origoffset = offset;
  900.     unsigned    deletions = 0;
  901.  
  902.     if (insts[offset].flags & ISGOOD)
  903.         return deletions;
  904.  
  905. #ifdef DEBUG
  906.     if (debug & MAKEGOOD)
  907.         fprintf(outfp, "makegood(%lx)\n", (long)offset);
  908. #endif
  909.  
  910.     do {
  911.         if (qptr) {
  912.             offset = qptr->address;
  913.             free(qptr);
  914.         }
  915.  
  916. #ifdef DEBUG
  917.         if (debug & MAKEGOOD)
  918.             fprintf(outfp, "Going with offset = %lx\n",
  919.               (long)offset);
  920. #endif
  921.  
  922.         while (1) {
  923.  
  924. #ifdef DEBUG
  925.             if (debug & MAKEGOOD)
  926.                 fprintf(outfp, "Offset = %lx\n", (long)offset);
  927. #endif
  928.  
  929.             if (insts[offset].size == 0 ||
  930.               insts[offset].flags & ISGOOD)
  931.                 break;
  932.  
  933.             /*
  934.              * We have a ``good'' instruction.
  935.              * Instructions that overlap it should be deleted.
  936.              */
  937.             for (size = odd ? 1 : WORDSIZE; size < longestinstsize
  938.               && size + maxoffset >= offset && size <= offset;
  939.               size += (odd ? 1 : WORDSIZE))
  940.                 if (insts[offset - size].size > size) {
  941. #ifndef NOBAD
  942.                     bad[offset - size] = origoffset
  943.                       + initialpc;
  944. #endif
  945. #ifdef DEBUG
  946.                     if (debug & DELETIONS)
  947. fprintf(outfp, "3. Deleting offset %lx, size %d, flags = %d because of %lx\n",
  948.   (long)(offset - size), insts[offset - size].size, insts[offset - size].flags,
  949.   (long)offset);
  950. #endif
  951.                     DELETE(offset - size);
  952.                     deletions++;
  953.                 }
  954.             for (size = odd ? 1 : WORDSIZE;
  955.               size < insts[offset].size
  956.               && maxoffset >= offset + size;
  957.               size += (odd ? 1 : WORDSIZE))
  958.                 if (insts[offset + size].size) {
  959. #ifndef NOBAD
  960.                     bad[offset + size] = origoffset
  961.                       + initialpc;
  962. #endif
  963. #ifdef DEBUG
  964.                     if (debug & DELETIONS)
  965. fprintf(outfp, "4. Deleting offset %lx, size %d, flags = %d because of %lx\n",
  966.   (long)(offset + size), insts[offset + size].size, insts[offset + size].flags,
  967.   (long)offset);
  968. #endif
  969.                     DELETE(offset + size);
  970.                     deletions++;
  971.                 }
  972.  
  973.             insts[offset].flags |= ISGOOD;
  974. #ifndef NOBAD
  975.             good[offset] = origoffset + initialpc;
  976. #endif
  977.             if ((insts[offset].flags & ISBRA)
  978.               || ((insts[offset].flags & ISJMP) &&
  979.               insts[offset].flags & 3)) {
  980.                 if (insts[offset].required[0] >= initialpc
  981.                   && insts[offset].required[0] <= initialpc
  982.                   + maxoffset)
  983.                     offset = insts[offset].required[0]
  984.                       - initialpc;
  985.                 else
  986.                     break;
  987.             } else if ((insts[offset].flags
  988.               & (ISBSR | ISJSR | ISBRA | ISBRcc | ISDBcc | ISJMP))
  989.               && (insts[offset].flags & 3)
  990.               && insts[offset].required[0] >= initialpc
  991.               && insts[offset].required[0] <= initialpc
  992.               + maxoffset) {
  993.                 writeq(insts[offset].required[0] - initialpc);
  994.                 offset += insts[offset].size;
  995.             } else if (insts[offset].flags & (ISRTS | ISJMP))
  996.                 break;
  997.             else
  998.                 offset += insts[offset].size;
  999.         }
  1000.     } while (qptr = readq());
  1001.  
  1002.     return deletions;
  1003. }
  1004.  
  1005. /*
  1006.  * Determine the number of remaining instances
  1007.  * of still-valid instructions overlapping each other.
  1008.  */
  1009. static long
  1010. overlaps(int list)
  1011. {
  1012.     long    num = 0;
  1013.     long    offset;
  1014.     size_t    size;
  1015.  
  1016.     for (offset = 0; offset <= maxoffset; offset += (odd ? 1 : WORDSIZE)) {
  1017.         if (insts[offset].size == 0)
  1018.             continue;
  1019.  
  1020.         for (size = odd ? 1 : WORDSIZE; size < longestinstsize
  1021.           && size <= offset; size += (odd ? 1 : WORDSIZE))
  1022.             if (insts[offset - size].size > size) {
  1023.                 num++;
  1024.                 if (list)
  1025.                     fprintf(stderr, "%s: Overlap at %lx\n",
  1026.                       sfile, offset);
  1027.             }
  1028.     }
  1029.  
  1030.     return num;
  1031. }
  1032.  
  1033. /*
  1034.  * Starting from ``offset'', return the next highest offset
  1035.  * containing an instruction marked good (or -1).
  1036.  */
  1037. static long
  1038. nextgood(m68kaddr offset)
  1039. {
  1040.     long    next;
  1041.  
  1042.     for (next = offset + (odd ? 1 : WORDSIZE); next <= maxoffset
  1043.       && (insts[next].size == 0 || (insts[next].flags & ISGOOD) == 0);
  1044.       next += (odd ? 1 : WORDSIZE))
  1045.         ;
  1046.  
  1047.     return (next > maxoffset) ? -1 : next;
  1048. }
  1049.  
  1050. /*
  1051.  * Return whether program flow reaches address ``target''
  1052.  * starting from address ``prevonly''.
  1053.  */
  1054. static int
  1055. reach(m68kaddr prevonly, m68kaddr target)
  1056. {
  1057.     m68kaddr    offset;
  1058.  
  1059.     for (offset = prevonly; insts[offset].size && offset < target;
  1060.       offset += insts[offset].size)
  1061.         ;
  1062.  
  1063.     return offset == target;
  1064. }
  1065.  
  1066. /*
  1067.  * Fix the overlap situation.
  1068.  * Do this by minimizing the amount of data (constants) in the input.
  1069.  */
  1070. static unsigned
  1071. fixoverlaps(void)
  1072. {
  1073.     m68kaddr    offset;
  1074.     m68kaddr    goodone = nextgood(0);
  1075.     unsigned    deletions = 0;
  1076.  
  1077.     for (offset = 0; offset <= maxoffset; ) {
  1078.         if (insts[offset].size == 0) {
  1079.             if (odd)
  1080.                 offset++;
  1081.             else
  1082.                 offset += WORDSIZE;
  1083.             continue;
  1084.         }
  1085.         if (insts[offset].flags & ISGOOD) {
  1086.             offset += insts[offset].size;
  1087.             continue;
  1088.         }
  1089.  
  1090.         if (/*goodone >= 0 &&*/ goodone <= offset)
  1091.             goodone = nextgood(offset);
  1092.  
  1093.         if (reach(offset, goodone))
  1094.             deletions += makegood(offset);
  1095.         else if (odd)
  1096.             offset++;
  1097.         else
  1098.             offset += WORDSIZE;
  1099.     }
  1100.  
  1101.     return deletions;
  1102. }
  1103.  
  1104. static int
  1105. addrcmp(const void *p1, const void *p2)
  1106. {
  1107.     m68kaddr    a1 = *(m68kaddr *)p1;
  1108.     m68kaddr    a2 = *(m68kaddr *)p2;
  1109.  
  1110.     if (a1 < a2)
  1111.         return -1;
  1112.     else if (a1 > a2)
  1113.         return 1;
  1114.     else
  1115.         return 0;
  1116. }
  1117.  
  1118. /*
  1119.  * Return whether a ``math'' FPU instruction
  1120.  * has the word at ``offset'' as an extension word.
  1121.  */
  1122. static int
  1123. fpuoverlap(m68kaddr offset)
  1124. {
  1125.     size_t    size;
  1126.  
  1127.     if (!FPU(chip) || (insts[offset].flags & (ISBSR | ISBRA | ISBRcc)) == 0)
  1128.         return 0;
  1129.  
  1130.     for (size = 1; size < longestinstsize && size <= offset; size++)
  1131.         if (insts[offset - size].size > size
  1132.           && insts[offset - size].flags & ISFPU)
  1133.             return 1;
  1134.  
  1135.     return 0;
  1136. }
  1137.  
  1138. /*
  1139.  * Disassemble!
  1140.  */
  1141. void
  1142. disassemble(void)
  1143. {
  1144.     m68kaddr    offset;
  1145.     long        fsize;
  1146.     int        changes;
  1147.     int        total_changes;
  1148.     short        nlabels;
  1149.     int        i;
  1150.     unsigned char    consts[BUFSIZ];
  1151.     size_t        stored = 0;
  1152.     size_t        curnbreak;
  1153.     static int    breakssaved = 0;
  1154.  
  1155.     /*
  1156.      * Determine the longest possible length of an instruction in words.
  1157.      */
  1158.     switch (CPU(chip)) {
  1159.     case MC68000:
  1160.     case MC68010:
  1161.         longestinstsize = 10;
  1162.         break;
  1163.     case MC68020:
  1164.     case MC68030:
  1165.     default:
  1166.         if (FPU(chip))
  1167.             longestinstsize = 20;
  1168.         else
  1169.             longestinstsize = 20;
  1170.         break;
  1171.     }
  1172.  
  1173.     /*
  1174.      * Determine the size of the input file.
  1175.      */
  1176.     if (fseek(infp, 0, SEEK_END) == -1) {
  1177.         perror("fseek");
  1178.         jumpfree();
  1179.     }
  1180.     if ((gfsize = fsize = ftell(infp)) == -1) {
  1181.         perror("ftell");
  1182.         jumpfree();
  1183.     } else if (fsize < WORDSIZE)
  1184.         jumpfree();
  1185.     if (fseek(infp, 0, SEEK_SET) == -1) {
  1186.         perror("fseek");
  1187.         jumpfree();
  1188.     }
  1189.     maxoffset = (fsize - (WORDSIZE - 1)) & ~(WORDSIZE - 1);
  1190.  
  1191.     /*
  1192.      * Malloc and initialize instruction structures.
  1193.      */
  1194.     if ((insts = malloc((fsize + maxoffset) * sizeof(*insts))) == NULL) {
  1195.         perror("malloc");
  1196.         jumpfree();
  1197.     }
  1198. #ifndef NOBAD
  1199.     if ((bad = malloc(fsize * sizeof(*bad))) == NULL
  1200.       || (good = malloc(fsize * sizeof(*good))) == NULL) {
  1201.         perror("malloc");
  1202.         jumpfree();
  1203.     }
  1204.     memset(bad, '\0', fsize * sizeof(*bad));
  1205.     memset(good, '\0', fsize * sizeof(*good));
  1206.     if (!odd) {
  1207.         size_t    i;
  1208.  
  1209.         for (i = 1; i < fsize; i += 2)
  1210.             bad[i] = i + initialpc;
  1211.     }
  1212. #endif
  1213.     memset(insts, '\0', (fsize + maxoffset) * sizeof(*insts));
  1214.     while (fsize--)
  1215.         insts[fsize].required = NULL;
  1216.  
  1217.     /*
  1218.      * Pass 1:
  1219.      *
  1220.      * Determine where the code is and where the data is.
  1221.      */
  1222.     pass1();
  1223.  
  1224.     if (onepass == INCONSISTENT) {
  1225.         printall();
  1226.         jumpfree();
  1227.     }
  1228.  
  1229.     /*
  1230.      * Process offsets specified by the user
  1231.      * as places in data to start a new line of output.
  1232.      */
  1233.     if (bfile && !breakssaved) {
  1234.         FILE    *bfp;
  1235.  
  1236.         if (bfp = fopen(bfile, "r")) {
  1237.             char        bbuf[80];
  1238.             unsigned long    ul;
  1239.             char        *cp;
  1240.             m68kaddr    *tmp;
  1241.  
  1242.             while (fgets(bbuf, sizeof bbuf, bfp)) {
  1243.                 ul = strtoul(bbuf, &cp, 0);
  1244.                 if (cp != bbuf && (odd || (ul & 1) == 0)) {
  1245.                     if (ul >= initialpc && ul <= initialpc
  1246.                       + maxoffset) {
  1247.                         offset = ul - initialpc;
  1248.                         if (tmp = realloc(breaks,
  1249.                           (nbreaks + 1)
  1250.                           * sizeof(*breaks))) {
  1251.                             breaks = tmp;
  1252.                             breaks[nbreaks++]
  1253.                               = offset;
  1254.                         }
  1255.                     } else
  1256.                         fprintf(outfp,
  1257.                           "File %s: bad pc: %s\n",
  1258.                           bfile, bbuf);
  1259.                 } else
  1260.                     fprintf(outfp,
  1261.                       "File %s: bad pc: %s\n", bfile, bbuf);
  1262.             }
  1263.             (void)fclose(bfp);
  1264.             qsort(breaks, nbreaks, sizeof(*breaks), addrcmp);
  1265.         } else
  1266.             perror(bfile);
  1267.         breakssaved = 1;
  1268.     }
  1269.  
  1270.     /*
  1271.      * Process offsets specified by the user as being data.
  1272.      */
  1273.     if (nfile) {
  1274.         FILE        *nfp;
  1275.         static int    notinstssaved = 0;
  1276.  
  1277.         if (nfp = fopen(nfile, "r")) {
  1278.             char        nbuf[80];
  1279.             unsigned long    ul;
  1280.             char        *cp;
  1281.             m68kaddr    *nottmp;
  1282.             size_t        size;
  1283.  
  1284.             while (fgets(nbuf, sizeof nbuf, nfp)) {
  1285.                 ul = strtoul(nbuf, &cp, 0);
  1286.                 if (cp != nbuf && (odd || (ul & 1) == 0)) {
  1287.                     if (ul >= initialpc && ul <= initialpc
  1288.                       + maxoffset) {
  1289.                         offset = ul - initialpc;
  1290.                         if (nottmp = realloc(notinsts,
  1291.                           (nnotinsts + 1)
  1292.                           * sizeof(*notinsts))) {
  1293.                             notinsts = nottmp;
  1294.                             notinsts[nnotinsts++]
  1295.                               = offset;
  1296.                         }
  1297.  
  1298.         for (size = 1; size < longestinstsize && size <= offset; size++)
  1299.             if (insts[offset - size].size > size) {
  1300. #ifndef NOBAD
  1301.                 bad[offset - size] = (insts[offset].size)
  1302.                   ? offset + initialpc : bad[offset];
  1303. #endif
  1304. #ifdef DEBUG
  1305.                 if (debug & DELETIONS)
  1306. fprintf(outfp,
  1307.   "5. Deleting offset %lx, size %d, flags = %d because %lx specified\n",
  1308.   (long)(offset - size), insts[offset - size].size, insts[offset - size].flags,
  1309.   (long)offset);
  1310. #endif
  1311.                 DELETE(offset - size);
  1312.             }
  1313.  
  1314.                         if (insts[offset].size) {
  1315. #ifndef NOBAD
  1316.                             bad[offset] = offset
  1317.                               + initialpc;
  1318. #endif
  1319. #ifdef DEBUG
  1320.                             if (debug & DELETIONS)
  1321. fprintf(outfp,
  1322.   "6. Deleting offset %lx, size %d, flags = %d because specified\n",
  1323.   (long)offset, insts[offset].size, insts[offset].flags);
  1324. #endif
  1325.                             DELETE(offset);
  1326.                         }
  1327.                     } else
  1328.                         fprintf(outfp,
  1329.                           "File %s: bad pc: %s\n",
  1330.                           nfile, nbuf);
  1331.                 } else
  1332.                     fprintf(outfp,
  1333.                       "File %s: bad pc: %s\n", nfile, nbuf);
  1334.             }
  1335.             (void)fclose(nfp);
  1336.             if (!notinstssaved) {
  1337.                 qsort(notinsts, nnotinsts, sizeof(*notinsts),
  1338.                   addrcmp);
  1339.                 notinstssaved = 1;
  1340.             }
  1341.         } else
  1342.             perror(nfile);
  1343.     }
  1344.  
  1345.     /*
  1346.      * Process offsets specified by the user
  1347.      * as not being the start of valid instructions.
  1348.      */
  1349.     if (nsfile) {
  1350.         FILE        *nfp;
  1351.         static int    notinstssaved = 0;
  1352.  
  1353.         if (nfp = fopen(nsfile, "r")) {
  1354.             char        nbuf[80];
  1355.             unsigned long    ul;
  1356.             char        *cp;
  1357.             m68kaddr    *nottmp;
  1358.  
  1359.             while (fgets(nbuf, sizeof nbuf, nfp)) {
  1360.                 ul = strtoul(nbuf, &cp, 0);
  1361.                 if (cp != nbuf && (odd || (ul & 1) == 0)) {
  1362.                     if (ul >= initialpc && ul <= initialpc
  1363.                       + maxoffset) {
  1364.                         offset = ul - initialpc;
  1365.                         if (nottmp = realloc(notinsts,
  1366.                           (nnotinsts + 1)
  1367.                           * sizeof(*notinsts))) {
  1368.                             notinsts = nottmp;
  1369.                             notinsts[nnotinsts++]
  1370.                               = offset;
  1371.                         }
  1372.  
  1373.                         if (insts[offset].size) {
  1374. #ifndef NOBAD
  1375.                             bad[offset] = offset
  1376.                               + initialpc;
  1377. #endif
  1378. #ifdef DEBUG
  1379.                             if (debug & DELETIONS)
  1380. fprintf(outfp,
  1381.   "6. Deleting offset %lx, size %d, flags = %d because specified\n",
  1382.   (long)offset, insts[offset].size, insts[offset].flags);
  1383. #endif
  1384.                             DELETE(offset);
  1385.                         }
  1386.                     } else
  1387.                         fprintf(outfp,
  1388.                           "File %s: bad pc: %s\n",
  1389.                           nsfile, nbuf);
  1390.                 } else
  1391.                     fprintf(outfp,
  1392.                       "File %s: bad pc: %s\n", nsfile,
  1393.                       nbuf);
  1394.             }
  1395.             (void)fclose(nfp);
  1396.             if (!notinstssaved) {
  1397.                 qsort(notinsts, nnotinsts, sizeof(*notinsts),
  1398.                   addrcmp);
  1399.                 notinstssaved = 1;
  1400.             }
  1401.         } else
  1402.             perror(nsfile);
  1403.     }
  1404.  
  1405.     /*
  1406.      * Process offsets specified by the user as being instructions.
  1407.      * Note that does *not* make an invalid instruction suddenly valid.
  1408.      */
  1409.     if (ifile) {
  1410.         FILE    *ifp;
  1411.  
  1412.         if (ifp = fopen(ifile, "r")) {
  1413.             char        ibuf[80];
  1414.             unsigned long    ul;
  1415.             char        *cp;
  1416.  
  1417.             while (fgets(ibuf, sizeof ibuf, ifp)) {
  1418.                 ul = strtoul(ibuf, &cp, 0);
  1419.                 if (cp != ibuf && (odd || (ul & 1) == 0)) {
  1420.                     if (ul >= initialpc && ul <= initialpc
  1421.                       + maxoffset)
  1422.                         makegood(ul - initialpc);
  1423.                     else
  1424.                         fprintf(outfp,
  1425.                           "File %s: bad pc: %s\n",
  1426.                           ifile, ibuf);
  1427.                 } else
  1428.                     fprintf(outfp,
  1429.                       "File %s: bad pc: %s\n", ifile, ibuf);
  1430.             }
  1431.             (void)fclose(ifp);
  1432.         } else
  1433.             perror(ifile);
  1434.     }
  1435.  
  1436.     /*
  1437.      * Instructions that don't set PC
  1438.      * must be followed by a valid instruction.
  1439.      *
  1440.      * Instructions must reference valid instructions.
  1441.      */
  1442.     findbadrefs();
  1443.  
  1444.     if (onepass == CONSISTENT) {
  1445.         printall();
  1446.         jumpfree();
  1447.     }
  1448.  
  1449.     /*
  1450.      * Assume that all LINK instructions that are referenced
  1451.      * by BSR or JSR instructions are valid.
  1452.      */
  1453.     for (offset = 0; offset <= maxoffset; offset += (odd ? 1 : WORDSIZE))
  1454.         if (insts[offset].size
  1455.           && (insts[offset].flags & (ISBSR | ISJSR))
  1456.           && (insts[offset].flags & 3)
  1457.           && insts[offset].required[0] >= initialpc
  1458.           && insts[offset].required[0] <= initialpc + maxoffset
  1459.           && (insts[insts[offset].required[0] - initialpc].flags
  1460.           & ISLINK)) {
  1461. #ifdef DEBUG
  1462.             if (debug & OVERLAPS)
  1463.                 fprintf(outfp,
  1464.                   "Number of overlaps = %ld\n", overlaps(0));
  1465. #endif
  1466.             makegood(insts[offset].required[0] - initialpc);
  1467.         }
  1468.  
  1469.     findbadrefs();
  1470.  
  1471. #ifdef DEBUG
  1472.     if (debug & OVERLAPS)
  1473.         fprintf(outfp,
  1474.           "Number of overlaps after LINKs with labels = %ld\n",
  1475.           overlaps(0));
  1476. #endif
  1477.  
  1478.     /*
  1479.      * Assume that all remaining LINK instructions are valid.
  1480.      */
  1481.     total_changes = 0;
  1482.     for (offset = 0; offset <= maxoffset; offset += (odd ? 1 : WORDSIZE))
  1483.         if (insts[offset].size
  1484.           && (insts[offset].flags & ISGOOD) == 0
  1485.           && (insts[offset].flags & ISLINK)) {
  1486. #ifdef DEBUG
  1487.             if (debug & OVERLAPS)
  1488.                 fprintf(stderr, "Number of overlaps = %ld\n",
  1489.                   overlaps(0));
  1490. #endif
  1491.             total_changes += makegood(offset);
  1492.         }
  1493.  
  1494.     if (total_changes)
  1495.         findbadrefs();
  1496.  
  1497. #ifdef DEBUG
  1498.     if (debug & OVERLAPS)
  1499.         fprintf(stderr, "Number of overlaps after all LINKs = %ld\n",
  1500.           overlaps(0));
  1501. #endif
  1502.  
  1503.     /*
  1504.      * Assume that branch instructions that jump to valid instructions
  1505.      * and that cannot be extension words of math FPU instructions
  1506.      * are valid.
  1507.      */
  1508.     total_changes = 0;
  1509.     do {
  1510.         changes = 0;
  1511.         for (offset = 0; offset <= maxoffset;
  1512.           offset += (odd ? 1 : WORDSIZE))
  1513.             if (insts[offset].size
  1514.               && (insts[offset].flags & ISGOOD) == 0
  1515.               && (insts[offset].flags & (ISBSR | ISJSR | ISBRA
  1516.               | ISBRcc | ISDBcc | ISJMP))
  1517.               && (insts[offset].flags & 3)
  1518.               && insts[offset].required[0] >= initialpc
  1519.               && insts[offset].required[0] <= initialpc
  1520.               + maxoffset
  1521.               && (insts[insts[offset].required[0] - initialpc].flags
  1522.               & ISGOOD)
  1523.               && !fpuoverlap(offset)) {
  1524. #ifdef DEBUG
  1525.                 if (debug & OVERLAPS)
  1526.                     fprintf(stderr,
  1527.                       "Number of overlaps = %ld\n",
  1528.                       overlaps(0));
  1529. #endif
  1530.                 makegood(offset);
  1531.                 changes++;
  1532.             }
  1533.         total_changes += changes;
  1534.     } while (changes);
  1535.  
  1536.     if (total_changes)
  1537.         findbadrefs();
  1538.  
  1539. #ifdef DEBUG
  1540.     if (debug & OVERLAPS)
  1541.         fprintf(stderr,
  1542. "Number of overlaps after all LINKs and jumps to good addresses = %ld\n",
  1543.       overlaps(0));
  1544. #endif
  1545.  
  1546.     /*
  1547.      * Assume that branch instructions that jump outside the current object
  1548.      * file and that cannot be extension words of math FPU instructions
  1549.      * are valid.
  1550.      */
  1551.     total_changes = 0;
  1552.     do {
  1553.         changes = 0;
  1554.         for (offset = 0; offset <= maxoffset;
  1555.           offset += (odd ? 1 : WORDSIZE))
  1556.             if (insts[offset].size
  1557.               && (insts[offset].flags & ISGOOD) == 0
  1558.               && (insts[offset].flags & (ISBSR | ISJSR | ISBRA
  1559.               | ISBRcc | ISDBcc | ISJMP | ISRTS))
  1560.               && !fpuoverlap(offset)) {
  1561. #ifdef DEBUG
  1562.                 if (debug & OVERLAPS)
  1563.                     fprintf(stderr,
  1564.                       "Number of overlaps = %ld\n",
  1565.                       overlaps(0));
  1566. #endif
  1567.                 makegood(offset);
  1568.                 changes++;
  1569.             }
  1570.         total_changes += changes;
  1571.     } while (changes);
  1572.  
  1573.     if (total_changes)
  1574.         findbadrefs();
  1575.  
  1576. #ifdef DEBUG
  1577.     if (debug & OVERLAPS)
  1578.         fprintf(stderr,
  1579.           "Number of overlaps after all LINKs and branches = %ld\n",
  1580.           overlaps(0));
  1581. #endif
  1582.  
  1583.     if (fixoverlaps())
  1584.         findbadrefs();
  1585.  
  1586. #if 1
  1587.     {
  1588.         long    noverlaps = overlaps(1);
  1589.  
  1590.         if (noverlaps
  1591. #ifdef DEBUG
  1592.           || debug & OVERLAPS
  1593. #endif
  1594.           )
  1595.             fprintf(stderr, "%s: Number of overlaps = %ld\n", sfile,
  1596.               noverlaps);
  1597.     }
  1598. #endif
  1599.  
  1600.     /*
  1601.      * Get the labels.
  1602.      */
  1603.     dcpass();
  1604.     for (offset = 0; offset <= maxoffset; ) {
  1605.         if (insts[offset].size) {
  1606.             for (i = 0; i < NREQD(offset); i++)
  1607.                 SETLABEL(insts[offset].required[i]);
  1608.             offset += insts[offset].size;
  1609.         } else if (odd)
  1610.             offset++;
  1611.         else
  1612.             offset += WORDSIZE;
  1613.     }
  1614.     for (nlabels = 0, offset = 0; offset <= maxoffset; offset++)
  1615.         if (insts[offset].flags & ISLABEL) {
  1616. #ifdef DEBUG
  1617.             if (debug & LABELS)
  1618.                 fprintf(outfp, "Label %d at %lx\n",
  1619.                   nlabels + 1, (long)offset);
  1620. #endif
  1621.             insts[offset].labelnum = ++nlabels;
  1622.         }
  1623.  
  1624.     /*
  1625.      * Last pass: Print!
  1626.      */
  1627.     if (fseek(infp, 0, SEEK_SET) == -1) {
  1628.         perror("fseek");
  1629.         jumpfree();
  1630.     }
  1631.     pc = ppc = initialpc;
  1632.     leninstbuf = 0;
  1633.     curnbreak = 0;
  1634.     pass = LASTPASS;
  1635.     for (stored = 0, curoffset = offset = 0; offset < gfsize; )  {
  1636.         if (curoffset != offset
  1637.           && fseek(infp, curoffset = offset, SEEK_SET) == -1) {
  1638.             perror("fseek");
  1639.             jumpfree();
  1640.         }
  1641.         flags = 0;
  1642.         if (insts[offset].size) {
  1643.             if (stored) {
  1644.                 flush(stored, consts,
  1645.                   insts[offset - stored].flags, 1);
  1646.                 stored = 0;
  1647.             }
  1648.  
  1649.             pc = ppc = initialpc + offset;
  1650.             leninstbuf = 0;
  1651.             validinst();
  1652.             offset = curoffset;
  1653.         } else {
  1654.             int    incrbreak;
  1655.  
  1656.             if (stored == 0)
  1657.                 pc = ppc = initialpc + offset;
  1658.  
  1659.             /*
  1660.              * Break the constant data up so that
  1661.              * all labels are printed on a new line.
  1662.              */
  1663.             while (curnbreak < nbreaks
  1664.               && breaks[curnbreak] < offset)
  1665.                 curnbreak++;
  1666.             incrbreak = curnbreak < nbreaks
  1667.               && offset == breaks[curnbreak];
  1668.             if (insts[offset].flags & ISLABEL || incrbreak) {
  1669.                 flush(stored, consts,
  1670.                   insts[offset - stored].flags, 1);
  1671.                 stored = 0;
  1672.                 if (incrbreak)
  1673.                     curnbreak++;
  1674.             }
  1675.             if (fread(consts + stored, 1, 1, infp) == 1)
  1676.                 if (++stored >= sizeof consts) {
  1677.                     stored = flush(stored, consts,
  1678.                       insts[offset - stored].flags, 0);
  1679.                     memmove(consts, consts + sizeof consts
  1680.                       - stored, stored);
  1681.                 }
  1682.  
  1683.             offset++;
  1684.         }
  1685.     }
  1686.     if (stored)
  1687.         flush(stored, consts, insts[offset - stored].flags, 1);
  1688.  
  1689.     jumpfree();
  1690.     /* NOTREACHED */
  1691. }
  1692.