|
|
1.1 root 1: static char sccsid[] = "@(#)runpcs.c 4.2 8/17/82";
2: #
3: /*
4: *
5: * UNIX debugger
6: *
7: */
8:
9: #include "head.h"
10: #include <a.out.h>
11: #include <stab.h>
12: struct user u;
13: #include <stdio.h>
14:
15: #ifndef SIGTRAP
16: #define SIGTRAP SIGTRC
17: #endif
18:
19: MSG NOFORK;
20: MSG ENDPCS;
21: MSG BADWAIT;
22:
23: ADDR sigint;
24: ADDR sigqit;
25: ADDR userpc;
26:
27: /* breakpoints */
28: BKPTR bkpthead;
29:
30: CHAR lastc;
31:
32: INT fcor;
33: INT fsym;
34: STRING errflg;
35: int errno;
36: INT signo;
37:
38: L_INT dot;
39: STRING symfil;
40: INT wtflag;
41: INT pid;
42: INT adrflg;
43: L_INT loopcnt;
44:
45:
46:
47:
48:
49:
50: getsig(sig)
51: { return(sig);
52: }
53:
54: runpcs(runmode,execsig)
55: {
56: REG BKPTR bkpt;
57: IF adrflg THEN userpc=dot; FI
58: WHILE --loopcnt>=0
59: DO
60: if (debug) printf("\ncontinue %x %d\n",userpc,execsig);
61: IF runmode==SINGLE
62: THEN delbp(); /* hardware handles single-stepping */
63: ELSE /* continuing from a breakpoint is hard */
64: IF bkpt=scanbkpt(userpc)
65: THEN execbkpt(bkpt,execsig); execsig=0;
66: FI
67: setbp();
68: FI
69: ptrace(runmode,pid,userpc,execsig);
70: bpwait(); chkerr(); execsig=0; delbp(); readregs();
71:
72: loop1: IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
73: THEN /* stopped by BPT instruction */
74: if (debug) printf("\n BPT code; '%s'%o'%o'%d",
75: bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
76: dot=bkpt->loc;
77: IF bkpt->comm[0] != EOR
78: THEN acommand(bkpt->comm);
79: FI
80: IF bkpt->flag==BKPTEXEC
81: ORF ((bkpt->flag=BKPTEXEC)
82: ANDF bkpt->comm[0]!=EOR)
83: THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
84: goto loop1;
85: ELSE bkpt->flag=BKPTSET; bkpt->count=bkpt->initcnt;
86: FI
87: ELSE execsig=signo;
88: if (execsig) break;
89: FI
90: OD
91: if (debug) printf("Returning from runpcs\n");
92: }
93:
94: #define BPOUT 0
95: #define BPIN 1
96: INT bpstate;
97:
98: endpcs()
99: {
100: REG BKPTR bkptr;
101: if (debug) printf("Entering endpcs with pid=%d\n");
102: IF pid
103: THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1;
104: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
105: DO IF bkptr->flag
106: THEN bkptr->flag=BKPTSET;
107: FI
108: OD
109: FI
110: bpstate=BPOUT;
111: }
112:
113: #ifdef VFORK
114: nullsig()
115: {
116:
117: }
118: #endif
119:
120: setup()
121: {
122: close(fsym); fsym = -1;
123: #ifdef VFORK
124: IF (pid = vfork()) == 0
125: #else
126: IF (pid = fork()) == 0
127: #endif
128: THEN ptrace(SETTRC,0,0,0);
129: signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
130: #ifdef VFORK
131: signal(SIGTRAP,nullsig);
132: #endif
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 bpwait(); readregs();
138: if (debug) printf("About to open symfil = %s\n", symfil);
139: fsym=open(symfil,wtflag);
140: IF errflg
141: THEN printf("%s: cannot execute\n",symfil);
142: if (debug) printf("%d %s\n", errflg, errflg);
143: endpcs();
144: FI
145: FI
146: bpstate=BPOUT;
147: }
148:
149: execbkpt(bkptr,execsig)
150: BKPTR bkptr;
151: {
152: if (debug) printf("exbkpt: %d\n",bkptr->count);
153: delbp();
154: ptrace(SINGLE,pid,bkptr->loc,execsig);
155: bkptr->flag=BKPTSET;
156: bpwait(); chkerr(); readregs();
157: }
158:
159: extern STRING environ;
160:
161: doexec()
162: {
163: char *argl[MAXARG], args[LINSIZ];
164: register char c, redchar, *argsp, **arglp, *filnam;
165:
166: arglp = argl;
167: argsp = args;
168: *arglp++ = symfil;
169: c = ' ';
170:
171: do {
172: while (eqany(c, " \t")) {
173: c = rdc();
174: }
175: if (eqany(c, "<>")) {
176: redchar = c;
177: do {
178: c = rdc();
179: } while (eqany(c, " \t"));
180: filnam = argsp;
181: do {
182: *argsp++ = c;
183: c = rdc();
184: } while (!eqany(c, " <>\t\n"));
185: *argsp++ = '\0';
186: if (redchar == '<') {
187: close(0);
188: if (open(filnam,0) < 0) {
189: printf("%s: cannot open\n",filnam);
190: fflush(stdout);
191: _exit(0);
192: }
193: } else {
194: close(1);
195: if (creat(filnam,0666) < 0) {
196: printf("%s: cannot create\n",filnam);
197: fflush(stdout);
198: _exit(0);
199: }
200: }
201: } else if (c != '\n') {
202: *arglp++ = argsp;
203: do {
204: *argsp++ = c;
205: c = rdc();
206: } while(!eqany(c, " <>\t\n"));
207: *argsp++ = '\0';
208: }
209: } while (c != '\n');
210: *arglp = (char *) 0;
211: if (debug) {
212: char **dap;
213: printf("About to exect(%s, %d, %d)\n",symfil,argl,environ);
214: for (dap = argl; *dap; dap++) {
215: printf("%s, ", *dap);
216: }
217: }
218: exect(symfil, argl, environ);
219: perror("Returned from exect");
220: }
221:
222: BKPTR scanbkpt(adr)
223: ADDR adr;
224: {
225: REG BKPTR bkptr;
226: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
227: DO IF bkptr->flag ANDF bkptr->loc==adr
228: THEN break;
229: FI
230: OD
231: return(bkptr);
232: }
233:
234: delbp()
235: {
236: REG ADDR a;
237: REG BKPTR bkptr;
238: IF bpstate!=BPOUT
239: THEN
240: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
241: DO IF bkptr->flag
242: THEN a=bkptr->loc;
243: ptrace(WIUSER,pid,a,
244: (bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF));
245: FI
246: OD
247: bpstate=BPOUT;
248: FI
249: }
250:
251: setbp()
252: {
253: REG ADDR a;
254: REG BKPTR bkptr;
255:
256: IF bpstate!=BPIN
257: THEN
258: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
259: DO IF bkptr->flag
260: THEN a = bkptr->loc;
261: bkptr->ins = ptrace(RIUSER, pid, a, 0);
262: ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF));
263: IF errno
264: THEN error("cannot set breakpoint: ");
265: printf("%s:%d @ %d\n", adrtoprocp(dot)->pname,
266: adrtolineno(dot), dot);
267: FI
268: FI
269: OD
270: bpstate=BPIN;
271: FI
272: }
273:
274: bpwait()
275: {
276: REG ADDR w;
277: ADDR stat;
278:
279: signal(SIGINT, 1);
280: if (debug) printf("Waiting for pid %d\n",pid);
281: WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
282: if (debug) printf("Ending wait\n");
283: if (debug) printf("w = %d; pid = %d; stat = %o;\n", w,pid,stat);
284: signal(SIGINT,sigint);
285: IF w == -1
286: THEN pid=0;
287: errflg=BADWAIT;
288: ELIF (stat & 0177) != 0177
289: THEN IF signo = stat&0177
290: THEN sigprint();
291: FI
292: IF stat&0200
293: THEN error(" - core dumped");
294: close(fcor);
295: setcor();
296: FI
297: pid=0;
298: errflg=ENDPCS;
299: ELSE signo = stat>>8;
300: if (debug) printf("PC = %d, dbsubn = %d\n",
301: ptrace(RUREGS, pid, PC, 0), extaddr("_dbsubn"));
302: IF signo!=SIGTRAP ANDF
303: ptrace(RUREGS, pid, PC, 0) != extaddr("_dbsubn")
304: THEN sigprint();
305: ELSE signo=0;
306: FI
307: FI
308: }
309:
310: REGLIST reglist[];
311: readregs()
312: {
313: /*get REG values from pcs*/
314: REG i;
315: FOR i=24; --i>=0;
316: DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
317: ptrace(RUREGS, pid, reglist[i].roffs, 0);
318: OD
319: userpc= *(ADDR *)(((ADDR)&u)+PC);
320: }
321:
322: char
323: readchar() {
324: lastc = *argsp++;
325: if (lastc == '\0') lastc = '\n';
326: return(lastc);
327: }
328:
329: char
330: rdc()
331: {
332: register char c;
333:
334: c = *argsp++;
335: return(c == '\0' ? '\n' : c);
336: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.