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