122282Sdist /* 222282Sdist * Copyright (c) 1980 Regents of the University of California. 322282Sdist * All rights reserved. The Berkeley software License Agreement 422282Sdist * specifies the terms and conditions for redistribution. 522282Sdist */ 65470Slinton 722282Sdist #ifndef lint 8*30843Smckusick static char sccsid[] = "@(#)trinfo.c 5.2 (Berkeley) 04/07/87"; 922282Sdist #endif not lint 105470Slinton 115470Slinton /* 125470Slinton * Trace information management. 135470Slinton * 145470Slinton * The trace information is a list of variables that are being 155470Slinton * traced or whose value changing should cause a stop. 165470Slinton */ 175470Slinton 185470Slinton #include "defs.h" 195470Slinton #include "breakpoint.h" 205470Slinton #include "process.h" 215470Slinton #include "machine.h" 225470Slinton #include "sym.h" 235470Slinton #include "tree.h" 245470Slinton #include "source.h" 255470Slinton #include "object.h" 265470Slinton #include "tree/tree.rep" 27*30843Smckusick #include "process/process.rep" 28*30843Smckusick #include "process/pxinfo.h" 295470Slinton 305470Slinton /* 315470Slinton * When tracing variables we keep a copy of their most recent value 325470Slinton * and compare it to the current one each time a breakpoint occurs. 335470Slinton * MAXTRSIZE is the maximum size variable we allow. 345470Slinton */ 355470Slinton 365470Slinton #define MAXTRSIZE 512 375470Slinton 385470Slinton /* 395470Slinton * The tracing structure is a list of information about all the 405470Slinton * variables that are being traced. 415470Slinton */ 425470Slinton 435470Slinton typedef struct trinfo { 445760Slinton TRTYPE trtype; 455760Slinton ADDRESS traddr; 465760Slinton SYM *trblock; 475760Slinton NODE *trvar; 485760Slinton NODE *trcond; 495760Slinton char *trvalue; 505760Slinton struct trinfo *trnext; 515470Slinton } TRINFO; 525470Slinton 535470Slinton LOCAL TRINFO *trhead; 545470Slinton 555470Slinton /* 565470Slinton * add a variable to be traced 575470Slinton */ 585470Slinton 595470Slinton addvar(trtype, node, cond) 605470Slinton TRTYPE trtype; 615470Slinton NODE *node; 625470Slinton NODE *cond; 635470Slinton { 645760Slinton register TRINFO *tp; 655470Slinton 665760Slinton tp = alloc(1, TRINFO); 675760Slinton tp->trtype = trtype; 685760Slinton tp->traddr = (ADDRESS) -1; 695760Slinton tp->trblock = curfunc; 705760Slinton tp->trvar = node; 715760Slinton tp->trcond = cond; 725760Slinton tp->trvalue = NIL; 735760Slinton tp->trnext = trhead; 745760Slinton trhead = tp; 755470Slinton } 765470Slinton 775470Slinton /* 785470Slinton * remove a variable from the trace list 795470Slinton */ 805470Slinton 815470Slinton delvar(trtype, node, cond) 825470Slinton TRTYPE trtype; 835470Slinton NODE *node; 845470Slinton NODE *cond; 855470Slinton { 865760Slinton register TRINFO *tp, *last; 875470Slinton 885760Slinton last = NIL; 895760Slinton for (tp = trhead; tp != NIL; tp = tp->trnext) { 905760Slinton if (tp->trtype == trtype && 915760Slinton tr_equal(tp->trvar, node) && 925760Slinton tr_equal(tp->trcond, cond)) { 935760Slinton break; 945470Slinton } 955760Slinton } 965760Slinton if (tp == NIL) { 975760Slinton trerror("can't delete term %t", node); 985760Slinton } 995760Slinton if (last == NIL) { 1005760Slinton trhead = tp->trnext; 1015760Slinton } else { 1025760Slinton last->trnext = tp->trnext; 1035760Slinton } 1045760Slinton if (tp->trvalue != NIL) { 1055760Slinton free(tp->trvalue); 1065760Slinton } 1075760Slinton free(tp); 1085470Slinton } 1095470Slinton 1105470Slinton /* 1115470Slinton * Print out any news about variables in the list whose 1125470Slinton * values have changed. 1135470Slinton */ 1145470Slinton 1155470Slinton prvarnews() 1165470Slinton { 1175760Slinton register TRINFO *tp; 1185760Slinton register NODE *p; 1195760Slinton register int n; 1205760Slinton SYM *s; 1215760Slinton char buff[MAXTRSIZE]; 1225760Slinton static LINENO prevline; 1235470Slinton 1245760Slinton for (tp = trhead; tp != NIL; tp = tp->trnext) { 1255760Slinton if (tp->trcond != NIL && !cond(tp->trcond)) { 1265760Slinton continue; 1275470Slinton } 1285760Slinton s = curfunc; 1295760Slinton while (s != NIL && s != tp->trblock) { 1305760Slinton s = container(s); 1315760Slinton } 1325760Slinton if (s == NIL) { 1335760Slinton continue; 1345760Slinton } 1355760Slinton p = tp->trvar; 1365760Slinton if (tp->traddr == (ADDRESS) -1) { 1375760Slinton tp->traddr = lval(p->left); 1385760Slinton } 1395760Slinton n = size(p->nodetype); 1405760Slinton dread(buff, tp->traddr, n); 1415760Slinton if (tp->trvalue == NIL) { 1425760Slinton tp->trvalue = alloc(n, char); 1435760Slinton mov(buff, tp->trvalue, n); 1445760Slinton mov(buff, sp, n); 1455760Slinton sp += n; 146*30843Smckusick #ifdef tahoe 147*30843Smckusick alignstack(); 148*30843Smckusick #endif 1495760Slinton if (tp->trtype == TRPRINT) { 1505760Slinton printf("initially (at "); 1515760Slinton printwhere(curline, srcfilename(pc)); 1525760Slinton printf("):\t"); 1535760Slinton prtree(p); 1545760Slinton printf(" = "); 1555760Slinton printval(p->nodetype); 1565760Slinton putchar('\n'); 1575760Slinton } 1585760Slinton } else if (cmp(tp->trvalue, buff, n) != 0) { 1595760Slinton mov(buff, tp->trvalue, n); 1605760Slinton mov(buff, sp, n); 1615760Slinton sp += n; 162*30843Smckusick #ifdef tahoe 163*30843Smckusick alignstack(); 164*30843Smckusick #endif 1655760Slinton printf("after "); 1665760Slinton printwhere(prevline, srcfilename(pc)); 1675760Slinton printf(":\t"); 1685760Slinton prtree(p); 1695760Slinton printf(" = "); 1705760Slinton printval(p->nodetype); 1715760Slinton putchar('\n'); 1725760Slinton if (tp->trtype == TRSTOP) { 1735760Slinton isstopped = TRUE; 1745760Slinton curline = srcline(pc); 1755760Slinton printstatus(); 1765760Slinton } 1775760Slinton } 1785760Slinton } 1795760Slinton prevline = curline; 1805470Slinton } 1815470Slinton 1825470Slinton /* 1835470Slinton * Free the table. Note that trvar and trcond fields are not freed, 1845470Slinton * this is because they are the same as in the breakpoint table and 1855470Slinton * are freed by the bpfree routine. 1865470Slinton */ 1875470Slinton 1885470Slinton trfree() 1895470Slinton { 1905760Slinton register TRINFO *tp, *next; 1915470Slinton 1925760Slinton for (tp = trhead; tp != NIL; tp = next) { 1935760Slinton next = tp->trnext; 1945760Slinton if (tp->trvalue != NIL) { 1955760Slinton free(tp->trvalue); 1965470Slinton } 1975760Slinton free(tp); 1985760Slinton } 1995760Slinton trhead = NIL; 2005470Slinton } 201