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