home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / szadb21b / source / src / adb1.c < prev    next >
C/C++ Source or Header  |  1992-01-09  |  15KB  |  701 lines

  1. /* Copyright (c) 1990 by Sozobon, Limited.  Authors: Johann Ruegg, Don Dugger
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    adb1.c
  12.  */
  13. /*
  14.  * Modifications:
  15.  *   Michal Jaegermann, May 1990
  16.  *
  17.  *   - added functions to handle MWC format symbol table and hooks to
  18.  *     possibly add other formats
  19.  *   - added functions for buffered output to external files
  20.  *
  21.  *   Michal Jaegermann, January 1991
  22.  *
  23.  *   - function setsym() modified to handle also extended format in
  24.  *     which function name can be continued in the next symbol slot
  25.  *     (known as "GST format")
  26.  *   - added function extndsymb() which checks if symbols are using
  27.  *     extended GST format
  28.  *
  29.  *   Michal Jaegermann, January 1992
  30.  *
  31.  *   - added function xsoz_setsym() to handle "Sozobon eXtended"
  32.  *     format introduced with version 2.0 of Sozobon C compiler.
  33.  *   - modified setsym() to switch to xsoz_setsym if such format
  34.  *     encountered.
  35.  */
  36.  
  37. #include <setjmp.h>
  38. #include "adb.h"
  39.  
  40. #define IN_ADB1
  41. #include "lang.h"
  42.  
  43. extern struct file binary;
  44.  
  45. extern long     dot;
  46. extern int      dotoff;
  47. extern long     maxoff;
  48. extern int      ibase;
  49.  
  50. extern int      lastc;
  51. extern char     sign;
  52.  
  53. extern int      swidth;
  54. extern jmp_buf  jmpb;
  55. extern int      trid;
  56. extern w_buf   *trbuf;
  57. extern char    *trname;
  58.  
  59. getfmt (fmt)
  60.     register char  *fmt;
  61. {
  62.     int             in_string = 0;
  63.  
  64.     while ((*fmt = getchr (in_string)) != '\n') {
  65.     if ('"' == *fmt)
  66.         in_string = !in_string;
  67.     fmt++;
  68.     }
  69.     *fmt = '\0';
  70.     PUSHC ('\n');
  71.     return;
  72. }
  73.  
  74. long
  75. getdot (d, n)
  76.     long            d;
  77.     int             n;
  78. {
  79.     long            l;
  80.  
  81.     l = dot;
  82.     if (n == 2)
  83.     l &= 0xffff;
  84.     else if (n == 1)
  85.     l &= 0xff;
  86.     return (l);
  87. }
  88.  
  89. #ifdef GONER
  90. unsigned char
  91. getb (fp)
  92.     struct file    *fp;
  93. {
  94.     long            getn ();
  95.  
  96.     return (getn (dot + dotoff, 1));
  97. }
  98. #endif
  99.  
  100. unsigned int
  101. getwd ()
  102. {
  103.     long            getn ();
  104.  
  105.     return (getn (dot + dotoff, 2));
  106. }
  107.  
  108. putn (v, d, n)
  109.     long            v, d;
  110.     int             n;
  111. {
  112.     union {
  113.     int             i;
  114.     long            l;
  115.     }               no, val;
  116.     long            b;
  117.     register int    o;
  118.     char           *p, *s;
  119.  
  120.     b = d >> LOGBS;
  121.     o = d & (BSIZE - 1);
  122.     switch (n) {
  123.  
  124.     case 2:
  125.     p = (char *) (&no.i);
  126.     val.i = v;
  127.     s = (char *) (&val.i);
  128.     break;
  129.     case 4:
  130.     p = (char *) (&no.l);
  131.     val.l = v;
  132.     s = (char *) (&val.l);
  133.     break;
  134.  
  135.     }
  136.     rdsub (d, p, n, 0);
  137.     dotoff += n;
  138.     switch (n) {
  139.  
  140.     case 2:
  141.     bcopy (s, p, n);
  142.     break;
  143.     case 4:
  144.     bcopy (s, p, n);
  145.     break;
  146.  
  147.     }
  148.     wrsub (p, d, n, 0);
  149.     return;
  150. }
  151.  
  152. long
  153. getn (d, n)
  154.     unsigned long   d;
  155.     int             n;
  156. {
  157.     unsigned long   b, no;
  158.     register unsigned int o;
  159.     char           *p;
  160.  
  161.     b = d >> LOGBS;
  162.     o = d & (BSIZE - 1);
  163.     rdsub (d, &b, n, 0);
  164.     p = (char *) &b;
  165.     dotoff += n;
  166.     switch (n) {
  167.  
  168.     case 1:
  169.     no = *p;
  170.     break;
  171.     case 2:
  172.     no = *(int *) p;
  173.     break;
  174.     case 4:
  175.     no = *(long *) p;
  176.     break;
  177.  
  178.     }
  179.     return (no);
  180. }
  181.  
  182. puto (n, s)
  183.     unsigned long   n;
  184.     int             s;
  185. {
  186.  
  187.     if (n > 0)
  188.     puto ((n >> 3) & 0x1fffffff, --s);
  189.     else
  190.     while (s-- > 0)
  191.         putchr (' ');
  192.     putchr ((char) ((n & 7) + '0'));
  193.     return;
  194. }
  195.  
  196. putd (n, s)
  197.     long            n;
  198.     int             s;
  199. {
  200.  
  201.     if (n < 0) {
  202.     s--;
  203.     n = -n;
  204.     if (n < 0) {
  205.         while (s-- > 0)
  206.         putchr (' ');
  207.         putchr ('?');
  208.         return;
  209.     }
  210.     else
  211.         sign = '-';
  212.     }
  213.     if (n > 9)
  214.     putd (n / 10, --s);
  215.     else
  216.     while (s-- > 0)
  217.         putchr (' ');
  218.     if (sign) {
  219.     putchr (sign);
  220.     sign = 0;
  221.     }
  222.     putchr ((char) ((n % 10) + '0'));
  223.     return;
  224. }
  225.  
  226. putx (n, s)
  227.     unsigned long   n;
  228.     int             s;
  229. {
  230.  
  231.     if (n > 0xf)
  232.     putx ((n >> 4) & 0xfffffff, --s);
  233.     else {
  234.     while (s-- > 0)
  235.         putchr (' ');
  236.     }
  237.     putchr ("0123456789abcdef"[n & 0xf]);
  238.     return;
  239. }
  240.  
  241. prtn (n, s)
  242.     long            n;
  243.     int             s;
  244. {
  245.  
  246.     switch (ibase) {
  247.  
  248.     case 8:
  249.     puto (n, s);
  250.     break;
  251.     case 10:
  252.     putd (n, s);
  253.     break;
  254.     default:
  255.     case 16:
  256.     putx (n, s);
  257.     break;
  258.  
  259.     }
  260.     return;
  261. }
  262.  
  263. prt (s)
  264.     register char  *s;
  265. {
  266.  
  267.     while (*s)
  268.     putchr (*s++);
  269.     return;
  270. }
  271.  
  272.  
  273. relsym ()
  274. {
  275.     register struct symbol *sp;
  276.     extern struct basepg *bpage;
  277.  
  278.     sp = binary.symptr;
  279.     while (sp) {
  280.     sp->value += (long) bpage->p_tbase;
  281.     sp = sp->next;
  282.     }
  283. }
  284.  
  285. mwsetsym (fid, ssize)
  286. /* read symbol table in MWC format */
  287.     int             fid;
  288.     long            ssize;
  289. {
  290.     struct mwfilsym sym;
  291.     char            ct;
  292.     
  293.     if (0 != (ssize % sizeof(sym))) {
  294.     if (ssize <= 0x30L)
  295.         return 0;
  296.     lseek (fid, 0x30L, 1);  /* skip some really not-symbol stuff */
  297.     ssize -= 0x30L;
  298.     }
  299.     do {
  300.     if (read (fid, &sym, sizeof (sym)) != sizeof (sym))
  301.         return -1;
  302.     if (sym.flag & 0x1000) {  /* global data */
  303.         ct = sym.sval.got[0];
  304.         sym.sval.got[0] = sym.sval.got[1];
  305.         sym.sval.got[1] = ct;
  306.         ct = sym.sval.got[2];
  307.         sym.sval.got[2] = sym.sval.got[3];
  308.         sym.sval.got[3] = ct;
  309.         if (0 == addsym (&binary.symptr, sym.name, sym.sval.value))
  310.         break;
  311.     }
  312.     } while (0 < (ssize -= sizeof (sym)));
  313.     return 0;
  314. } /* mwsetsym */
  315.  
  316. #define XNAME    "SozobonX"
  317. #define XVALUE    0x87654321
  318. #define NAMEMAX 80
  319.  
  320. /* Read symbol table in "Sozobon extended" format introduced with */
  321. /* version 2.0 of this compiler.                  */
  322. /* Maximum name length is rather high.  We will ensure that all   */
  323. /* symbol table entries are NULL terminated.                      */
  324. xsoz_setsym (fid, ssize)
  325.     int             fid;
  326.     long            ssize;
  327. {
  328.     register char *ptr, *npos = 0;
  329.     register int count;
  330.     struct filsym sym;
  331.     char name[NAMEMAX + 2];
  332.     long value;
  333.  
  334.     swidth = NAMEMAX + 2;
  335.  
  336.     do {
  337.     if (read (fid, &sym, sizeof(sym)) != sizeof(sym))
  338.         return -1;
  339.     ssize -= sizeof(sym);
  340.     /*
  341.      * not an extension - add to symbol table what we collected
  342.      * so far and start reading a new symbol
  343.      */
  344.     if (XVALUE != sym.value || S_EXTEND != sym.flag) {
  345.         if (npos != 0)
  346.         addsym (&binary.symptr, name, value);
  347.         npos = name;
  348.         value = sym.value;
  349.     }
  350.     ptr = &(sym.name[0]);
  351.     /* copy what we got to a name buffer */
  352.     count = sizeof(sym.name);
  353.     do {
  354.         if ('\0' == (*npos = *ptr++))
  355.         break;
  356.         npos++;
  357.     } while (--count > 0);
  358.     } while (ssize > 0);
  359.     /* write out the last symbol */
  360.     if (npos != 0)
  361.     addsym (&binary.symptr, name, value);
  362.     return 0;
  363. } /* xsoz_setsym */
  364.  
  365. setsym (fid, ssize)
  366. /* Read symbol table in Alcyon format - used by Sozobon as well.    */
  367. /* This function modified to handle also symbol tables where symbol */
  368. /* name possibly extends into the next symbol slot; only when       */
  369. /* signalled by S_LNAM flag, otherwise backward compatible.        */
  370.     int             fid;
  371.     long            ssize;
  372. {
  373.     register int extsymbs;
  374.     struct filsym sym; /* dummy for #defines - Sozobon doesn't know what
  375.                    to do with sizeof(struct filsym) */
  376. #define SYMSPAN sizeof(sym)
  377. #define NAMSIZE sizeof(sym.name)
  378.  
  379.     struct  {
  380.     char    xname[NAMSIZE + SYMSPAN];
  381.     short    xflag;
  382.     long    xvalue;
  383.     } xsym;
  384.  
  385.     static int first_symbol = 1;
  386.  
  387.     extsymbs = (22 == swidth);
  388.     do {
  389.     if ((read (fid, &xsym, NAMSIZE) != NAMSIZE) ||
  390.         (read (fid, (char *)(&xsym) + NAMSIZE + SYMSPAN, SYMSPAN - NAMSIZE)
  391.                 != SYMSPAN - NAMSIZE))
  392.         return -1;
  393.     ssize -= SYMSPAN;
  394.     if (first_symbol) { /* check if this is an "extended Sozobon" format */
  395.         if (XVALUE == xsym.xvalue && S_EXTEND == xsym.xflag &&
  396.                  strncmp(xsym.xname, XNAME, 8) == 0) {
  397.         return (xsoz_setsym(fid, ssize));
  398.         }
  399.         first_symbol = 0;
  400.     }
  401.  
  402.     if (0 >= ssize) {
  403.         xsym.xflag &= ~S_LNAM;
  404.     }
  405.     if (extsymbs && (S_LNAM == (xsym.xflag & S_LNAM))) {
  406.         if (read (fid, (char *)(&xsym) + NAMSIZE, SYMSPAN) != SYMSPAN)
  407.         return -1;
  408.         ssize -= SYMSPAN;
  409.     }
  410.     else {
  411.         xsym.xname[NAMSIZE] = '\0';
  412.     }
  413.     if ((xsym.xflag & S_EXT) &&
  414.         (xsym.xflag & (S_DATA | S_TEXT | S_BSS))) {
  415.         if (0 == addsym (&binary.symptr, xsym.xname, xsym.xvalue))
  416.         break;
  417.     }
  418.     } while (ssize > 0);
  419.     return 0;
  420. } /* setsym */
  421.  
  422. #undef SYMSPAN
  423. #undef NAMSIZE
  424.  
  425. addsym (spp, name, value)
  426.     struct symbol **spp;
  427.     char           *name;
  428.     long            value;
  429. {
  430.     register char  *cp, *cps, *cptr;
  431.     long            v;
  432.     struct symbol  *sp;
  433.     char           *malloc ();
  434.     struct symbol  *p;
  435.     int             msize;
  436.  
  437.     v = value;
  438.     sp = *spp;
  439.     while (sp && (sp->value <= v)) {
  440.     spp = &sp->next;
  441.     sp = *spp;
  442.     }
  443.     
  444.     cps = name;
  445.     cp = cps + swidth;    /* max symbol size */
  446.     while ( *cps && (cps < cp))
  447.     cps++;
  448.     cp = name;
  449.  
  450.     msize =  sizeof (*p) + (int)(cps - cp) + 1; /* need a space for '\0' */
  451.     if ((p = (struct symbol *) malloc (msize)) == 0) {
  452. /*        prtf("can't allocate %i bytes for symbol\n", sizeof(*p)); */
  453.     prtf (M1, msize);
  454.     return 0;
  455.     }
  456.     *spp = p;
  457.     p->next = sp;
  458.     p->value = v;
  459.     cptr = p->name;
  460.     while (cp < cps)
  461.     *cptr++ = *cp++;
  462.     *cptr = '\0';
  463.     return 1;
  464. }
  465.  
  466. int
  467. extndsymb(fid, ssize)
  468. /* check if any symbol in a file is in an extended format */
  469.     int             fid;
  470.     long            ssize;
  471. {
  472.     register int extended;
  473.     struct filsym sym;
  474.     long position;
  475.     extern long tell();
  476.     
  477.     position = tell(fid);
  478.     do {
  479.     if (read (fid, &sym, sizeof (sym)) != sizeof (sym))
  480.         break;
  481.     if (extended = (S_LNAM == (sym.flag & S_LNAM)))
  482.         break;      
  483.     } while (0 < (ssize -= sizeof(sym)));
  484.     /* restore an original position in a file */
  485.     lseek (fid, position, 0);
  486.     return extended;
  487. }
  488.  
  489. struct symbol  *
  490. findnam (cp, sp)
  491.     char           *cp;
  492.     struct symbol  *sp;
  493. {
  494.     while (sp) {
  495.     if (strncmp (cp, sp->name, swidth) == 0)
  496.         return (sp);
  497.     else
  498.         sp = sp->next;
  499.     }
  500.     return (0);
  501. }
  502.  
  503. struct symbol  *
  504. findsym (v, sp)
  505.     unsigned long   v;
  506.     struct symbol  *sp;
  507. {
  508.     struct symbol  *lp;
  509.     unsigned long   val;
  510.  
  511.     lp = sp;
  512.     while (sp) {
  513.     val = sp->value;
  514.     if (val > v)
  515.         break;
  516.     else {
  517.         lp = sp;
  518.         sp = sp->next;
  519.     }
  520.     }
  521.     if (lp && v >= lp->value && v < lp->value + maxoff)
  522.     return (lp);
  523.     return (0);
  524. }
  525.  
  526. long
  527. atonum (s, inbase, nond_p)
  528.     register char  *s;
  529.     int             inbase;
  530.     int            *nond_p;
  531. /*
  532.  *  Convert a string of characters to a number in a base not bigger
  533.  *  than 16. Returns accumulated number and stores first not
  534.  *  converted character in a location pointed by nond_p.
  535.  *
  536.  *  To override an original base use 0x, 0t or 0o prefix.
  537.  */
  538. {
  539.     int             type ();
  540.     register int    c, base;
  541.     register long   n = 0;
  542.  
  543.     c = *s++;
  544.     base = inbase;
  545.     if (c == '0') {
  546.     base = 8;
  547.     switch (c = *s++) {
  548.     case 'x':
  549.         base += 6;        /* FALLTHROUGH */
  550.     case 't':
  551.         base += 2;        /* FALLTHROUGH */
  552.     case 'o':
  553.         c = *s++;
  554.         break;
  555.     default:
  556.         base = inbase;
  557.         break;
  558.     }
  559.     }
  560.     while (c && (type (c) & HEXDIG)) {
  561.     if (c >= 'A') {
  562.         c &= ~' ';        /* ensure that we are in an upper case */
  563.         c -= 'A' - '0' - 10;
  564.     }
  565.     c -= '0';
  566.     if (c >= base)
  567.         break;
  568.     n = (n * base) + c;
  569.     c = *s++;
  570.     }
  571.     *nond_p = c;
  572.     return (n);
  573. }
  574.  
  575. prtsym (v, sp)
  576.     unsigned long   v;
  577.     struct symbol  *sp;
  578. {
  579.  
  580.     prt (sp->name);
  581.     if (v != sp->value) {
  582.     putchr ('+');
  583.     prtn (v - sp->value, 0);
  584.     }
  585.     return;
  586. }
  587.  
  588. rdsub (from, to, n, pid)
  589.     char           *from, *to;
  590.     int             n, pid;
  591. {
  592.     long            l[2];
  593.     register int    off;
  594.  
  595.     off = (int) from & (sizeof (l[0]) - 1);
  596.     from -= off;
  597.     l[0] = ptrace (RD_DATA, pid, from, 0);
  598.     if ((off + n) > sizeof (l[0]))
  599.     l[1] = ptrace (RD_DATA, pid, from + sizeof (l[0]), 0);
  600.     bcopy ((char *) l + off, to, n);
  601.     return;
  602. }
  603.  
  604. wrsub (from, to, n, pid)
  605.     char           *from, *to;
  606.     int             n, pid;
  607. {
  608.     long            l[2];
  609.     register int    off;
  610.  
  611.     off = (int) to & (sizeof (l[0]) - 1);
  612.     to -= off;
  613.     if (off || n != sizeof (l[0]))
  614.     l[0] = ptrace (RD_DATA, pid, to, 0);
  615.     if ((off + n) > sizeof (l[0]))
  616.     l[1] = ptrace (RD_DATA, pid, to + sizeof (l[0]), 0);
  617.     bcopy (from, (char *) l + off, n);
  618.     ptrace (WR_DATA, pid, to, l[0]);
  619.     if ((off + n) > sizeof (l[0]))
  620.     ptrace (WR_DATA, pid, to + sizeof (l[0]), l[1]);
  621.     return;
  622. }
  623.  
  624. cmdsreg (c, fmt, get)
  625.     int             c;
  626.     char           *fmt;
  627.     long            (*get) ();
  628. {
  629.     char            buf[10], *cp, c;
  630.     int             i;
  631.     struct regs    *rp, *findreg ();
  632.  
  633.     cp = buf;
  634.     i = 0;
  635.     while (i < 5 && (c = getchr (0)) != '\n') {
  636.     i++;
  637.     *cp++ = c;
  638.     }
  639.     *cp = '\0';
  640.     if (c == '\n')
  641.     PUSHC ('\n');
  642.  
  643.     if (rp = findreg (buf)) {
  644.     *rp->value = dot;
  645.     return;
  646.     }
  647.     error (BADRNAME);
  648. }
  649.  
  650. int
  651. bf_write (fd, data, size)
  652.     int             fd;
  653.     char           *data;
  654.     int             size;
  655. /*
  656.  * Write to a file with a descriptor fd when no more space in a buffer
  657.  * - otherwise keep adding to a storage.
  658.  * Returns 0 on success or a negative error code.
  659.  */
  660. {
  661.     int             grab = 0;
  662.     int             rc;
  663.  
  664.     do {
  665.     data += grab;
  666.     if (size > (trbuf->buf_len - trbuf->buffered)) {
  667.         if (0 > (rc = write (fd, trbuf->storage, trbuf->buffered))) {
  668.         return (rc);
  669.         }
  670.         trbuf->buffered = 0;
  671.     }
  672.  
  673.     grab = (size > trbuf->buf_len ? trbuf->buf_len : size);
  674.     /* bcopy defined in assist.s */
  675.     bcopy (data, trbuf->storage + trbuf->buffered, grab);
  676.     trbuf->buffered += grab;
  677.     size -= grab;
  678.     } while (0 < size);
  679.  
  680.     return (grab);
  681. }                /* bf_write */
  682.  
  683. void
  684. trflush ()
  685. {
  686.     if ((w_buf *) 0 != trbuf && 0 < trbuf->buffered) {
  687.     for (;;) {        /* if error on write give a chance of a
  688.                  * recovery */
  689.         if (0 <= write (trid, trbuf->storage, trbuf->buffered))
  690.         break;
  691.         prtf (MW, trname);    /* error happened  */
  692.         prt (M2);        /* "Retry? (y/n) " */
  693.         if ('N' == (~' ' & getkchr ())) {
  694.         putchr ('\n');
  695.         break;        /* buffered output lost */
  696.         }
  697.     }            /* retry loop */
  698.     trbuf->buffered = 0;
  699.     }
  700. }                /* trflush */
  701.