|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)runpcs.c 4.6 4/25/85";
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(PT_KILL,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(PT_TRACE_ME,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(PT_STEP,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(PT_WRITE_I,pid,a,bkptr->ins);
236: ELSE
237: ptrace(PT_WRITE_D,pid,a,bkptr->ins);
238: FI
239: FI
240: OD
241: bpstate=BPOUT;
242: FI
243: }
244:
245: #ifdef vax
246: #define SETBP(ins) (BPT | ((ins) &~ 0xFF))
247: #endif
248:
249: setbp()
250: {
251: REG ADDR a;
252: REG BKPTR bkptr;
253:
254: IF bpstate!=BPIN
255: THEN
256: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
257: DO IF bkptr->flag
258: THEN a = bkptr->loc;
259: IF a < txtmap.e1 THEN
260: bkptr->ins = ptrace(PT_READ_I, pid, a, 0);
261: ptrace(PT_WRITE_I, pid, a, SETBP(bkptr->ins));
262: ELSE
263: bkptr->ins = ptrace(PT_READ_D, pid, a, 0);
264: ptrace(PT_WRITE_D, pid, a, SETBP(bkptr->ins));
265: FI
266: IF errno
267: THEN prints("cannot set breakpoint: ");
268: psymoff(bkptr->loc,ISYM,"\n");
269: FI
270: FI
271: OD
272: bpstate=BPIN;
273: FI
274: }
275:
276: bpwait()
277: {
278: REG ADDR w;
279: ADDR stat;
280:
281: signal(SIGINT, 1);
282: WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
283: signal(SIGINT,sigint);
284: IF w == -1
285: THEN pid=0;
286: errflg=BADWAIT;
287: ELIF (stat & 0177) != 0177
288: THEN sigcode = 0;
289: IF signo = stat&0177
290: THEN sigprint();
291: FI
292: IF stat&0200
293: THEN prints(" - core dumped");
294: close(fcor);
295: setcor();
296: FI
297: pid=0;
298: errflg=ENDPCS;
299: ELSE signo = stat>>8;
300: sigcode = ptrace(PT_READ_U, pid, &((struct user *)0)->u_code, 0);
301: IF signo!=SIGTRAP
302: THEN sigprint();
303: ELSE signo=0;
304: FI
305: flushbuf();
306: FI
307: }
308:
309: readregs()
310: {
311: /*get REG values from pcs*/
312: REG i;
313: FOR i=24; --i>=0;
314: DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
315: ptrace(PT_READ_U, pid, reglist[i].roffs, 0);
316: OD
317: userpc= *(ADDR *)(((ADDR)&u)+PC);
318: }
319:
320:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.