|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)runpcs.c 4.4 10/27/83";
3: #endif
4: /*
5: *
6: * UNIX debugger
7: *
8: */
9:
10: #include "defs.h"
11:
12: extern MAP txtmap;
13:
14: MSG NOFORK;
15: MSG ENDPCS;
16: MSG BADWAIT;
17:
18: CHAR *lp;
19: ADDR sigint;
20: ADDR sigqit;
21:
22: /* breakpoints */
23: BKPTR bkpthead;
24:
25: REGLIST reglist[];
26:
27: CHAR lastc;
28:
29: INT fcor;
30: INT fsym;
31: STRING errflg;
32: INT errno;
33: INT signo;
34: INT sigcode;
35:
36: L_INT dot;
37: STRING symfil;
38: INT wtflag;
39: L_INT pid;
40: L_INT expv;
41: INT adrflg;
42: L_INT loopcnt;
43:
44:
45:
46:
47:
48: /* service routines for sub process control */
49:
50: getsig(sig)
51: { return(expr(0) ? expv : sig);
52: }
53:
54: ADDR userpc = 1;
55:
56: runpcs(runmode,execsig)
57: {
58: INT rc;
59: REG BKPTR bkpt;
60: IF adrflg THEN userpc=dot; FI
61: printf("%s: running\n", symfil);
62:
63: WHILE --loopcnt>=0
64: DO
65: #ifdef DEBUG
66: printf("\ncontinue %x %d\n",userpc,execsig);
67: #endif
68: IF runmode==SINGLE
69: THEN delbp(); /* hardware handles single-stepping */
70: ELSE /* continuing from a breakpoint is hard */
71: IF bkpt=scanbkpt(userpc)
72: THEN execbkpt(bkpt,execsig); execsig=0;
73: FI
74: setbp();
75: FI
76: ptrace(runmode,pid,userpc,execsig);
77: bpwait(); chkerr(); execsig=0; delbp(); readregs();
78:
79: IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
80: THEN /* stopped by BPT instruction */
81: #ifdef DEBUG
82: printf("\n BPT code; '%s'%o'%o'%d",
83: bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
84: #endif
85: dot=bkpt->loc;
86: IF bkpt->flag==BKPTEXEC
87: ORF ((bkpt->flag=BKPTEXEC)
88: ANDF bkpt->comm[0]!=EOR
89: ANDF command(bkpt->comm,':')
90: ANDF --bkpt->count)
91: THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
92: ELSE bkpt->count=bkpt->initcnt; rc=1;
93: FI
94: ELSE execsig=signo; rc=0;
95: FI
96: OD
97: return(rc);
98: }
99:
100: #define BPOUT 0
101: #define BPIN 1
102: INT bpstate = BPOUT;
103:
104: endpcs()
105: {
106: REG BKPTR bkptr;
107: IF pid
108: THEN ptrace(EXIT,pid,0,0); 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: #ifdef VFORK
119: nullsig()
120: {
121:
122: }
123: #endif
124:
125: setup()
126: {
127: close(fsym); fsym = -1;
128: #ifndef VFORK
129: IF (pid = fork()) == 0
130: #else
131: IF (pid = vfork()) == 0
132: #endif
133: THEN ptrace(SETTRC,0,0,0);
134: #ifdef VFORK
135: signal(SIGTRAP,nullsig);
136: #endif
137: signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
138: doexec(); exit(0);
139: ELIF pid == -1
140: THEN error(NOFORK);
141: ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0;
142: fsym=open(symfil,wtflag);
143: IF errflg
144: THEN printf("%s: cannot execute\n",symfil);
145: endpcs(); error(0);
146: FI
147: FI
148: bpstate=BPOUT;
149: }
150:
151: execbkpt(bkptr,execsig)
152: BKPTR bkptr;
153: {
154: #ifdef DEBUG
155: printf("exbkpt: %d\n",bkptr->count);
156: #endif
157: delbp();
158: ptrace(SINGLE,pid,bkptr->loc,execsig);
159: bkptr->flag=BKPTSET;
160: bpwait(); chkerr(); readregs();
161: }
162:
163:
164: doexec()
165: {
166: STRING argl[MAXARG];
167: CHAR args[LINSIZ];
168: STRING p, *ap, filnam;
169: extern STRING environ;
170: ap=argl; p=args;
171: *ap++=symfil;
172: REP IF rdc()==EOR THEN break; FI
173: *ap = p;
174: /*
175: * First thing is to look for direction characters
176: * and get filename. Do not use up the args for filenames.
177: * Then get rid of spaces before next args.
178: */
179: IF lastc=='<'
180: THEN REP readchar(); PER lastc==SP ORF lastc==TB DONE
181: filnam = p;
182: WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='>'
183: DO *p++=lastc; readchar(); OD
184: *p = 0;
185: close(0);
186: IF open(filnam,0)<0
187: THEN printf("%s: cannot open\n",filnam); _exit(0);
188: FI
189: p = *ap;
190: ELIF lastc=='>'
191: THEN REP readchar(); PER lastc==SP ORF lastc==TB DONE
192: filnam = p;
193: WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='<'
194: DO *p++=lastc; readchar(); OD
195: *p = '\0';
196: close(1);
197: IF creat(filnam,0666)<0
198: THEN printf("%s: cannot create\n",filnam); _exit(0);
199: FI
200: p = *ap;
201: ELSE
202: WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='>' ANDF lastc!='<'
203: DO *p++=lastc; readchar(); OD
204: *p++ = '\0';
205: ap++;
206: FI
207: PER lastc!=EOR DONE
208: *ap++=0;
209: exect(symfil, argl, environ);
210: perror(symfil);
211: }
212:
213: BKPTR scanbkpt(adr)
214: ADDR adr;
215: {
216: REG BKPTR bkptr;
217: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
218: DO IF bkptr->flag ANDF bkptr->loc==adr
219: THEN break;
220: FI
221: OD
222: return(bkptr);
223: }
224:
225: delbp()
226: {
227: REG ADDR a;
228: REG BKPTR bkptr;
229: IF bpstate!=BPOUT
230: THEN
231: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
232: DO IF bkptr->flag
233: THEN a=bkptr->loc;
234: IF a < txtmap.e1 THEN
235: ptrace(WIUSER,pid,a,
236: (bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF));
237: ELSE
238: ptrace(WDUSER,pid,a,
239: (bkptr->ins&0xFF)|(ptrace(RDUSER,pid,a,0)&~0xFF));
240: FI
241: FI
242: OD
243: bpstate=BPOUT;
244: FI
245: }
246:
247: setbp()
248: {
249: REG ADDR a;
250: REG BKPTR bkptr;
251:
252: IF bpstate!=BPIN
253: THEN
254: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
255: DO IF bkptr->flag
256: THEN a = bkptr->loc;
257: IF a < txtmap.e1 THEN
258: bkptr->ins = ptrace(RIUSER, pid, a, 0);
259: ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF));
260: ELSE
261: bkptr->ins = ptrace(RDUSER, pid, a, 0);
262: ptrace(WDUSER, pid, a, BPT | (bkptr->ins&~0xFF));
263: FI
264: IF errno
265: THEN prints("cannot set breakpoint: ");
266: psymoff(bkptr->loc,ISYM,"\n");
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: WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
281: signal(SIGINT,sigint);
282: IF w == -1
283: THEN pid=0;
284: errflg=BADWAIT;
285: ELIF (stat & 0177) != 0177
286: THEN sigcode = 0;
287: IF signo = stat&0177
288: THEN sigprint();
289: FI
290: IF stat&0200
291: THEN prints(" - core dumped");
292: close(fcor);
293: setcor();
294: FI
295: pid=0;
296: errflg=ENDPCS;
297: ELSE signo = stat>>8;
298: sigcode = ptrace(RUREGS, pid, &((struct user *)0)->u_code, 0);
299: IF signo!=SIGTRAP
300: THEN sigprint();
301: ELSE signo=0;
302: FI
303: flushbuf();
304: FI
305: }
306:
307: readregs()
308: {
309: /*get REG values from pcs*/
310: REG i;
311: FOR i=24; --i>=0;
312: DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
313: ptrace(RUREGS, pid, reglist[i].roffs, 0);
314: OD
315: userpc= *(ADDR *)(((ADDR)&u)+PC);
316: }
317:
318:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.