BSD 3 development
[unix-history] / usr / src / cmd / adb / runpcs.c
CommitLineData
7df176f7
BJ
1#
2/*
3 *
4 * UNIX debugger
5 *
6 */
7
8#include "defs.h"
9SCCSID(@(#)runpcs.c 2.7);
10struct user u;
11
12
13MSG NOFORK;
14MSG ENDPCS;
15MSG BADWAIT;
16
17CHAR *lp;
18ADDR sigint;
19ADDR sigqit;
20
21/* breakpoints */
22BKPTR bkpthead;
23
24REGLIST reglist[];
25
26CHAR lastc;
27
28INT fcor;
29INT fsym;
30STRING errflg;
31INT errno;
32INT signo;
33
34L_INT dot;
35STRING symfil;
36INT wtflag;
37L_INT pid;
38L_INT expv;
39INT adrflg;
40L_INT loopcnt;
41
42
43
44
45
46/* service routines for sub process control */
47
48getsig(sig)
49{ return(expr(0) ? expv : sig);
50}
51
52ADDR userpc = 1;
53
54runpcs(runmode,execsig)
55{
56 INT rc;
57 REG BKPTR bkpt;
58 IF adrflg THEN userpc=dot; FI
59 printf("%s: running\n", symfil);
60
61 WHILE --loopcnt>=0
62 DO
63#ifdef DEBUG
64 printf("\ncontinue %x %d\n",userpc,execsig);
65#endif
66 IF runmode==SINGLE
67 THEN delbp(); /* hardware handles single-stepping */
68 ELSE /* continuing from a breakpoint is hard */
69 IF bkpt=scanbkpt(userpc)
70 THEN execbkpt(bkpt,execsig); execsig=0;
71 FI
72 setbp();
73 FI
74 ptrace(runmode,pid,userpc,execsig);
75 bpwait(); chkerr(); execsig=0; delbp(); readregs();
76
77 IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
78 THEN /* stopped by BPT instruction */
79#ifdef DEBUG
80 printf("\n BPT code; '%s'%o'%o'%d",
81 bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
82#endif
83 dot=bkpt->loc;
84 IF bkpt->flag==BKPTEXEC
85 ORF ((bkpt->flag=BKPTEXEC)
86 ANDF bkpt->comm[0]!=EOR
87 ANDF command(bkpt->comm,':')
88 ANDF --bkpt->count)
89 THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
90 ELSE bkpt->count=bkpt->initcnt; rc=1;
91 FI
92 ELSE execsig=signo; rc=0;
93 FI
94 OD
95 return(rc);
96}
97
98#define BPOUT 0
99#define BPIN 1
100INT bpstate = BPOUT;
101
102endpcs()
103{
104 REG BKPTR bkptr;
105 IF pid
106 THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1;
107 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
108 DO IF bkptr->flag
109 THEN bkptr->flag=BKPTSET;
110 FI
111 OD
112 FI
113 bpstate=BPOUT;
114}
115
116#ifdef VFORK
117nullsig()
118{
119
120}
121#endif
122
123setup()
124{
125 close(fsym); fsym = -1;
126#ifndef VFORK
127 IF (pid = fork()) == 0
128#else
129 IF (pid = vfork()) == 0
130#endif
131 THEN ptrace(SETTRC,0,0,0);
132#ifdef VFORK
133 signal(SIGTRC,nullsig);
134#endif
135 signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
136 doexec(); exit(0);
137 ELIF pid == -1
138 THEN error(NOFORK);
139 ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0;
140 fsym=open(symfil,wtflag);
141 IF errflg
142 THEN printf("%s: cannot execute\n",symfil);
143 endpcs(); error(0);
144 FI
145 FI
146 bpstate=BPOUT;
147}
148
149execbkpt(bkptr,execsig)
150BKPTR bkptr;
151{
152#ifdef DEBUG
153 printf("exbkpt: %d\n",bkptr->count);
154#endif
155 delbp();
156 ptrace(SINGLE,pid,bkptr->loc,execsig);
157 bkptr->flag=BKPTSET;
158 bpwait(); chkerr(); readregs();
159}
160
161
162doexec()
163{
164 STRING argl[MAXARG];
165 CHAR args[LINSIZ];
166 STRING p, *ap, filnam;
167 extern STRING environ;
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 exect(symfil, argl, environ);
189 perror(symfil);
190}
191
192BKPTR scanbkpt(adr)
193ADDR 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
204delbp()
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 ptrace(WIUSER,pid,a,
214 (bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF));
215 FI
216 OD
217 bpstate=BPOUT;
218 FI
219}
220
221setbp()
222{
223 REG ADDR a;
224 REG BKPTR bkptr;
225
226 IF bpstate!=BPIN
227 THEN
228 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
229 DO IF bkptr->flag
230 THEN a = bkptr->loc;
231 bkptr->ins = ptrace(RIUSER, pid, a, 0);
232 ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF));
233 IF errno
234 THEN prints("cannot set breakpoint: ");
235 psymoff(bkptr->loc,ISYM,"\n");
236 FI
237 FI
238 OD
239 bpstate=BPIN;
240 FI
241}
242
243bpwait()
244{
245 REG ADDR w;
246 ADDR stat;
247
248 signal(SIGINT, 1);
249 WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
250 signal(SIGINT,sigint);
251 IF w == -1
252 THEN pid=0;
253 errflg=BADWAIT;
254 ELIF (stat & 0177) != 0177
255 THEN IF signo = stat&0177
256 THEN sigprint();
257 FI
258 IF stat&0200
259 THEN prints(" - core dumped");
260 close(fcor);
261 setcor();
262 FI
263 pid=0;
264 errflg=ENDPCS;
265 ELSE signo = stat>>8;
266 IF signo!=SIGTRC
267 THEN sigprint();
268 ELSE signo=0;
269 FI
270 flushbuf();
271 FI
272}
273
274readregs()
275{
276 /*get REG values from pcs*/
277 REG i;
278 FOR i=24; --i>=0;
279 DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
280 ptrace(RUREGS, pid, reglist[i].roffs, 0);
281 OD
282 userpc= *(ADDR *)(((ADDR)&u)+PC);
283}
284
285