1 /* 2 * functions for running the debugged process 3 */ 4 5 #include "defs.h" 6 #include "fns.h" 7 8 extern char lastc, peekc; 9 10 int child; 11 int msgfd = -1; 12 int notefd = -1; 13 int pcspid = -1; 14 int pcsactive = 0; 15 16 void 17 setpcs(void) 18 { 19 char buf[128]; 20 21 if(pid && pid != pcspid){ 22 if(msgfd >= 0){ 23 close(msgfd); 24 msgfd = -1; 25 } 26 if(notefd >= 0){ 27 close(notefd); 28 notefd = -1; 29 } 30 pcspid = -1; 31 sprint(buf, "/proc/%d/ctl", pid); 32 msgfd = open(buf, OWRITE); 33 if(msgfd < 0) 34 error("can't open control file"); 35 sprint(buf, "/proc/%d/note", pid); 36 notefd = open(buf, ORDWR); 37 if(notefd < 0) 38 error("can't open note file"); 39 pcspid = pid; 40 } 41 } 42 43 void 44 msgpcs(char *msg) 45 { 46 char err[ERRLEN]; 47 48 setpcs(); 49 if(write(msgfd, msg, strlen(msg)) < 0 && !ending){ 50 errstr(err); 51 if(strcmp(err, "interrupted") != 0) 52 endpcs(); 53 errors("can't write control file", err); 54 } 55 } 56 57 /* 58 * empty the note buffer and toss pending breakpoint notes 59 */ 60 void 61 unloadnote(void) 62 { 63 char err[ERRLEN]; 64 65 setpcs(); 66 for(; nnote<NNOTE; nnote++){ 67 switch(read(notefd, note[nnote], ERRLEN)){ 68 case -1: 69 errstr(err); 70 if(strcmp(err, "interrupted") != 0) 71 endpcs(); 72 errors("can't read note file", err); 73 case 0: 74 return; 75 } 76 note[nnote][ERRLEN-1] = 0; 77 if(strncmp(note[nnote], "sys: breakpoint", 15) == 0) 78 --nnote; 79 } 80 } 81 82 /* 83 * reload the note buffer 84 */ 85 void 86 loadnote(void) 87 { 88 int i; 89 char err[ERRLEN]; 90 91 setpcs(); 92 for(i=0; i<nnote; i++){ 93 if(write(notefd, note[i], strlen(note[i])) < 0){ 94 errstr(err); 95 if(strcmp(err, "interrupted") != 0) 96 endpcs(); 97 errors("can't write note file", err); 98 } 99 } 100 nnote = 0; 101 } 102 103 void 104 notes(void) 105 { 106 int n; 107 108 if(nnote == 0) 109 return; 110 dprint("notes:\n"); 111 for(n=0; n<nnote; n++) 112 dprint("%d:\t%s\n", n, note[n]); 113 } 114 115 void 116 killpcs(void) 117 { 118 msgpcs("kill"); 119 } 120 121 void 122 grab(void) 123 { 124 flush(); 125 msgpcs("stop"); 126 bpwait(); 127 } 128 129 void 130 ungrab(void) 131 { 132 msgpcs("start"); 133 } 134 135 void 136 doexec(void) 137 { 138 char *argl[MAXARG]; 139 char args[LINSIZ]; 140 char *p; 141 char **ap; 142 char *thisarg; 143 144 ap = argl; 145 p = args; 146 *ap++ = symfil; 147 for (rdc(); lastc != EOR;) { 148 thisarg = p; 149 if (lastc == '<' || lastc == '>') { 150 *p++ = lastc; 151 rdc(); 152 } 153 while (lastc != EOR && lastc != SPC && lastc != TB) { 154 *p++ = lastc; 155 readchar(); 156 } 157 if (lastc == SPC || lastc == TB) 158 rdc(); 159 *p++ = 0; 160 if (*thisarg == '<') { 161 close(0); 162 if (open(&thisarg[1], OREAD) < 0) { 163 print("%s: cannot open\n", &thisarg[1]); 164 _exits(0); 165 } 166 } 167 else if (*thisarg == '>') { 168 close(1); 169 if (create(&thisarg[1], OWRITE, 0666) < 0) { 170 print("%s: cannot create\n", &thisarg[1]); 171 _exits(0); 172 } 173 } 174 else 175 *ap++ = thisarg; 176 } 177 *ap = 0; 178 exec(symfil, argl); 179 perror(symfil); 180 } 181 182 char procname[100]; 183 184 void 185 startpcs(void) 186 { 187 if ((pid = fork()) == 0) { 188 pid = getpid(); 189 msgpcs("hang"); 190 doexec(); 191 exits(0); 192 } 193 194 if (pid == -1) 195 error("can't fork"); 196 child++; 197 sprint(procname, "/proc/%d/mem", pid); 198 corfil = procname; 199 msgpcs("waitstop"); 200 bpwait(); 201 if (adrflg) 202 rput(cormap, mach->pc, adrval); 203 while (rdc() != EOR) 204 ; 205 reread(); 206 } 207 208 void 209 runstep(ulong loc, int keepnote) 210 { 211 int nfoll; 212 ulong foll[3]; 213 BKPT bkpt[3]; 214 int i; 215 216 if(machdata->foll == 0){ 217 dprint("stepping unimplemented; assuming not a branch\n"); 218 nfoll = 1; 219 foll[0] = loc+mach->pcquant; 220 }else { 221 nfoll = machdata->foll(cormap, loc, rget, foll); 222 if (nfoll < 0) 223 error("%r"); 224 } 225 memset(bkpt, 0, sizeof bkpt); 226 for(i=0; i<nfoll; i++){ 227 if(foll[i] == loc) 228 error("can't single step: next instruction is dot"); 229 bkpt[i].loc = foll[i]; 230 bkput(&bkpt[i], 1); 231 } 232 runrun(keepnote); 233 for(i=0; i<nfoll; i++) 234 bkput(&bkpt[i], 0); 235 } 236 237 void 238 bpwait(void) 239 { 240 setcor(); 241 unloadnote(); 242 } 243 244 void 245 runrun(int keepnote) 246 { 247 int on; 248 249 on = nnote; 250 unloadnote(); 251 if(on != nnote){ 252 notes(); 253 error("not running: new notes pending"); 254 } 255 if(keepnote) 256 loadnote(); 257 else 258 nnote = 0; 259 flush(); 260 msgpcs("startstop"); 261 bpwait(); 262 } 263 264 void 265 bkput(BKPT *bp, int install) 266 { 267 char buf[256]; 268 ulong loc; 269 int ret; 270 271 errstr(buf); 272 if(machdata->bpfix) 273 loc = (*machdata->bpfix)(bp->loc); 274 else 275 loc = bp->loc; 276 if(install){ 277 ret = get1(cormap, loc, bp->save, machdata->bpsize); 278 if (ret > 0) 279 ret = put1(cormap, loc, machdata->bpinst, machdata->bpsize); 280 }else 281 ret = put1(cormap, loc, bp->save, machdata->bpsize); 282 if(ret < 0){ 283 sprint(buf, "can't set breakpoint at %lux: %r", bp->loc); 284 print(buf); 285 read(0, buf, 100); 286 } 287 } 288