|
|
1.1 root 1: static char sccsid[] = "@(#)runpcs.c 4.1 10/9/80";
2: #
3: /*
4: *
5: * UNIX debugger
6: * process control routines for sdb
7: * this is a hack on top of a hack on top of a hack
8: *
9: */
10:
11: #include "head.h"
12: #include <a.out.h>
13: #include <stab.h>
14: struct user u;
15: #include <stdio.h>
16: #include <sys/pioctl.h>
17: #include <sys/proc.h>
18: #include "base.h"
19:
20: #ifndef SIGTRAP
21: #define SIGTRAP SIGTRC
22: #endif
23:
24: MSG NOFORK;
25: MSG ENDPCS;
26: MSG BADWAIT;
27:
28: ADDR sigint;
29: ADDR sigqit;
30: ADDR userpc;
31:
32: /* breakpoints */
33: BKPTR bkpthead;
34:
35: CHAR lastc;
36:
37: INT fcor;
38: INT fsym;
39: STRING errflg;
40: int errno;
41: INT signo;
42:
43: L_INT dot;
44: STRING symfil;
45: INT wtflag;
46: INT pid;
47: INT adrflg;
48: L_INT loopcnt;
49:
50:
51:
52:
53:
54:
55: getsig(sig)
56: { return(sig);
57: }
58:
59: runpcs(runmode,execsig)
60: {
61: REG BKPTR bkpt;
62: IF adrflg THEN userpc=dot; FI
63: WHILE --loopcnt>=0
64: DO
65: if (debug) printf("\ncontinue %x %d\n",userpc,execsig);
66: IF runmode==SINGLE
67: THEN delbp(); /* hardware handles single-stepping */
68: ELSE /* continuing from a breakpoint is hard */
69: IF bkpt=scanbkpt(userpc)
70: THEN execbkpt(bkpt,execsig); execsig=0;
71: FI
72: setbp();
73: FI
74: setrun(runmode,userpc,execsig);
75: bpwait(); chkerr(); execsig=0; delbp(); readregs();
76:
77: loop1: IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
78: THEN /* stopped by BPT instruction */
79: if (debug) printf("\n BPT code; '%s'%o'%o'%d",
80: bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
81: dot=bkpt->loc;
82: IF bkpt->comm[0] != EOR
83: THEN acommand(bkpt->comm);
84: FI
85: IF bkpt->flag==BKPTEXEC
86: ORF ((bkpt->flag=BKPTEXEC)
87: ANDF bkpt->comm[0]!=EOR)
88: THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
89: goto loop1;
90: ELSE bkpt->flag=BKPTSET; bkpt->count=bkpt->initcnt;
91: FI
92: ELSE execsig=signo;
93: if (execsig) break;
94: FI
95: OD
96: if (debug) printf("Returning from runpcs\n");
97: }
98:
99: #define BPOUT 0
100: #define BPIN 1
101: INT bpstate;
102:
103: endpcs()
104: {
105: REG BKPTR bkptr;
106: if (debug) printf("Entering endpcs with pid=%d\n");
107: IF pid
108: THEN killpcs(); pid=0; userpc=1;
109: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
110: DO IF bkptr->flag
111: THEN bkptr->flag=BKPTSET;
112: FI
113: OD
114: FI
115: bpstate=BPOUT;
116: }
117:
118: setup()
119: {
120: int fd;
121: long tsigs = ~0;
122:
123: fd = openproc(getpid());
124: if (ioctl(fd, PIOCSEXEC, 0) < 0) {
125: close(fd);
126: error("no process ioctl");
127: }
128: close(fsym);
129: fsym = -1;
130: IF (pid = fork()) == 0
131: THEN close(fd);
132: signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
133: if (debug) printf("About to doexec pid=%d\n",pid);
134: doexec(); _exit(0);
135: ELIF pid == -1
136: THEN error(NOFORK);
137: ELSE ioctl(fd, PIOCREXEC, 0);
138: close(fd);
139: datmap.ufd = fcor = openproc(pid);
140: ioctl(fcor, PIOCSMASK, &tsigs);
141: bpwait();
142: readregs();
143: if (debug) printf("About to open symfil = %s\n", symfil);
144: fsym=open(symfil,wtflag);
145: IF errflg
146: THEN printf("%s: cannot execute\n",symfil);
147: if (debug) printf("%d %s\n", errflg, errflg);
148: endpcs();
149: FI
150: FI
151: bpstate=BPOUT;
152: }
153:
154: execbkpt(bkptr,execsig)
155: BKPTR bkptr;
156: {
157: if (debug) printf("exbkpt: %d\n",bkptr->count);
158: delbp();
159: setrun(SINGLE,bkptr->loc,execsig);
160: bkptr->flag=BKPTSET;
161: bpwait(); chkerr(); readregs();
162: }
163:
164: doexec()
165: {
166: char *argl[MAXARG], args[LINSIZ];
167: register char c, redchar, *argsp, **arglp, *filnam;
168:
169: arglp = argl;
170: argsp = args;
171: *arglp++ = symfil;
172: c = ' ';
173:
174: do {
175: while (eqany(c, " \t")) {
176: c = rdc();
177: }
178: if (eqany(c, "<>")) {
179: redchar = c;
180: do {
181: c = rdc();
182: } while (eqany(c, " \t"));
183: filnam = argsp;
184: do {
185: *argsp++ = c;
186: c = rdc();
187: } while (!eqany(c, " <>\t\n"));
188: *argsp++ = '\0';
189: if (redchar == '<') {
190: close(0);
191: if (open(filnam,0) < 0) {
192: printf("%s: cannot open\n",filnam);
193: fflush(stdout);
194: _exit(0);
195: }
196: } else {
197: close(1);
198: if (creat(filnam,0666) < 0) {
199: printf("%s: cannot create\n",filnam);
200: fflush(stdout);
201: _exit(0);
202: }
203: }
204: } else if (c != '\n') {
205: *arglp++ = argsp;
206: do {
207: *argsp++ = c;
208: c = rdc();
209: } while(!eqany(c, " <>\t\n"));
210: *argsp++ = '\0';
211: }
212: } while (c != '\n');
213: *arglp = (char *) 0;
214: if (debug) {
215: char **dap;
216: printf("About to execv(%s, %d)\n",symfil,argl);
217: for (dap = argl; *dap; dap++) {
218: printf("%s, ", *dap);
219: }
220: }
221: execv(symfil, argl);
222: perror("Returned from exect");
223: }
224:
225: BKPTR scanbkpt(adr)
226: ADDR adr;
227: {
228: REG BKPTR bkptr;
229: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
230: DO IF bkptr->flag ANDF bkptr->loc==adr
231: THEN break;
232: FI
233: OD
234: return(bkptr);
235: }
236:
237: delbp()
238: {
239: REG ADDR a;
240: REG BKPTR bkptr;
241: IF bpstate!=BPOUT
242: THEN
243: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
244: DO IF bkptr->flag
245: THEN a=bkptr->loc;
246: prwrite(a, &bkptr->ins, 1);
247: FI
248: OD
249: bpstate=BPOUT;
250: FI
251: }
252:
253: setbp()
254: {
255: REG ADDR a;
256: REG BKPTR bkptr;
257: char bpt = BPT;
258:
259: IF bpstate!=BPIN
260: THEN
261: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
262: DO IF bkptr->flag
263: THEN a = bkptr->loc;
264: prread(a, &bkptr->ins, 1);
265: prwrite(a, &bpt, 1);
266: IF errflg
267: THEN error("cannot set breakpoint: ");
268: printf("%s:%d @ %d\n", adrtoprocp(dot)->pname,
269: adrtolineno(dot), dot);
270: errflg = 0;
271: FI
272: FI
273: OD
274: bpstate=BPIN;
275: FI
276: }
277:
278: #define WSLEEP 10
279:
280: bpwait()
281: {
282: register int w;
283: struct proc p;
284: int pc;
285: int stat;
286: int (*isig)();
287: int nulsig();
288: extern int errno;
289:
290: isig = signal(SIGINT, SIG_IGN);
291: /*
292: * alarm stuff is just in case
293: */
294: for (;;) {
295: signal(SIGALRM, nulsig);
296: alarm(WSLEEP);
297: if (ioctl(fcor, PIOCWSTOP, 0) >= 0)
298: errno = 0;
299: alarm(0);
300: if (errno == 0) {
301: signal(SIGINT, isig);
302: ioctl(fcor, PIOCGETPR, &p);
303: signo = p.p_cursig;
304: prread(UBASE + PC, &pc, sizeof(pc));
305: if (signo == SIGTRAP || signo == SIGSTOP)
306: signo = 0;
307: else if (pc == extaddr("_dbsubn"))
308: signo = 0;
309: else
310: sigprint();
311: return;
312: }
313: if (errno == ENOENT)
314: break;
315: /* still there, still running. try again. */
316: }
317: /*
318: * process has died; wait and report status
319: * should check if it's really our child
320: */
321: signal(SIGALRM, nulsig);
322: alarm(WSLEEP);
323: while ((w = wait(&stat)) != -1 && w != pid)
324: ;
325: alarm(0);
326: pid = 0;
327: signal(SIGINT, isig);
328: close(fcor);
329: pid = 0;
330: corfil = NULL;
331: errflg = ENDPCS;
332: if (w == -1)
333: errflg = BADWAIT;
334: else {
335: if ((stat & 0177) == 0177)
336: printf("trace status? 0%o\n", stat);
337: else {
338: if ((signo = stat & 0177) != 0)
339: sigprint();
340: if (stat & 0200) {
341: printf(" - core dumped");
342: corfil = "core";
343: setcor();
344: }
345: printf("\n");
346: }
347: }
348: }
349:
350: nulsig() {}
351:
352: REGLIST reglist[];
353: readregs()
354: {
355: /*get REG values from pcs*/
356: REG i;
357: FOR i=24; --i>=0;
358: DO prread(UBASE + reglist[i].roffs, (char *)&u + reglist[i].roffs, sizeof(int));
359: OD
360: userpc = *(ADDR *)((char *)&u + PC);
361: }
362:
363: char
364: readchar() {
365: lastc = *argsp++;
366: if (lastc == '\0') lastc = '\n';
367: return(lastc);
368: }
369:
370: char
371: rdc()
372: {
373: register char c;
374:
375: c = *argsp++;
376: return(c == '\0' ? '\n' : c);
377: }
378:
379: /*
380: * miscellaneous /proc hooks
381: */
382:
383: setrun(mode, pc, sig)
384: {
385: int ps;
386:
387: if (pc != 1)
388: prwrite(UBASE + PC, &pc, sizeof(pc));
389: if (mode == SINGLE) {
390: prread(UBASE + PSL, &ps, sizeof(ps));
391: ps |= TBIT;
392: prwrite(UBASE + PSL, &ps, sizeof(ps));
393: }
394: if (sig == 0)
395: ioctl(fcor, PIOCCSIG, 0);
396: ioctl(fcor, PIOCRUN, 0);
397: }
398:
399: killpcs()
400: {
401: long ksig = SIGKILL;
402:
403: ioctl(fcor, PIOCCSIG, 0);
404: ioctl(fcor, PIOCKILL, &ksig);
405: ioctl(fcor, PIOCRUN, 0);
406: /*
407: * assert that it's our child
408: */
409: while (wait((int *)0) >= 0)
410: ;
411: }
412:
413: int
414: openproc(id)
415: int id;
416: {
417: char buf[20];
418: int fd;
419:
420: sprintf(buf, "/proc/%d", id);
421: if ((fd = open(buf, 2)) < 0) {
422: perror("can't open process");
423: longjmp(env, 0);
424: }
425: return (fd);
426: }
427:
428: prread(addr, buf, size)
429: char *buf;
430: {
431:
432: lseek(fcor, (long)addr, 0);
433: if (read(fcor, buf, size) != size)
434: errflg = "can't read process";
435: }
436:
437: prwrite(addr, buf, size)
438: char *buf;
439: {
440:
441: lseek(fcor, (long)addr, 0);
442: if (write(fcor, buf, size) != size)
443: errflg = "can't read process";
444: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.