|
|
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.2 (Berkeley) 4/7/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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.