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