BSD 3 development
[unix-history] / usr / src / cmd / sdb / runpcs.c
CommitLineData
534114c4
HK
1#
2/*
3 *
4 * UNIX debugger
5 *
6 */
7
8#include "head.h"
9#include <a.out.h>
10struct user u;
11#include <stdio.h>
12
13
14MSG NOFORK;
15MSG ENDPCS;
16MSG BADWAIT;
17
18ADDR sigint;
19ADDR sigqit;
20
21/* breakpoints */
22BKPTR bkpthead;
23
24
25REGLIST 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
53CHAR lastc;
54
55INT fcor;
56INT fsym;
57STRING errflg;
58int errno;
59INT signo;
60
61L_INT dot;
62STRING symfil;
63INT wtflag;
64INT pid;
65INT adrflg;
66L_INT loopcnt;
67
68
69
70
71
72
73getsig(sig)
74{ return(sig);
75}
76
77ADDR userpc = 1;
78
79runpcs(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
121INT bpstate = BPOUT;
122
123endpcs()
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
139nullsig()
140{
141
142}
143#endif
144
145setup()
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
178execbkpt(bkptr,execsig)
179BKPTR 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
188extern STRING environ;
189
190doexec()
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
257BKPTR scanbkpt(adr)
258ADDR 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
269delbp()
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
286setbp()
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
309bpwait()
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
345readregs()
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
356char
357readchar() {
358 lastc = *argsp++;
359 if (lastc == '\0') lastc = '\n';
360 return(lastc);
361}
362
363char
364rdc()
365{
366 register char c;
367
368 c = *argsp++;
369 return(c == '\0' ? '\n' : c);
370}