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