148103Sbostic /*-
2*62122Sbostic * Copyright (c) 1980, 1993
3*62122Sbostic * The Regents of the University of California. All rights reserved.
448103Sbostic *
548103Sbostic * %sccs.include.redist.c%
622282Sdist */
75470Slinton
822282Sdist #ifndef lint
9*62122Sbostic static char sccsid[] = "@(#)trinfo.c 8.1 (Berkeley) 06/06/93";
1048103Sbostic #endif /* not lint */
115470Slinton
125470Slinton /*
135470Slinton * Trace information management.
145470Slinton *
155470Slinton * The trace information is a list of variables that are being
165470Slinton * traced or whose value changing should cause a stop.
175470Slinton */
185470Slinton
195470Slinton #include "defs.h"
205470Slinton #include "breakpoint.h"
215470Slinton #include "process.h"
225470Slinton #include "machine.h"
235470Slinton #include "sym.h"
245470Slinton #include "tree.h"
255470Slinton #include "source.h"
265470Slinton #include "object.h"
275470Slinton #include "tree/tree.rep"
2830843Smckusick #include "process/process.rep"
2930843Smckusick #include "process/pxinfo.h"
305470Slinton
315470Slinton /*
325470Slinton * When tracing variables we keep a copy of their most recent value
335470Slinton * and compare it to the current one each time a breakpoint occurs.
345470Slinton * MAXTRSIZE is the maximum size variable we allow.
355470Slinton */
365470Slinton
375470Slinton #define MAXTRSIZE 512
385470Slinton
395470Slinton /*
405470Slinton * The tracing structure is a list of information about all the
415470Slinton * variables that are being traced.
425470Slinton */
435470Slinton
445470Slinton typedef struct trinfo {
455760Slinton TRTYPE trtype;
465760Slinton ADDRESS traddr;
475760Slinton SYM *trblock;
485760Slinton NODE *trvar;
495760Slinton NODE *trcond;
505760Slinton char *trvalue;
515760Slinton struct trinfo *trnext;
525470Slinton } TRINFO;
535470Slinton
545470Slinton LOCAL TRINFO *trhead;
555470Slinton
565470Slinton /*
575470Slinton * add a variable to be traced
585470Slinton */
595470Slinton
addvar(trtype,node,cond)605470Slinton addvar(trtype, node, cond)
615470Slinton TRTYPE trtype;
625470Slinton NODE *node;
635470Slinton NODE *cond;
645470Slinton {
655760Slinton register TRINFO *tp;
665470Slinton
675760Slinton tp = alloc(1, TRINFO);
685760Slinton tp->trtype = trtype;
695760Slinton tp->traddr = (ADDRESS) -1;
705760Slinton tp->trblock = curfunc;
715760Slinton tp->trvar = node;
725760Slinton tp->trcond = cond;
735760Slinton tp->trvalue = NIL;
745760Slinton tp->trnext = trhead;
755760Slinton trhead = tp;
765470Slinton }
775470Slinton
785470Slinton /*
795470Slinton * remove a variable from the trace list
805470Slinton */
815470Slinton
delvar(trtype,node,cond)825470Slinton delvar(trtype, node, cond)
835470Slinton TRTYPE trtype;
845470Slinton NODE *node;
855470Slinton NODE *cond;
865470Slinton {
875760Slinton register TRINFO *tp, *last;
885470Slinton
895760Slinton last = NIL;
905760Slinton for (tp = trhead; tp != NIL; tp = tp->trnext) {
915760Slinton if (tp->trtype == trtype &&
925760Slinton tr_equal(tp->trvar, node) &&
935760Slinton tr_equal(tp->trcond, cond)) {
945760Slinton break;
955470Slinton }
965760Slinton }
975760Slinton if (tp == NIL) {
985760Slinton trerror("can't delete term %t", node);
995760Slinton }
1005760Slinton if (last == NIL) {
1015760Slinton trhead = tp->trnext;
1025760Slinton } else {
1035760Slinton last->trnext = tp->trnext;
1045760Slinton }
1055760Slinton if (tp->trvalue != NIL) {
1065760Slinton free(tp->trvalue);
1075760Slinton }
1085760Slinton free(tp);
1095470Slinton }
1105470Slinton
1115470Slinton /*
1125470Slinton * Print out any news about variables in the list whose
1135470Slinton * values have changed.
1145470Slinton */
1155470Slinton
prvarnews()1165470Slinton prvarnews()
1175470Slinton {
1185760Slinton register TRINFO *tp;
1195760Slinton register NODE *p;
1205760Slinton register int n;
1215760Slinton SYM *s;
1225760Slinton char buff[MAXTRSIZE];
1235760Slinton static LINENO prevline;
1245470Slinton
1255760Slinton for (tp = trhead; tp != NIL; tp = tp->trnext) {
1265760Slinton if (tp->trcond != NIL && !cond(tp->trcond)) {
1275760Slinton continue;
1285470Slinton }
1295760Slinton s = curfunc;
1305760Slinton while (s != NIL && s != tp->trblock) {
1315760Slinton s = container(s);
1325760Slinton }
1335760Slinton if (s == NIL) {
1345760Slinton continue;
1355760Slinton }
1365760Slinton p = tp->trvar;
1375760Slinton if (tp->traddr == (ADDRESS) -1) {
1385760Slinton tp->traddr = lval(p->left);
1395760Slinton }
1405760Slinton n = size(p->nodetype);
1415760Slinton dread(buff, tp->traddr, n);
1425760Slinton if (tp->trvalue == NIL) {
1435760Slinton tp->trvalue = alloc(n, char);
1445760Slinton mov(buff, tp->trvalue, n);
1455760Slinton mov(buff, sp, n);
1465760Slinton sp += n;
14730843Smckusick #ifdef tahoe
14830843Smckusick alignstack();
14930843Smckusick #endif
1505760Slinton if (tp->trtype == TRPRINT) {
1515760Slinton printf("initially (at ");
1525760Slinton printwhere(curline, srcfilename(pc));
1535760Slinton printf("):\t");
1545760Slinton prtree(p);
1555760Slinton printf(" = ");
1565760Slinton printval(p->nodetype);
1575760Slinton putchar('\n');
1585760Slinton }
1595760Slinton } else if (cmp(tp->trvalue, buff, n) != 0) {
1605760Slinton mov(buff, tp->trvalue, n);
1615760Slinton mov(buff, sp, n);
1625760Slinton sp += n;
16330843Smckusick #ifdef tahoe
16430843Smckusick alignstack();
16530843Smckusick #endif
1665760Slinton printf("after ");
1675760Slinton printwhere(prevline, srcfilename(pc));
1685760Slinton printf(":\t");
1695760Slinton prtree(p);
1705760Slinton printf(" = ");
1715760Slinton printval(p->nodetype);
1725760Slinton putchar('\n');
1735760Slinton if (tp->trtype == TRSTOP) {
1745760Slinton isstopped = TRUE;
1755760Slinton curline = srcline(pc);
1765760Slinton printstatus();
1775760Slinton }
1785760Slinton }
1795760Slinton }
1805760Slinton prevline = curline;
1815470Slinton }
1825470Slinton
1835470Slinton /*
1845470Slinton * Free the table. Note that trvar and trcond fields are not freed,
1855470Slinton * this is because they are the same as in the breakpoint table and
1865470Slinton * are freed by the bpfree routine.
1875470Slinton */
1885470Slinton
trfree()1895470Slinton trfree()
1905470Slinton {
1915760Slinton register TRINFO *tp, *next;
1925470Slinton
1935760Slinton for (tp = trhead; tp != NIL; tp = next) {
1945760Slinton next = tp->trnext;
1955760Slinton if (tp->trvalue != NIL) {
1965760Slinton free(tp->trvalue);
1975470Slinton }
1985760Slinton free(tp);
1995760Slinton }
2005760Slinton trhead = NIL;
2015470Slinton }
202