13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier * functions for running the debugged process
33e12c5d1SDavid du Colombier */
43e12c5d1SDavid du Colombier
53e12c5d1SDavid du Colombier #include "defs.h"
63e12c5d1SDavid du Colombier #include "fns.h"
73e12c5d1SDavid du Colombier
83e12c5d1SDavid du Colombier
93e12c5d1SDavid du Colombier int child;
103e12c5d1SDavid du Colombier int msgfd = -1;
113e12c5d1SDavid du Colombier int notefd = -1;
123e12c5d1SDavid du Colombier int pcspid = -1;
133e12c5d1SDavid du Colombier int pcsactive = 0;
143e12c5d1SDavid du Colombier
153e12c5d1SDavid du Colombier void
setpcs(void)163e12c5d1SDavid du Colombier setpcs(void)
173e12c5d1SDavid du Colombier {
183e12c5d1SDavid du Colombier char buf[128];
193e12c5d1SDavid du Colombier
203e12c5d1SDavid du Colombier if(pid && pid != pcspid){
213e12c5d1SDavid du Colombier if(msgfd >= 0){
223e12c5d1SDavid du Colombier close(msgfd);
233e12c5d1SDavid du Colombier msgfd = -1;
243e12c5d1SDavid du Colombier }
253e12c5d1SDavid du Colombier if(notefd >= 0){
263e12c5d1SDavid du Colombier close(notefd);
273e12c5d1SDavid du Colombier notefd = -1;
283e12c5d1SDavid du Colombier }
293e12c5d1SDavid du Colombier pcspid = -1;
303e12c5d1SDavid du Colombier sprint(buf, "/proc/%d/ctl", pid);
313e12c5d1SDavid du Colombier msgfd = open(buf, OWRITE);
323e12c5d1SDavid du Colombier if(msgfd < 0)
333e12c5d1SDavid du Colombier error("can't open control file");
343e12c5d1SDavid du Colombier sprint(buf, "/proc/%d/note", pid);
353e12c5d1SDavid du Colombier notefd = open(buf, ORDWR);
363e12c5d1SDavid du Colombier if(notefd < 0)
373e12c5d1SDavid du Colombier error("can't open note file");
383e12c5d1SDavid du Colombier pcspid = pid;
393e12c5d1SDavid du Colombier }
403e12c5d1SDavid du Colombier }
413e12c5d1SDavid du Colombier
423e12c5d1SDavid du Colombier void
msgpcs(char * msg)433e12c5d1SDavid du Colombier msgpcs(char *msg)
443e12c5d1SDavid du Colombier {
459a747e4fSDavid du Colombier char err[ERRMAX];
463e12c5d1SDavid du Colombier
473e12c5d1SDavid du Colombier setpcs();
483e12c5d1SDavid du Colombier if(write(msgfd, msg, strlen(msg)) < 0 && !ending){
499a747e4fSDavid du Colombier errstr(err, sizeof err);
503e12c5d1SDavid du Colombier if(strcmp(err, "interrupted") != 0)
513e12c5d1SDavid du Colombier endpcs();
523e12c5d1SDavid du Colombier errors("can't write control file", err);
533e12c5d1SDavid du Colombier }
543e12c5d1SDavid du Colombier }
553e12c5d1SDavid du Colombier
563e12c5d1SDavid du Colombier /*
573e12c5d1SDavid du Colombier * empty the note buffer and toss pending breakpoint notes
583e12c5d1SDavid du Colombier */
593e12c5d1SDavid du Colombier void
unloadnote(void)603e12c5d1SDavid du Colombier unloadnote(void)
613e12c5d1SDavid du Colombier {
629a747e4fSDavid du Colombier char err[ERRMAX];
633e12c5d1SDavid du Colombier
643e12c5d1SDavid du Colombier setpcs();
653e12c5d1SDavid du Colombier for(; nnote<NNOTE; nnote++){
669a747e4fSDavid du Colombier switch(read(notefd, note[nnote], sizeof note[nnote])){
673e12c5d1SDavid du Colombier case -1:
689a747e4fSDavid du Colombier errstr(err, sizeof err);
693e12c5d1SDavid du Colombier if(strcmp(err, "interrupted") != 0)
703e12c5d1SDavid du Colombier endpcs();
713e12c5d1SDavid du Colombier errors("can't read note file", err);
723e12c5d1SDavid du Colombier case 0:
733e12c5d1SDavid du Colombier return;
743e12c5d1SDavid du Colombier }
759a747e4fSDavid du Colombier note[nnote][ERRMAX-1] = '\0';
763e12c5d1SDavid du Colombier if(strncmp(note[nnote], "sys: breakpoint", 15) == 0)
773e12c5d1SDavid du Colombier --nnote;
783e12c5d1SDavid du Colombier }
793e12c5d1SDavid du Colombier }
803e12c5d1SDavid du Colombier
813e12c5d1SDavid du Colombier /*
823e12c5d1SDavid du Colombier * reload the note buffer
833e12c5d1SDavid du Colombier */
843e12c5d1SDavid du Colombier void
loadnote(void)853e12c5d1SDavid du Colombier loadnote(void)
863e12c5d1SDavid du Colombier {
873e12c5d1SDavid du Colombier int i;
889a747e4fSDavid du Colombier char err[ERRMAX];
893e12c5d1SDavid du Colombier
903e12c5d1SDavid du Colombier setpcs();
913e12c5d1SDavid du Colombier for(i=0; i<nnote; i++){
923e12c5d1SDavid du Colombier if(write(notefd, note[i], strlen(note[i])) < 0){
939a747e4fSDavid du Colombier errstr(err, sizeof err);
943e12c5d1SDavid du Colombier if(strcmp(err, "interrupted") != 0)
953e12c5d1SDavid du Colombier endpcs();
963e12c5d1SDavid du Colombier errors("can't write note file", err);
973e12c5d1SDavid du Colombier }
983e12c5d1SDavid du Colombier }
993e12c5d1SDavid du Colombier nnote = 0;
1003e12c5d1SDavid du Colombier }
1013e12c5d1SDavid du Colombier
1023e12c5d1SDavid du Colombier void
notes(void)1033e12c5d1SDavid du Colombier notes(void)
1043e12c5d1SDavid du Colombier {
1053e12c5d1SDavid du Colombier int n;
1063e12c5d1SDavid du Colombier
1073e12c5d1SDavid du Colombier if(nnote == 0)
1083e12c5d1SDavid du Colombier return;
1093e12c5d1SDavid du Colombier dprint("notes:\n");
1103e12c5d1SDavid du Colombier for(n=0; n<nnote; n++)
1113e12c5d1SDavid du Colombier dprint("%d:\t%s\n", n, note[n]);
1123e12c5d1SDavid du Colombier }
1133e12c5d1SDavid du Colombier
1143e12c5d1SDavid du Colombier void
killpcs(void)1153e12c5d1SDavid du Colombier killpcs(void)
1163e12c5d1SDavid du Colombier {
1173e12c5d1SDavid du Colombier msgpcs("kill");
1183e12c5d1SDavid du Colombier }
1193e12c5d1SDavid du Colombier
1203e12c5d1SDavid du Colombier void
grab(void)1213e12c5d1SDavid du Colombier grab(void)
1223e12c5d1SDavid du Colombier {
1233e12c5d1SDavid du Colombier flush();
1243e12c5d1SDavid du Colombier msgpcs("stop");
1253e12c5d1SDavid du Colombier bpwait();
1263e12c5d1SDavid du Colombier }
1273e12c5d1SDavid du Colombier
1283e12c5d1SDavid du Colombier void
ungrab(void)1293e12c5d1SDavid du Colombier ungrab(void)
1303e12c5d1SDavid du Colombier {
1313e12c5d1SDavid du Colombier msgpcs("start");
1323e12c5d1SDavid du Colombier }
1333e12c5d1SDavid du Colombier
1343e12c5d1SDavid du Colombier void
doexec(void)1353e12c5d1SDavid du Colombier doexec(void)
1363e12c5d1SDavid du Colombier {
1373e12c5d1SDavid du Colombier char *argl[MAXARG];
1383e12c5d1SDavid du Colombier char args[LINSIZ];
1393e12c5d1SDavid du Colombier char *p;
1403e12c5d1SDavid du Colombier char **ap;
1413e12c5d1SDavid du Colombier char *thisarg;
1423e12c5d1SDavid du Colombier
1433e12c5d1SDavid du Colombier ap = argl;
1443e12c5d1SDavid du Colombier p = args;
1453e12c5d1SDavid du Colombier *ap++ = symfil;
1463e12c5d1SDavid du Colombier for (rdc(); lastc != EOR;) {
1473e12c5d1SDavid du Colombier thisarg = p;
1483e12c5d1SDavid du Colombier if (lastc == '<' || lastc == '>') {
1493e12c5d1SDavid du Colombier *p++ = lastc;
1503e12c5d1SDavid du Colombier rdc();
1513e12c5d1SDavid du Colombier }
1523e12c5d1SDavid du Colombier while (lastc != EOR && lastc != SPC && lastc != TB) {
1533e12c5d1SDavid du Colombier *p++ = lastc;
1543e12c5d1SDavid du Colombier readchar();
1553e12c5d1SDavid du Colombier }
1563e12c5d1SDavid du Colombier if (lastc == SPC || lastc == TB)
1573e12c5d1SDavid du Colombier rdc();
1583e12c5d1SDavid du Colombier *p++ = 0;
1593e12c5d1SDavid du Colombier if (*thisarg == '<') {
1603e12c5d1SDavid du Colombier close(0);
1613e12c5d1SDavid du Colombier if (open(&thisarg[1], OREAD) < 0) {
1623e12c5d1SDavid du Colombier print("%s: cannot open\n", &thisarg[1]);
1633e12c5d1SDavid du Colombier _exits(0);
1643e12c5d1SDavid du Colombier }
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier else if (*thisarg == '>') {
1673e12c5d1SDavid du Colombier close(1);
1683e12c5d1SDavid du Colombier if (create(&thisarg[1], OWRITE, 0666) < 0) {
1693e12c5d1SDavid du Colombier print("%s: cannot create\n", &thisarg[1]);
1703e12c5d1SDavid du Colombier _exits(0);
1713e12c5d1SDavid du Colombier }
1723e12c5d1SDavid du Colombier }
1733e12c5d1SDavid du Colombier else
1743e12c5d1SDavid du Colombier *ap++ = thisarg;
1753e12c5d1SDavid du Colombier }
1763e12c5d1SDavid du Colombier *ap = 0;
1773e12c5d1SDavid du Colombier exec(symfil, argl);
1783e12c5d1SDavid du Colombier perror(symfil);
1793e12c5d1SDavid du Colombier }
1803e12c5d1SDavid du Colombier
1813e12c5d1SDavid du Colombier char procname[100];
1823e12c5d1SDavid du Colombier
1833e12c5d1SDavid du Colombier void
startpcs(void)1843e12c5d1SDavid du Colombier startpcs(void)
1853e12c5d1SDavid du Colombier {
1863e12c5d1SDavid du Colombier if ((pid = fork()) == 0) {
1873e12c5d1SDavid du Colombier pid = getpid();
1883e12c5d1SDavid du Colombier msgpcs("hang");
1893e12c5d1SDavid du Colombier doexec();
1903e12c5d1SDavid du Colombier exits(0);
1913e12c5d1SDavid du Colombier }
1923e12c5d1SDavid du Colombier
1933e12c5d1SDavid du Colombier if (pid == -1)
1943e12c5d1SDavid du Colombier error("can't fork");
1953e12c5d1SDavid du Colombier child++;
1963e12c5d1SDavid du Colombier sprint(procname, "/proc/%d/mem", pid);
1973e12c5d1SDavid du Colombier corfil = procname;
1983e12c5d1SDavid du Colombier msgpcs("waitstop");
1993e12c5d1SDavid du Colombier bpwait();
2003e12c5d1SDavid du Colombier if (adrflg)
201219b2ee8SDavid du Colombier rput(cormap, mach->pc, adrval);
2023e12c5d1SDavid du Colombier while (rdc() != EOR)
2033e12c5d1SDavid du Colombier ;
2043e12c5d1SDavid du Colombier reread();
2053e12c5d1SDavid du Colombier }
2063e12c5d1SDavid du Colombier
2073e12c5d1SDavid du Colombier void
runstep(uvlong loc,int keepnote)208*4de34a7eSDavid du Colombier runstep(uvlong loc, int keepnote)
2093e12c5d1SDavid du Colombier {
2103e12c5d1SDavid du Colombier int nfoll;
211*4de34a7eSDavid du Colombier uvlong foll[3];
2123e12c5d1SDavid du Colombier BKPT bkpt[3];
2133e12c5d1SDavid du Colombier int i;
2143e12c5d1SDavid du Colombier
2153e12c5d1SDavid du Colombier if(machdata->foll == 0){
2163e12c5d1SDavid du Colombier dprint("stepping unimplemented; assuming not a branch\n");
2173e12c5d1SDavid du Colombier nfoll = 1;
2183e12c5d1SDavid du Colombier foll[0] = loc+mach->pcquant;
219219b2ee8SDavid du Colombier }else {
220219b2ee8SDavid du Colombier nfoll = machdata->foll(cormap, loc, rget, foll);
221219b2ee8SDavid du Colombier if (nfoll < 0)
222219b2ee8SDavid du Colombier error("%r");
223219b2ee8SDavid du Colombier }
2243e12c5d1SDavid du Colombier memset(bkpt, 0, sizeof bkpt);
2253e12c5d1SDavid du Colombier for(i=0; i<nfoll; i++){
2263e12c5d1SDavid du Colombier if(foll[i] == loc)
2273e12c5d1SDavid du Colombier error("can't single step: next instruction is dot");
2283e12c5d1SDavid du Colombier bkpt[i].loc = foll[i];
2293e12c5d1SDavid du Colombier bkput(&bkpt[i], 1);
2303e12c5d1SDavid du Colombier }
2313e12c5d1SDavid du Colombier runrun(keepnote);
2323e12c5d1SDavid du Colombier for(i=0; i<nfoll; i++)
2333e12c5d1SDavid du Colombier bkput(&bkpt[i], 0);
2343e12c5d1SDavid du Colombier }
2353e12c5d1SDavid du Colombier
2363e12c5d1SDavid du Colombier void
bpwait(void)2373e12c5d1SDavid du Colombier bpwait(void)
2383e12c5d1SDavid du Colombier {
239219b2ee8SDavid du Colombier setcor();
2403e12c5d1SDavid du Colombier unloadnote();
2413e12c5d1SDavid du Colombier }
2423e12c5d1SDavid du Colombier
2433e12c5d1SDavid du Colombier void
runrun(int keepnote)2443e12c5d1SDavid du Colombier runrun(int keepnote)
2453e12c5d1SDavid du Colombier {
2463e12c5d1SDavid du Colombier int on;
2473e12c5d1SDavid du Colombier
2483e12c5d1SDavid du Colombier on = nnote;
2493e12c5d1SDavid du Colombier unloadnote();
2503e12c5d1SDavid du Colombier if(on != nnote){
2513e12c5d1SDavid du Colombier notes();
2523e12c5d1SDavid du Colombier error("not running: new notes pending");
2533e12c5d1SDavid du Colombier }
2543e12c5d1SDavid du Colombier if(keepnote)
2553e12c5d1SDavid du Colombier loadnote();
2563e12c5d1SDavid du Colombier else
2573e12c5d1SDavid du Colombier nnote = 0;
2583e12c5d1SDavid du Colombier flush();
2593e12c5d1SDavid du Colombier msgpcs("startstop");
2603e12c5d1SDavid du Colombier bpwait();
2613e12c5d1SDavid du Colombier }
2623e12c5d1SDavid du Colombier
2633e12c5d1SDavid du Colombier void
bkput(BKPT * bp,int install)2643e12c5d1SDavid du Colombier bkput(BKPT *bp, int install)
2653e12c5d1SDavid du Colombier {
2663e12c5d1SDavid du Colombier char buf[256];
267*4de34a7eSDavid du Colombier ADDR loc;
268219b2ee8SDavid du Colombier int ret;
2693e12c5d1SDavid du Colombier
2709a747e4fSDavid du Colombier errstr(buf, sizeof buf);
2713e12c5d1SDavid du Colombier if(machdata->bpfix)
2723e12c5d1SDavid du Colombier loc = (*machdata->bpfix)(bp->loc);
2733e12c5d1SDavid du Colombier else
2743e12c5d1SDavid du Colombier loc = bp->loc;
2753e12c5d1SDavid du Colombier if(install){
276219b2ee8SDavid du Colombier ret = get1(cormap, loc, bp->save, machdata->bpsize);
277219b2ee8SDavid du Colombier if (ret > 0)
278219b2ee8SDavid du Colombier ret = put1(cormap, loc, machdata->bpinst, machdata->bpsize);
2793e12c5d1SDavid du Colombier }else
280219b2ee8SDavid du Colombier ret = put1(cormap, loc, bp->save, machdata->bpsize);
281219b2ee8SDavid du Colombier if(ret < 0){
2829a747e4fSDavid du Colombier sprint(buf, "can't set breakpoint at %#llux: %r", bp->loc);
2833e12c5d1SDavid du Colombier print(buf);
2843e12c5d1SDavid du Colombier read(0, buf, 100);
2853e12c5d1SDavid du Colombier }
2863e12c5d1SDavid du Colombier }
287