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