|
|
1.1 root 1: /*
2: *
3: * UNIX debugger
4: *
5: */
6:
7: #include "defs.h"
8:
9: extern MAP txtmap;
10:
11: MSG NOFORK;
12: MSG ENDPCS;
13: MSG BADWAIT;
14:
15: CHAR *lp;
16: SIG sigint;
17: SIG sigqit;
18:
19: /* breakpoints */
20: BKPTR bkpthead;
21:
22: REGLIST reglist[];
23:
24: CHAR lastc;
25:
26: INT fcor;
27: INT fsym;
28: STRING errflg;
29: INT errno;
30: INT signo;
31: INT sigcode;
32:
33: L_INT dot;
34: STRING symfil;
35: INT wtflag;
36: L_INT pid;
37: L_INT expv;
38: INT adrflg;
39: L_INT loopcnt;
40:
41:
42:
43:
44:
45: /* service routines for sub process control */
46:
47: getsig(sig)
48: { return(expr(0) ? expv : sig);
49: }
50:
51: ADDR userpc = 1;
52:
53: runpcs(runmode,execsig)
54: {
55: REG rc;
56: REG BKPTR bkpt;
57: IF adrflg THEN userpc=dot; FI
58: printf("%s: running\n", symfil);
59:
60: WHILE --loopcnt>=0
61: DO
62: #ifdef DEBUG
63: printf("\ncontinue %X %D loopcnt=%D\n",userpc,execsig, loopcnt);
64: #endif
65: IF runmode==SINGLE
66: THEN delbp(); /* hardware handles single-stepping */
67: ELSE /* continuing from a breakpoint is hard */
68: IF bkpt=scanbkpt(userpc)
69: THEN execbkpt(bkpt,execsig); execsig=0;
70: FI
71: setbp();
72: FI
73: ptrace(runmode,pid,userpc,execsig);
74: bpwait(); chkerr(); execsig=0; delbp(); readregs();
75:
76: IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
77: THEN /* stopped by BPT instruction */
78: #ifdef DEBUG
79: printf("\n BPT code; '%s'%o'%d",
80: bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
81: #endif
82: dot=bkpt->loc;
83: IF bkpt->flag==BKPTEXEC
84: ORF ((bkpt->flag=BKPTEXEC)
85: ANDF bkpt->comm[0]!=EOR
86: ANDF command(bkpt->comm,':')
87: ANDF --bkpt->count)
88: THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
89: ELSE bkpt->count=bkpt->initcnt; rc=1;
90: FI
91: ELSE execsig=signo; rc=0;
92: FI
93: OD
94: return(rc);
95: }
96:
97: #define BPOUT 0
98: #define BPIN 1
99: INT bpstate = BPOUT;
100:
101: endpcs()
102: {
103: REG BKPTR bkptr;
104: IF pid
105: THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1;
106: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
107: DO IF bkptr->flag
108: THEN bkptr->flag=BKPTSET;
109: FI
110: OD
111: FI
112: bpstate=BPOUT;
113: }
114:
115: #ifdef VFORK
116: nullsig()
117: {
118:
119: }
120: #endif
121:
122: setup()
123: {
124: close(fsym); fsym = -1;
125: #ifndef VFORK
126: IF (pid = fork()) == 0
127: #else
128: IF (pid = vfork()) == 0
129: #endif
130: THEN ptrace(SETTRC,0,0,0);
131: #ifdef VFORK
132: signal(SIGTRAP,nullsig);
133: #endif
134: signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
135: doexec(); exit(0);
136: ELIF pid == -1
137: THEN error(NOFORK);
138: ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0;
139: fsym=open(symfil,wtflag);
140: IF errflg
141: THEN printf("%s: cannot execute\n",symfil);
142: endpcs(); error(0);
143: FI
144: FI
145: bpstate=BPOUT;
146: }
147:
148: execbkpt(bkptr,execsig)
149: BKPTR bkptr;
150: {
151: #ifdef DEBUG
152: printf("exbkpt: %d\n",bkptr->count);
153: #endif
154: delbp();
155: ptrace(SINGLE,pid,bkptr->loc,execsig);
156: bkptr->flag=BKPTSET;
157: bpwait(); chkerr(); readregs();
158: }
159:
160:
161: doexec()
162: {
163: STRING argl[MAXARG];
164: CHAR args[LINSIZ];
165: REG STRING p, *ap, filnam;
166: extern STRING environ;
167:
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: execve(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&0xFF000000)|(ptrace(RIUSER,pid,a,0)&0xFFFFFF));
216: ELSE
217: ptrace(WDUSER,pid,a,
218: (bkptr->ins&0xFF000000)|(ptrace(RDUSER,pid,a,0)&0xFFFFFF));
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<<24 | (bkptr->ins&0xFFFFFF));
239: ELSE
240: bkptr->ins = ptrace(RDUSER, pid, a, 0);
241: ptrace(WDUSER, pid, a, BPT<<24 | (bkptr->ins&0xFFFFFF));
242: FI
243: IF errno
244: THEN printf("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 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 sigcode = 0;
266: IF signo = stat&0177
267: THEN sigprint();
268: FI
269: IF stat&0200
270: THEN printf(" - core dumped");
271: close(fcor);
272: setcor();
273: FI
274: pid=0;
275: errflg=ENDPCS;
276: ELSE signo = stat>>8;
277: sigcode = ptrace(RUREGS, pid, &((struct user *)0)->u_code, 0);
278: IF signo!=SIGTRAP
279: THEN sigprint();
280: ELSE signo=0;
281: FI
282: flushbuf();
283: FI
284: }
285:
286: readregs()
287: {
288: /*get REG values from pcs*/
289: REG REGPTR p;
290:
291: FOR p=reglist; p->rname; p++
292: DO uw[p->roffs] =
293: ptrace(RUREGS, pid, p->roffs*NBPW, 0);
294: OD
295: userpc= uw[PC];
296: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.