/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ /* * functions for running the debugged process */ #include "defs.h"#include "fns.h" int child;int msgfd = -1;int notefd = -1;int pcspid = -1;int pcsactive = 0; voidsetpcs(void){ char buf[128]; if(pid && pid != pcspid){ if(msgfd >= 0){ close(msgfd); msgfd = -1; } if(notefd >= 0){ close(notefd); notefd = -1; } pcspid = -1; sprint(buf, "/proc/%d/ctl", pid); msgfd = open(buf, OWRITE); if(msgfd < 0) error("can't open control file"); sprint(buf, "/proc/%d/note", pid); notefd = open(buf, ORDWR); if(notefd < 0) error("can't open note file"); pcspid = pid; }} voidmsgpcs(char *msg){ char err[ERRMAX]; setpcs(); if(write(msgfd, msg, strlen(msg)) < 0 && !ending){ errstr(err, sizeof err); if(strcmp(err, "interrupted") != 0) endpcs(); errors("can't write control file", err); }} /* * empty the note buffer and toss pending breakpoint notes */voidunloadnote(void){ char err[ERRMAX]; setpcs(); for(; nnote<NNOTE; nnote++){ switch(read(notefd, note[nnote], sizeof note[nnote])){ case -1: errstr(err, sizeof err); if(strcmp(err, "interrupted") != 0) endpcs(); errors("can't read note file", err); case 0: return; } note[nnote][ERRMAX-1] = '\0'; if(strncmp(note[nnote], "sys: breakpoint", 15) == 0) --nnote; }} /* * reload the note buffer */voidloadnote(void){ int i; char err[ERRMAX]; setpcs(); for(i=0; i<nnote; i++){ if(write(notefd, note[i], strlen(note[i])) < 0){ errstr(err, sizeof err); if(strcmp(err, "interrupted") != 0) endpcs(); errors("can't write note file", err); } } nnote = 0;} voidnotes(void){ int n; if(nnote == 0) return; dprint("notes:\n"); for(n=0; n<nnote; n++) dprint("%d:\t%s\n", n, note[n]);} voidkillpcs(void){ msgpcs("kill");} voidgrab(void){ flush(); msgpcs("stop"); bpwait();} voidungrab(void){ msgpcs("start");} voiddoexec(void){ char *argl[MAXARG]; char args[LINSIZ]; char *p; char **ap; char *thisarg; ap = argl; p = args; *ap++ = symfil; for (rdc(); lastc != EOR;) { thisarg = p; if (lastc == '<' || lastc == '>') { *p++ = lastc; rdc(); } while (lastc != EOR && lastc != SPC && lastc != TB) { *p++ = lastc; readchar(); } if (lastc == SPC || lastc == TB) rdc(); *p++ = 0; if (*thisarg == '<') { close(0); if (open(&thisarg[1], OREAD) < 0) { print("%s: cannot open\n", &thisarg[1]); _exits(0); } } else if (*thisarg == '>') { close(1); if (create(&thisarg[1], OWRITE, 0666) < 0) { print("%s: cannot create\n", &thisarg[1]); _exits(0); } } else *ap++ = thisarg; } *ap = 0; exec(symfil, argl); perror(symfil);} char procname[100]; voidstartpcs(void){ if ((pid = fork()) == 0) { pid = getpid(); msgpcs("hang"); doexec(); exits(0); } if (pid == -1) error("can't fork"); child++; sprint(procname, "/proc/%d/mem", pid); corfil = procname; msgpcs("waitstop"); bpwait(); if (adrflg) rput(cormap, mach->pc, adrval); while (rdc() != EOR) ; reread();} voidrunstep(uvlong loc, int keepnote){ int nfoll; uvlong foll[3]; BKPT bkpt[3]; int i; if(machdata->foll == 0){ dprint("stepping unimplemented; assuming not a branch\n"); nfoll = 1; foll[0] = loc+mach->pcquant; }else { nfoll = machdata->foll(cormap, loc, rget, foll); if (nfoll < 0) error("%r"); } memset(bkpt, 0, sizeof bkpt); for(i=0; i<nfoll; i++){ if(foll[i] == loc) error("can't single step: next instruction is dot"); bkpt[i].loc = foll[i]; bkput(&bkpt[i], 1); } runrun(keepnote); for(i=0; i<nfoll; i++) bkput(&bkpt[i], 0);} voidbpwait(void){ setcor(); unloadnote();} voidrunrun(int keepnote){ int on; on = nnote; unloadnote(); if(on != nnote){ notes(); error("not running: new notes pending"); } if(keepnote) loadnote(); else nnote = 0; flush(); msgpcs("startstop"); bpwait();} voidbkput(BKPT *bp, int install){ char buf[256]; ADDR loc; int ret; errstr(buf, sizeof buf); if(machdata->bpfix) loc = (*machdata->bpfix)(bp->loc); else loc = bp->loc; if(install){ ret = get1(cormap, loc, bp->save, machdata->bpsize); if (ret > 0) ret = put1(cormap, loc, machdata->bpinst, machdata->bpsize); }else ret = put1(cormap, loc, bp->save, machdata->bpsize); if(ret < 0){ sprint(buf, "can't set breakpoint at %#llux: %r", bp->loc); print(buf); read(0, buf, 100); }}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
/*
* functions for running the debugged process
*/
#include "defs.h"
#include "fns.h"
int child;
int msgfd = -1;
int notefd = -1;
int pcspid = -1;
int pcsactive = 0;
void
setpcs(void)
{
char buf[128];
if(pid && pid != pcspid){
if(msgfd >= 0){
close(msgfd);
msgfd = -1;
}
if(notefd >= 0){
close(notefd);
notefd = -1;
}
pcspid = -1;
sprint(buf, "/proc/%d/ctl", pid);
msgfd = open(buf, OWRITE);
if(msgfd < 0)
error("can't open control file");
sprint(buf, "/proc/%d/note", pid);
notefd = open(buf, ORDWR);
if(notefd < 0)
error("can't open note file");
pcspid = pid;
}
}
void
msgpcs(char *msg)
{
char err[ERRMAX];
setpcs();
if(write(msgfd, msg, strlen(msg)) < 0 && !ending){
errstr(err, sizeof err);
if(strcmp(err, "interrupted") != 0)
endpcs();
errors("can't write control file", err);
}
}
/*
* empty the note buffer and toss pending breakpoint notes
*/
void
unloadnote(void)
{
char err[ERRMAX];
setpcs();
for(; nnote<NNOTE; nnote++){
switch(read(notefd, note[nnote], sizeof note[nnote])){
case -1:
errstr(err, sizeof err);
if(strcmp(err, "interrupted") != 0)
endpcs();
errors("can't read note file", err);
case 0:
return;
}
note[nnote][ERRMAX-1] = '\0';
if(strncmp(note[nnote], "sys: breakpoint", 15) == 0)
--nnote;
}
}
/*
* reload the note buffer
*/
void
loadnote(void)
{
int i;
char err[ERRMAX];
setpcs();
for(i=0; i<nnote; i++){
if(write(notefd, note[i], strlen(note[i])) < 0){
errstr(err, sizeof err);
if(strcmp(err, "interrupted") != 0)
endpcs();
errors("can't write note file", err);
}
}
nnote = 0;
}
void
notes(void)
{
int n;
if(nnote == 0)
return;
dprint("notes:\n");
for(n=0; n<nnote; n++)
dprint("%d:\t%s\n", n, note[n]);
}
void
killpcs(void)
{
msgpcs("kill");
}
void
grab(void)
{
flush();
msgpcs("stop");
bpwait();
}
void
ungrab(void)
{
msgpcs("start");
}
void
doexec(void)
{
char *argl[MAXARG];
char args[LINSIZ];
char *p;
char **ap;
char *thisarg;
ap = argl;
p = args;
*ap++ = symfil;
for (rdc(); lastc != EOR;) {
thisarg = p;
if (lastc == '<' || lastc == '>') {
*p++ = lastc;
rdc();
}
while (lastc != EOR && lastc != SPC && lastc != TB) {
*p++ = lastc;
readchar();
}
if (lastc == SPC || lastc == TB)
rdc();
*p++ = 0;
if (*thisarg == '<') {
close(0);
if (open(&thisarg[1], OREAD) < 0) {
print("%s: cannot open\n", &thisarg[1]);
_exits(0);
}
}
else if (*thisarg == '>') {
close(1);
if (create(&thisarg[1], OWRITE, 0666) < 0) {
print("%s: cannot create\n", &thisarg[1]);
_exits(0);
}
}
else
*ap++ = thisarg;
}
*ap = 0;
exec(symfil, argl);
perror(symfil);
}
char procname[100];
void
startpcs(void)
{
if ((pid = fork()) == 0) {
pid = getpid();
msgpcs("hang");
doexec();
exits(0);
}
if (pid == -1)
error("can't fork");
child++;
sprint(procname, "/proc/%d/mem", pid);
corfil = procname;
msgpcs("waitstop");
bpwait();
if (adrflg)
rput(cormap, mach->pc, adrval);
while (rdc() != EOR)
;
reread();
}
void
runstep(uvlong loc, int keepnote)
{
int nfoll;
uvlong foll[3];
BKPT bkpt[3];
int i;
if(machdata->foll == 0){
dprint("stepping unimplemented; assuming not a branch\n");
nfoll = 1;
foll[0] = loc+mach->pcquant;
}else {
nfoll = machdata->foll(cormap, loc, rget, foll);
if (nfoll < 0)
error("%r");
}
memset(bkpt, 0, sizeof bkpt);
for(i=0; i<nfoll; i++){
if(foll[i] == loc)
error("can't single step: next instruction is dot");
bkpt[i].loc = foll[i];
bkput(&bkpt[i], 1);
}
runrun(keepnote);
for(i=0; i<nfoll; i++)
bkput(&bkpt[i], 0);
}
void
bpwait(void)
{
setcor();
unloadnote();
}
void
runrun(int keepnote)
{
int on;
on = nnote;
unloadnote();
if(on != nnote){
notes();
error("not running: new notes pending");
}
if(keepnote)
loadnote();
else
nnote = 0;
flush();
msgpcs("startstop");
bpwait();
}
void
bkput(BKPT *bp, int install)
{
char buf[256];
ADDR loc;
int ret;
errstr(buf, sizeof buf);
if(machdata->bpfix)
loc = (*machdata->bpfix)(bp->loc);
else
loc = bp->loc;
if(install){
ret = get1(cormap, loc, bp->save, machdata->bpsize);
if (ret > 0)
ret = put1(cormap, loc, machdata->bpinst, machdata->bpsize);
}else
ret = put1(cormap, loc, bp->save, machdata->bpsize);
if(ret < 0){
sprint(buf, "can't set breakpoint at %#llux: %r", bp->loc);
print(buf);
read(0, buf, 100);
}
}