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