1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)setbp.c 1.1 01/18/82"; 4 5 /* 6 * Breakpoint/machine interface. 7 */ 8 9 #include "defs.h" 10 #include <signal.h> 11 #include "machine.h" 12 #include "process.h" 13 #include "main.h" 14 #include "pxops.h" 15 #include "process/process.rep" 16 17 #define BP_OP O_BPT /* breakpoint trap */ 18 #define BP_ERRNO SIGILL /* signal received at a breakpoint */ 19 20 /* 21 * Setting a breakpoint at a location consists of saving 22 * the half-word at the location and poking a BP_OP there. 23 * 24 * We save the locations and half-words on a list for use in unsetting. 25 */ 26 27 typedef struct savelist SAVELIST; 28 29 struct savelist { 30 ADDRESS location; 31 short save; 32 short refcount; 33 SAVELIST *link; 34 }; 35 36 LOCAL SAVELIST *savelist; 37 38 /* 39 * Set a breakpoint at the given address. Only save the half-word there 40 * if it's not already a breakpoint. 41 */ 42 43 setbp(addr) 44 ADDRESS addr; 45 { 46 short w; 47 short save; 48 register SAVELIST *newsave, *s; 49 50 if (option('b')) { 51 printf("setting breakpoint at %d\n", addr); 52 fflush(stdout); 53 } 54 for (s = savelist; s != NIL; s = s->link) { 55 if (s->location == addr) { 56 s->refcount++; 57 return; 58 } 59 } 60 iread(&save, addr, sizeof(save)); 61 newsave = alloc(1, SAVELIST); 62 newsave->location = addr; 63 newsave->save = save; 64 newsave->refcount = 1; 65 newsave->link = savelist; 66 savelist = newsave; 67 w = BP_OP; 68 iwrite(&w, addr, sizeof(w)); 69 } 70 71 /* 72 * Unset a breakpoint; unfortunately we have to search the SAVELIST 73 * to find the saved value. The assumption is that the SAVELIST will 74 * usually be quite small. 75 */ 76 77 unsetbp(addr) 78 ADDRESS addr; 79 { 80 register SAVELIST *s, *prev; 81 82 if (option('b')) { 83 printf("unsetting breakpoint at %d\n", addr); 84 fflush(stdout); 85 } 86 prev = NIL; 87 for (s = savelist; s != NIL; s = s->link) { 88 if (s->location == addr) { 89 iwrite(&s->save, addr, sizeof(s->save)); 90 s->refcount--; 91 if (s->refcount == 0) { 92 if (prev == NIL) { 93 savelist = s->link; 94 } else { 95 prev->link = s->link; 96 } 97 dispose(s); 98 } 99 return; 100 } 101 prev = s; 102 } 103 panic("unsetbp: couldn't find address %d", addr); 104 } 105 106 /* 107 * Predicate to test if the reason the process stopped was because 108 * of a breakpoint. 109 */ 110 111 BOOLEAN isbperr() 112 { 113 register PROCESS *p; 114 115 p = process; 116 return(p->status==STOPPED && p->signo==BP_ERRNO); 117 } 118