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