1*5470Slinton /* Copyright (c) 1982 Regents of the University of California */ 2*5470Slinton 3*5470Slinton static char sccsid[] = "@(#)trinfo.c 1.1 01/18/82"; 4*5470Slinton 5*5470Slinton /* 6*5470Slinton * Trace information management. 7*5470Slinton * 8*5470Slinton * The trace information is a list of variables that are being 9*5470Slinton * traced or whose value changing should cause a stop. 10*5470Slinton */ 11*5470Slinton 12*5470Slinton #include "defs.h" 13*5470Slinton #include "breakpoint.h" 14*5470Slinton #include "process.h" 15*5470Slinton #include "machine.h" 16*5470Slinton #include "sym.h" 17*5470Slinton #include "tree.h" 18*5470Slinton #include "source.h" 19*5470Slinton #include "object.h" 20*5470Slinton #include "tree/tree.rep" 21*5470Slinton 22*5470Slinton /* 23*5470Slinton * When tracing variables we keep a copy of their most recent value 24*5470Slinton * and compare it to the current one each time a breakpoint occurs. 25*5470Slinton * MAXTRSIZE is the maximum size variable we allow. 26*5470Slinton */ 27*5470Slinton 28*5470Slinton #define MAXTRSIZE 512 29*5470Slinton 30*5470Slinton /* 31*5470Slinton * The tracing structure is a list of information about all the 32*5470Slinton * variables that are being traced. 33*5470Slinton */ 34*5470Slinton 35*5470Slinton typedef struct trinfo { 36*5470Slinton TRTYPE trtype; 37*5470Slinton ADDRESS traddr; 38*5470Slinton SYM *trblock; 39*5470Slinton NODE *trvar; 40*5470Slinton NODE *trcond; 41*5470Slinton char *trvalue; 42*5470Slinton struct trinfo *trnext; 43*5470Slinton } TRINFO; 44*5470Slinton 45*5470Slinton LOCAL TRINFO *trhead; 46*5470Slinton 47*5470Slinton /* 48*5470Slinton * add a variable to be traced 49*5470Slinton */ 50*5470Slinton 51*5470Slinton addvar(trtype, node, cond) 52*5470Slinton TRTYPE trtype; 53*5470Slinton NODE *node; 54*5470Slinton NODE *cond; 55*5470Slinton { 56*5470Slinton register TRINFO *tp; 57*5470Slinton 58*5470Slinton tp = alloc(1, TRINFO); 59*5470Slinton tp->trtype = trtype; 60*5470Slinton tp->traddr = (ADDRESS) -1; 61*5470Slinton tp->trblock = curfunc; 62*5470Slinton tp->trvar = node; 63*5470Slinton tp->trcond = cond; 64*5470Slinton tp->trvalue = NIL; 65*5470Slinton tp->trnext = trhead; 66*5470Slinton trhead = tp; 67*5470Slinton } 68*5470Slinton 69*5470Slinton /* 70*5470Slinton * remove a variable from the trace list 71*5470Slinton */ 72*5470Slinton 73*5470Slinton delvar(trtype, node, cond) 74*5470Slinton TRTYPE trtype; 75*5470Slinton NODE *node; 76*5470Slinton NODE *cond; 77*5470Slinton { 78*5470Slinton register TRINFO *tp, *last; 79*5470Slinton 80*5470Slinton last = NIL; 81*5470Slinton for (tp = trhead; tp != NIL; tp = tp->trnext) { 82*5470Slinton if (tp->trtype == trtype && 83*5470Slinton tr_equal(tp->trvar, node) && 84*5470Slinton tr_equal(tp->trcond, cond)) { 85*5470Slinton break; 86*5470Slinton } 87*5470Slinton } 88*5470Slinton if (tp == NIL) { 89*5470Slinton trerror("can't delete term %t", node); 90*5470Slinton } 91*5470Slinton if (last == NIL) { 92*5470Slinton trhead = tp->trnext; 93*5470Slinton } else { 94*5470Slinton last->trnext = tp->trnext; 95*5470Slinton } 96*5470Slinton if (tp->trvalue != NIL) { 97*5470Slinton free(tp->trvalue); 98*5470Slinton } 99*5470Slinton free(tp); 100*5470Slinton } 101*5470Slinton 102*5470Slinton /* 103*5470Slinton * Print out any news about variables in the list whose 104*5470Slinton * values have changed. 105*5470Slinton */ 106*5470Slinton 107*5470Slinton prvarnews() 108*5470Slinton { 109*5470Slinton register TRINFO *tp; 110*5470Slinton register NODE *p; 111*5470Slinton register int n; 112*5470Slinton SYM *s; 113*5470Slinton char buff[MAXTRSIZE]; 114*5470Slinton static LINENO prevline; 115*5470Slinton 116*5470Slinton for (tp = trhead; tp != NIL; tp = tp->trnext) { 117*5470Slinton if (tp->trcond != NIL && !cond(tp->trcond)) { 118*5470Slinton continue; 119*5470Slinton } 120*5470Slinton s = curfunc; 121*5470Slinton while (s != NIL && s != tp->trblock) { 122*5470Slinton s = container(s); 123*5470Slinton } 124*5470Slinton if (s == NIL) { 125*5470Slinton continue; 126*5470Slinton } 127*5470Slinton p = tp->trvar; 128*5470Slinton if (tp->traddr == (ADDRESS) -1) { 129*5470Slinton tp->traddr = lval(p->left); 130*5470Slinton } 131*5470Slinton n = size(p->nodetype); 132*5470Slinton dread(buff, tp->traddr, n); 133*5470Slinton if (tp->trvalue == NIL) { 134*5470Slinton tp->trvalue = alloc(n, char); 135*5470Slinton mov(buff, tp->trvalue, n); 136*5470Slinton mov(buff, sp, n); 137*5470Slinton sp += n; 138*5470Slinton if (tp->trtype == TRPRINT) { 139*5470Slinton printf("initially (at line %d):\t", curline); 140*5470Slinton prtree(p); 141*5470Slinton printf(" = "); 142*5470Slinton printval(p->nodetype); 143*5470Slinton putchar('\n'); 144*5470Slinton } 145*5470Slinton } else if (cmp(tp->trvalue, buff, n) != 0) { 146*5470Slinton mov(buff, tp->trvalue, n); 147*5470Slinton mov(buff, sp, n); 148*5470Slinton sp += n; 149*5470Slinton printf("after line %d:\t", prevline); 150*5470Slinton prtree(p); 151*5470Slinton printf(" = "); 152*5470Slinton printval(p->nodetype); 153*5470Slinton putchar('\n'); 154*5470Slinton if (tp->trtype == TRSTOP) { 155*5470Slinton isstopped = TRUE; 156*5470Slinton getsrcinfo(); 157*5470Slinton printstatus(); 158*5470Slinton } 159*5470Slinton } 160*5470Slinton } 161*5470Slinton prevline = curline; 162*5470Slinton } 163*5470Slinton 164*5470Slinton /* 165*5470Slinton * Free the table. Note that trvar and trcond fields are not freed, 166*5470Slinton * this is because they are the same as in the breakpoint table and 167*5470Slinton * are freed by the bpfree routine. 168*5470Slinton */ 169*5470Slinton 170*5470Slinton trfree() 171*5470Slinton { 172*5470Slinton register TRINFO *tp, *next; 173*5470Slinton 174*5470Slinton for (tp = trhead; tp != NIL; tp = next) { 175*5470Slinton next = tp->trnext; 176*5470Slinton if (tp->trvalue != NIL) { 177*5470Slinton free(tp->trvalue); 178*5470Slinton } 179*5470Slinton free(tp); 180*5470Slinton } 181*5470Slinton trhead = NIL; 182*5470Slinton } 183