1*48101Sbostic /*- 2*48101Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48101Sbostic * All rights reserved. 4*48101Sbostic * 5*48101Sbostic * %sccs.include.redist.c% 622369Sdist */ 75487Slinton 822369Sdist #ifndef lint 9*48101Sbostic static char sccsid[] = "@(#)setbp.c 5.3 (Berkeley) 04/16/91"; 10*48101Sbostic #endif /* not lint */ 11*48101Sbostic 125487Slinton /* 135487Slinton * Breakpoint/machine interface. 145487Slinton */ 155487Slinton 165487Slinton #include "defs.h" 175487Slinton #include <signal.h> 185487Slinton #include "machine.h" 195487Slinton #include "process.h" 205487Slinton #include "main.h" 215487Slinton #include "pxops.h" 225487Slinton #include "process/process.rep" 2330845Smckusick #include "process/pxinfo.h" 245487Slinton 255487Slinton #define BP_OP O_BPT /* breakpoint trap */ 265487Slinton #define BP_ERRNO SIGILL /* signal received at a breakpoint */ 275487Slinton 285487Slinton /* 295487Slinton * Setting a breakpoint at a location consists of saving 305487Slinton * the half-word at the location and poking a BP_OP there. 315487Slinton * 325487Slinton * We save the locations and half-words on a list for use in unsetting. 335487Slinton */ 345487Slinton 355487Slinton typedef struct savelist SAVELIST; 365487Slinton 375487Slinton struct savelist { 385487Slinton ADDRESS location; 395487Slinton short save; 405487Slinton short refcount; 415487Slinton SAVELIST *link; 425487Slinton }; 435487Slinton 445487Slinton LOCAL SAVELIST *savelist; 455487Slinton 465487Slinton /* 475487Slinton * Set a breakpoint at the given address. Only save the half-word there 485487Slinton * if it's not already a breakpoint. 495487Slinton */ 505487Slinton 515487Slinton setbp(addr) 525487Slinton ADDRESS addr; 535487Slinton { 5430845Smckusick unsigned char w; 555487Slinton short save; 565487Slinton register SAVELIST *newsave, *s; 575487Slinton 585487Slinton if (option('b')) { 595487Slinton printf("setting breakpoint at %d\n", addr); 605487Slinton fflush(stdout); 615487Slinton } 625487Slinton for (s = savelist; s != NIL; s = s->link) { 635487Slinton if (s->location == addr) { 645487Slinton s->refcount++; 655487Slinton return; 665487Slinton } 675487Slinton } 685487Slinton iread(&save, addr, sizeof(save)); 695487Slinton newsave = alloc(1, SAVELIST); 705487Slinton newsave->location = addr; 715487Slinton newsave->save = save; 725487Slinton newsave->refcount = 1; 735487Slinton newsave->link = savelist; 745487Slinton savelist = newsave; 755487Slinton w = BP_OP; 765487Slinton iwrite(&w, addr, sizeof(w)); 775487Slinton } 785487Slinton 795487Slinton /* 805487Slinton * Unset a breakpoint; unfortunately we have to search the SAVELIST 815487Slinton * to find the saved value. The assumption is that the SAVELIST will 825487Slinton * usually be quite small. 835487Slinton */ 845487Slinton 855487Slinton unsetbp(addr) 865487Slinton ADDRESS addr; 875487Slinton { 885487Slinton register SAVELIST *s, *prev; 895487Slinton 905487Slinton if (option('b')) { 915487Slinton printf("unsetting breakpoint at %d\n", addr); 925487Slinton fflush(stdout); 935487Slinton } 945487Slinton prev = NIL; 955487Slinton for (s = savelist; s != NIL; s = s->link) { 965487Slinton if (s->location == addr) { 975487Slinton iwrite(&s->save, addr, sizeof(s->save)); 985487Slinton s->refcount--; 995487Slinton if (s->refcount == 0) { 1005487Slinton if (prev == NIL) { 1015487Slinton savelist = s->link; 1025487Slinton } else { 1035487Slinton prev->link = s->link; 1045487Slinton } 1055487Slinton dispose(s); 1065487Slinton } 1075487Slinton return; 1085487Slinton } 1095487Slinton prev = s; 1105487Slinton } 1115487Slinton panic("unsetbp: couldn't find address %d", addr); 1125487Slinton } 1135487Slinton 1145487Slinton /* 1155487Slinton * Predicate to test if the reason the process stopped was because 1165487Slinton * of a breakpoint. 1175487Slinton */ 1185487Slinton 1195487Slinton BOOLEAN isbperr() 1205487Slinton { 1215487Slinton register PROCESS *p; 1225487Slinton 1235487Slinton p = process; 1245487Slinton return(p->status==STOPPED && p->signo==BP_ERRNO); 1255487Slinton } 126