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