/*
* 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);
}
}
|