|
|
1.1 ! root 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) 6/6/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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.