|
|
1.1 root 1: /*
2: * machine-specific functions for running the debugged process
3: * v7-style (ptrace)
4: */
5:
6: #include "defs.h"
7: #include "regs.h"
8: #include "ptrace.h"
9: #include "bkpt.h"
10: #include "space.h"
11: #include <sys/param.h>
12: #include <signal.h>
13:
14: extern char lastc, peekc;
15: extern ADDR txtsize;
16:
17: static BKPT stepbk, step2bk;
18:
19: /*
20: * kill process
21: */
22:
23: killpcs()
24: {
25:
26: ptrace(P_KILL, pid, 0, 0);
27: }
28:
29: /*
30: * grab the process already opened (but not traced);
31: * stop it so we can look at it
32: */
33:
34: grab()
35: {
36:
37: error("antique system, can't grab");
38: }
39:
40: /*
41: * turn off tracing & let it go
42: */
43:
44: ungrab()
45: {
46:
47: error("antique system, can't ungrab");
48: }
49:
50: /*
51: * get the program to be debugged ready to run
52: * program is left stopped at the beginning (so we can poke in breakpoints)
53: */
54:
55: extern int (*sigint)(), (*sigqit)();
56:
57: startpcs()
58: {
59:
60: if ((pid = fork()) == 0) {
61: close(fsym);
62: close(fcor);
63: signal(SIGINT, sigint);
64: signal(SIGQUIT, sigqit);
65: doexec();
66: exit(0);
67: }
68: if (pid == -1)
69: error("cannot fork");
70: bpwait();
71: if (adrflg)
72: rput(PC, wtoa(adrval));
73: while (rdc() != EOR)
74: ;
75: reread();
76: }
77:
78: /*
79: * set process running, single-stepped
80: */
81:
82: runstep(keepsig)
83: int keepsig;
84: {
85: WORD ins;
86: ADDR pc;
87: BKPT bk;
88:
89: /*
90: * this is the hard part:
91: * the cray can't single step
92: */
93: pc = (ADDR)rtow(rget(PC));
94: ins = stow(sget(pc, CORF|INSTSP));
95: switch (ins & 0177000) {
96: case 05000: /* j bXX */
97: pc = (ADDR)rtow(rget(B00 + (ins&077))) * 2;
98: break;
99:
100: case 010000: /* jaz exp */
101: case 011000: /* jan exp */
102: case 012000: /* jap exp */
103: case 013000: /* jam exp */
104: case 014000: /* jsz exp */
105: case 015000: /* jsn exp */
106: case 016000: /* jsp exp */
107: case 017000: /* jsm exp */
108: /* conditional branch: need 2 breaks */
109: step2bk.loc = pc + 4;
110: bkput(&step2bk, 1);
111: step2bk.flag = BKPTTMP;
112: /* fall through ... */
113: case 06000: /* j exp */
114: case 07000: /* r exp */
115:
116: pc = (ADDR)(((ins & 0777)<<16) | stow(sget(pc+2, CORF|INSTSP))) * 2;
117: break;
118:
119: case 020000:
120: case 021000:
121: case 040000:
122: case 041000:
123: case 0100000:
124: case 0101000:
125: case 0102000:
126: case 0103000:
127: case 0104000:
128: case 0105000:
129: case 0106000:
130: case 0107000:
131: case 0110000:
132: case 0111000:
133: case 0112000:
134: case 0113000:
135: case 0114000:
136: case 0115000:
137: case 0116000:
138: case 0117000:
139: case 0120000:
140: case 0121000:
141: case 0122000:
142: case 0123000:
143: case 0124000:
144: case 0125000:
145: case 0126000:
146: case 0127000:
147: case 0130000:
148: case 0131000:
149: case 0132000:
150: case 0133000:
151: case 0134000:
152: case 0135000:
153: case 0136000:
154: case 0137000:
155: pc += 4; /* two-parcel instruction */
156: break;
157:
158: default:
159: pc += 2;
160: break;
161: }
162: stepbk.loc = pc;
163: bkput(&stepbk, 1);
164: stepbk.flag = BKPTTMP;
165: runrun(keepsig);
166: }
167:
168: /*
169: * set process running
170: */
171:
172: runrun(keepsig)
173: int keepsig;
174: {
175:
176: ptrace(P_CONT, pid, CONTNEXT, keepsig ? signo : 0);
177: }
178:
179: /*
180: * exec the program to be debugged
181: * opening standard input and output as requested
182: */
183:
184: extern char **environ;
185:
186: doexec()
187: {
188: char *argl[MAXARG];
189: char args[LINSIZ];
190: register char *p;
191: register char **ap;
192: register char *thisarg;
193:
194: ap = argl;
195: p = args;
196: *ap++ = symfil;
197: for (rdc(); lastc != EOR;) {
198: thisarg = p;
199: if (lastc == '<' || lastc == '>') {
200: *p++ = lastc;
201: rdc();
202: }
203: while (lastc != EOR && lastc != SPC && lastc != TB) {
204: *p++ = lastc;
205: readchar();
206: }
207: if (lastc == SPC || lastc == TB)
208: rdc();
209: *p++ = 0;
210: if (*thisarg == '<') {
211: close(0);
212: if (open(&thisarg[1], 0) < 0) {
213: printf("%s: cannot open\n", &thisarg[1]);
214: _exit(0);
215: }
216: }
217: else if (*thisarg == '>') {
218: close(1);
219: if (creat(&thisarg[1], 0666) < 0) {
220: printf("%s: cannot create\n", &thisarg[1]);
221: _exit(0);
222: }
223: }
224: else
225: *ap++ = thisarg;
226: }
227: *ap = NULL;
228: ptrace(P_INIT, 0, (int *)0, 0);
229: execve(symfil, argl, environ);
230: perror(symfil);
231: }
232:
233: /*
234: * wait for the process to stop;
235: * pick up status and registers when it does
236: */
237:
238: #define WSLEEP 10
239:
240: extern int errno;
241:
242: bpwait()
243: {
244: register int w;
245: int stat;
246: int (*isig)();
247: int nulsig();
248:
249: isig = signal(SIGINT, SIG_IGN);
250: while ((w = wait(&stat)) != -1 && w != pid)
251: ;
252: signal(SIGINT, isig);
253: if (w == -1)
254: errflg = "wait failed";
255: else if ((stat & 0177) == 0177) { /* trace status */
256: signo = (stat >> 8) & 0177;
257: mapimage();
258: /*
259: * awful hack to get breakpoints right
260: */
261: if (signo == SIGEMT)
262: rput(PC, wtor(rtow(rget(PC))-2));
263: if (signo == SIGTRAP || signo == SIGEMT)
264: signo = 0;
265: else {
266: sigprint();
267: newline();
268: }
269: if (stepbk.flag) {
270: stepbk.flag = 0;
271: bkput(&stepbk, 0);
272: }
273: if (step2bk.flag) {
274: step2bk.flag = 0;
275: bkput(&step2bk, 0);
276: }
277: return;
278: }
279: else {
280: errflg = "process terminated";
281: sigcode = 0;
282: if ((signo = stat & 0177) != 0)
283: sigprint();
284: if (stat & 0200) {
285: prints(" - core dumped");
286: corfil = "core";
287: }
288: pid = 0;
289: setcor();
290: }
291: }
292:
293: /*
294: * is the right-hand file a process image?
295: */
296:
297: trcimage()
298: {
299:
300: return (pid != 0);
301: }
302:
303: /*
304: * grab some data from the user block,
305: * before maps are set up (ugh)
306: */
307:
308: int
309: trcunab(off)
310: int off;
311: {
312: int data;
313:
314: errno = 0;
315: data = ptrace(P_RDU, pid, off, 0);
316: if (errno) {
317: errflg = "can't read user block";
318: return (0);
319: }
320: return (data);
321: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.