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