home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / szadb21b / source / src / pcs.c < prev    next >
C/C++ Source or Header  |  1990-11-13  |  11KB  |  518 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.  *    pcs.c
  12.  */
  13. /*
  14.  * Modifications:
  15.  *   - cmdcol() changed for a cooperation with stepping commands
  16.  *   - added function getrequs() which handles turning on/off
  17.  *     execution on breakpoints and stepping commands
  18.  *   - added function findval() which returns values of read-only
  19.  *     internal variables
  20.  *
  21.  *     Anthony Howe, Michal Jaegermann, April 1990
  22.  *
  23.  *   - prnstack now uses Unwind function from stepping.c to find
  24.  *     a chain of return addresses.  (MJ - November 1990)
  25.  */
  26. #include <setjmp.h>
  27. #include <ctype.h>
  28. #include "adb.h"
  29.  
  30. #define IN_PCS
  31. #include "lang.h"
  32.  
  33. #ifndef NULL
  34. #define NULL    0L
  35. #endif
  36.  
  37. unsigned long   esp;
  38. struct basepg  *bpage;
  39. jmp_buf         cont_buf;
  40. static int      got_args = 0;
  41.  
  42. extern long     dot;
  43. extern long     olddot;
  44. extern int      dotset;
  45. extern int      dotoff;
  46. extern int      lastc;
  47. extern int      print_regs;
  48. extern int      click;
  49. extern struct regs regs[];
  50. extern next_step next_list[];
  51. extern next_step jump_list[];
  52.  
  53. prstack (argsflg)
  54. {
  55.     int             first, at_sp;
  56.     long            pc, fp, sp, ap;
  57.     long            npc, nfp;
  58.     long            getn ();
  59.     short          *Unwind();
  60.     struct basepg  *bp = bpage;
  61.  
  62.     pc = *(regs[PC].value);
  63.     fp = *(regs[FP].value);
  64.     sp = *(regs[SP].value);
  65.     at_sp = first = 1;
  66.  
  67.     while (pc) {
  68.     prtf ("%A", pc);
  69.     npc = (long) Unwind (&at_sp, pc, sp, fp);
  70.                  /* this may modify value of at_sp */
  71.     if (first && at_sp) {
  72.         nfp = fp;
  73.         ap = sp + 4;
  74.         at_sp = 0;            /* get the next return address from fp */
  75.     }
  76.     else {
  77.         nfp = getn (fp, 4);
  78.         ap = fp + 8;
  79.     }
  80.     if (argsflg && npc)
  81.         funargs (npc, ap, nfp);
  82.     putchr ('\n');
  83.  
  84.     if (nfp < (long) bp->p_bbase + bp->p_blen ||
  85.         nfp > (long) bp->p_hitpa ||
  86.         nfp <= sp || nfp < fp ||
  87.         (nfp == fp && !first))
  88.         break;
  89.     pc = npc;
  90.     fp = nfp;
  91.     first = 0;
  92.     }
  93. }
  94.  
  95. funargs (retpc, argp, limit)
  96.     long            retpc, argp, limit;
  97. {
  98.     int             i, n;
  99.     unsigned        w;
  100.  
  101.     n = numargs (retpc);
  102.  
  103.     if (n == 0) {        /* optimized out maybe */
  104. /*        prtf("(? at %I)", argp); */
  105.     prtf (M1, argp);
  106.     return;
  107.     }
  108.  
  109.     putchr ('(');
  110.     for (i = 0; i < n; i++, argp += 2) {
  111.     w = getn (argp, 2);
  112.     prt4x (w);
  113.     if (argp + 2 >= limit)
  114.         break;
  115.     if ((i + 1) < n)
  116.         putchr (',');
  117.     }
  118.     putchr (')');
  119. }
  120.  
  121. prt4x (w)
  122.     unsigned        w;
  123. {
  124.     int             i, j, k;
  125.  
  126.     k = 12;
  127.     for (k = 12; k >= 0; k -= 4) {
  128.     j = w >> k;
  129.     j &= 0xf;
  130.     putchr ("0123456789abcdef"[j]);
  131.     }
  132. }
  133.  
  134. numargs (retpc)
  135.     long            retpc;
  136. {
  137.     int             ins, n;
  138.     long            getn ();
  139.  
  140.     ins = getn (retpc, 2);
  141.     if ((ins & 0xf1ff) == 0x504f ||
  142.     (ins & 0xf1ff) == 0x508f) {    /* addq.[wl] #n,A7 */
  143.     n = (ins >> 9) & 7;
  144.     if (n == 0)
  145.         n = 8;
  146.     }
  147.     else if (ins == 0xdefc) {    /* adda.w #n,A7 */
  148.     n = getn (retpc + 2, 2);
  149.     }
  150.     else if (ins == 0xdffc) {    /* adda.l #n,A7 */
  151.     n = getn (retpc + 2, 4);
  152.     }
  153.     else
  154.     n = 0;
  155.  
  156.     if (n < 0)
  157.     n = 0;
  158.     return n / 2;
  159. }
  160.  
  161. long
  162. atbranch (loc)
  163.     long            loc;
  164. {
  165.     int             ins, i;
  166.  
  167.     ins = getn (loc, 2);
  168.     if ((ins & 0xff00) == 0x6000) {
  169.     i = ins & 0xff;
  170.     if (i == 0)
  171.         i = getn (loc + 2, 2);
  172.     return loc + 2 + i;
  173.     }
  174.     return 0;
  175. }
  176.  
  177. atlink (loc)
  178.     long            loc;
  179. {
  180.     int             ins;
  181.  
  182.     ins = getn (loc, 2);
  183.     return (ins == 0x4e56);    /* link a6,#N */
  184. }
  185.  
  186. atrts (loc)
  187.     long            loc;
  188. {
  189.     int             ins;
  190.  
  191.     ins = getn (loc, 2);
  192.     return (ins == 0x4e75);
  193. }
  194.  
  195. prbasepg ()
  196. {
  197.     int             n, i;
  198.     unsigned char   c;
  199.     struct basepg  *bp;
  200.  
  201.     if (dotset)
  202.     bp = (struct basepg *) dot;
  203.     else
  204.     bp = bpage;
  205.  
  206. /*    prtf("base page at %I", bp); */
  207.     prtf (M2, bp);
  208. /*    prt("low tpa ");    */
  209.     prt (M3);
  210.     prtn (bp->p_lowtpa, 10);
  211. /*    prt("  hi tpa  ");    */
  212.     prt (M4);
  213.     prtn (bp->p_hitpa, 10);
  214. /*    prt("\ntext at ");    */
  215.     prt (M5);
  216.     prtn (bp->p_tbase, 10);
  217. /*    prt("  size    ");    */
  218.     prt (M6);
  219.     prtn (bp->p_tlen, 10);
  220. /*    prt("\ndata at ");    */
  221.     prt (M7);
  222.     prtn (bp->p_dbase, 10);
  223. /*    prt("  size    ");    */
  224.     prt (M6);
  225.     prtn (bp->p_dlen, 10);
  226. /*    prt("\nbss at  ");    */
  227.     prt (M8);
  228.     prtn (bp->p_bbase, 10);
  229. /*    prt("  size    ");    */
  230.     prt (M6);
  231.     prtn (bp->p_blen, 10);
  232. /*    prt("\nenv ptr ");    */
  233.     prt (M9);
  234.     prtn (bp->p_env, 10);
  235. /*    prt("  parent  ");    */
  236.     prt (M10);
  237.     prtn (bp->p_parent, 10);
  238.  
  239.     prtf ("\nargs: ");
  240.     n = bp->p_cmdlin[0];
  241.     for (i = 0; i < n;) {
  242.     c = bp->p_cmdlin[++i];
  243.     if (c < ' ') {
  244.         putchr ('^');
  245.         c += 'A';
  246.     }
  247.     putchr (c);
  248.     }
  249.     putchr ('\n');
  250. }
  251.  
  252. loadpcs ()
  253. {
  254.     int           **ip;
  255.     char            parms[80], *envp;
  256.     extern struct basepg *gemdos ();
  257.     extern struct file binary;
  258.     extern struct basepg *_base;
  259.     extern unsigned long ossp;
  260.  
  261.     parms[0] = '\0';
  262.     envp = _base->p_env;
  263.     if ((bpage = gemdos (0x4b, 3, binary.name, parms, envp)) < 0) {
  264. /*        prtf("can't load %s\n", binary.name);    */
  265.     prtf (M11, binary.name);
  266.     return -1;
  267.     }
  268.     ip = (int **) (bpage->p_hitpa);
  269.     *--ip = (int *) bpage;
  270.     --ip;
  271.     *(regs[SP].value) = (unsigned long) ip;
  272.     *(regs[PC].value) = dot = olddot = (unsigned long) bpage->p_tbase;
  273.     *(regs[XSP].value) = ossp;
  274. #ifdef OLD
  275.     bpage->p_parent = _base;
  276. #else
  277.     bpage->p_parent = 0;
  278. #endif
  279.     return 0;
  280. }
  281.  
  282. void
  283. cmdcol (c, fmt, get)
  284.     int             c;
  285.     char           *fmt;
  286.     long            (*get) ();
  287. {
  288.     extern int      MakeReq ();
  289.     int             kind, tmp;
  290.  
  291.     if ('b' == c) {        /* set breakpoint */
  292.     SetBpt (dot);
  293.     }
  294.     else if ('d' == c) {    /* clear breakpoint */
  295.     ClrBpt (dot);
  296.     }
  297.     else {            /* tracing */
  298.     if (dotset)
  299.         *regs[PC].value = dot;
  300.     else
  301.         dot = *regs[PC].value;
  302.  
  303.     c = ((print_regs = isupper (c)) ? tolower (c) : c);
  304.     if ('s' == c)
  305.         kind = CM_STEP;
  306.     else if ('n' == c || 'j' == c)
  307.         kind = CM_NEXT;
  308.     else if ('f' == c)
  309.         kind = CM_FINISH;
  310.     else {
  311.         kind = CM_CONT;    /* we hope */
  312.         if (click)        /* command line started with :: */
  313.         c = 0;        /* force error */
  314.     }
  315.  
  316.     if (CM_CONT == kind || 0 == MakeReq (kind)) {
  317.         switch (c) {
  318.         case 's':
  319.         SingleStep (dot, CM_STEP);
  320.         break;
  321.         case 'c':
  322.         getargs ();
  323.         if (setjmp (cont_buf)) {
  324.             dot = *regs[PC].value;
  325.         }
  326.         FullStep (dot, (short *) NULL, CM_CONT);
  327.         break;
  328.         case 'n':
  329.         NextStep (dot, next_list);
  330.         break;
  331.         case 'j':
  332.         NextStep (dot, jump_list);
  333.         break;
  334.         case 'f':
  335.         FuncStep (dot);
  336.         break;
  337.         default:
  338.         prt (UNKNOWN_CMD);
  339.         }            /* switch */
  340.     }            /* if (click) */
  341.     }                /* if ('b' == c) */
  342.     click = 0;            /* next time around execute */
  343.     return;
  344. }                /* cmdcol */
  345.  
  346. int
  347. getrequs (buf)
  348.     char           *buf;
  349. /*
  350.  *   If 'click' is off and if on a current position, and after all white space
  351.  *   was skipped, there is a character other then '\n', then copy all remaining
  352.  *   characters on a line into a supplied buffer buf. Terminate with '\n\0'.
  353.  *   Return ON if something was copied and BLANK otherwise.
  354.  *   If click is ON return one of the status comands depending on what follows.
  355.  *   Skip to the next delimiter and push '\n'.
  356.  */
  357. {
  358.     register int    c;
  359.     register char  *pos = buf;
  360.     int             status;
  361.     extern int      getchr (), nb ();
  362.  
  363.     if (0 == click) {
  364.     if ('\n' != PEEKC) {
  365.         do {
  366.         *pos++ = c = getchr (1);
  367.         } while ('\n' != c);
  368.         *pos++ = '\0';
  369.         status = NEW;
  370.     }
  371.     else    /* '\n' is pushed */
  372.         return BLANK;
  373.     }
  374.     else {            /* we are changing status of attached
  375.                  * commands - ignore buffer */
  376.     switch (c = nb ()) {
  377.     case '+':
  378.         status = ON;
  379.         break;
  380.     case '-':
  381.         status = SILENT;
  382.         break;
  383.     case '_':
  384.         status = DOWN;
  385.         break;
  386.     case '`':
  387.         status = REVERT;
  388.         break;
  389.     default:
  390.         status = IGNORE;
  391.     }
  392.     while (getchr (0) != '\n') /* skip to the next delimiter */
  393.         ;
  394.     }
  395.     PUSHC ('\n');
  396.     return (status);
  397. }                /* getrequs */
  398.  
  399. getargs ()
  400. {
  401.     char            c, *cp;
  402.     int             n;
  403.  
  404.     c = nb ();
  405.     if (c == '\n')
  406.     return;
  407.  
  408.     if (got_args)
  409.     return;
  410.     got_args++;
  411.  
  412.     n = 1;
  413.     cp = &bpage->p_cmdlin[n];
  414.     *cp++ = c;
  415.     while ((c = getchr (1)) != '\n') {
  416.     *cp++ = c;
  417.     n++;
  418.     if (n >= 0x7f)
  419.         break;
  420.     }
  421.     bpage->p_cmdlin[0] = n;
  422.     *cp = 0;
  423.     PUSHC ('\n');
  424. }
  425.  
  426. void
  427. copyargs (argc, argv)
  428.     int             argc;
  429.     char          **argv;
  430. /*
  431.  * If argc > 0 copy command line arguments into a base page of
  432.  * process to debug. Terminating zero not included in count.
  433.  */
  434. {
  435.     char            c, *cp;
  436.     int             n;
  437.  
  438.     if (0 == argc) {
  439.     bpage->p_cmdlin[0] = 0;
  440.     return;
  441.     }
  442.     got_args++;
  443.  
  444.     n = 0;
  445.     cp = &bpage->p_cmdlin[1];
  446.     for (;;) {
  447.     if (n >= 0x7e)
  448.         break;
  449.     while (0 != (c = *(*argv)++)) {
  450.         *cp++ = c;
  451.         n++;
  452.         if (n >= 0x7e)
  453.         goto out;
  454.     }
  455.     if (--argc == 0)
  456.         break;
  457.     *cp++ = ' ';
  458.     n++;
  459.     }
  460. out:
  461.     *cp = 0;
  462.     bpage->p_cmdlin[0] = n;
  463. }
  464.  
  465.  
  466. #ifdef GONER
  467. cleanup (fp)
  468.     struct file    *fp;
  469. {
  470.  
  471.     ptrace (KILL_PID, fp->pid, 0, 0);
  472.     return;
  473. }
  474.  
  475. #endif
  476.  
  477. prbpt (pc)
  478.     long            pc;
  479. {
  480.     dot = pc;
  481.     dotoff = 0;
  482.     prtad (dot + dotoff);
  483.     putchr (':');
  484.     puti ();
  485.     return;
  486. }
  487.  
  488. long
  489. findval (buf, err_p)
  490.     char           *buf;
  491.     int            *err_p;
  492. /*
  493.  * If a string in buf is "l", "b", "t" or "d" return value of
  494.  * text segment base, data segment base, text size and data size
  495.  * respectively.  Otherwise set error indicator and return 0.
  496.  *
  497.  * Names are chosen to avoid conflicts with a Un*x adb. Names
  498.  * "b", "t", "d" and some other are already taken.
  499.  */
  500. {
  501.     struct basepg  *bp = bpage;
  502.  
  503.     if (0 == (*err_p = buf[1])) {
  504.     switch (buf[0]) {
  505.     case 'l':
  506.         return (bp->p_tbase);
  507.     case 'b':
  508.         return (bp->p_dbase);
  509.     case 'd':
  510.         return (bp->p_dlen);
  511.     case 't':
  512.         return (bp->p_tlen);
  513.     }
  514.     }
  515.     *err_p = 1;
  516.     return 0;
  517. }
  518.