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