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