read opcodes from specified space, not always from i-space
[unix-history] / usr / src / old / adb / adb.tahoe / runpcs.c
CommitLineData
286e78ae
SL
1#ifndef lint
2static char sccsid[] = "@(#)runpcs.c 1.1 (Berkeley) %G%";
3#endif
4/*
5 *
6 * UNIX debugger
7 *
8 */
9
10#include "defs.h"
11
12extern MAP txtmap;
13
14MSG NOFORK;
15MSG ENDPCS;
16MSG BADWAIT;
17
18CHAR *lp;
19SIG sigint;
20SIG sigqit;
21
22/* breakpoints */
23BKPTR bkpthead;
24
25REGLIST reglist[];
26
27CHAR lastc;
28
29INT fcor;
30INT fsym;
31STRING errflg;
32INT errno;
33INT signo;
34INT sigcode;
35
36L_INT dot;
37STRING symfil;
38INT wtflag;
39L_INT pid;
40L_INT expv;
41INT adrflg;
42L_INT loopcnt;
43
44
45
46
47
48/* service routines for sub process control */
49
50getsig(sig)
51{ return(expr(0) ? expv : sig);
52}
53
54ADDR userpc = 1;
55
56runpcs(runmode,execsig)
57{
58 REG rc;
59 REG BKPTR bkpt;
60 IF adrflg THEN userpc=dot; FI
61 printf("%s: running\n", symfil);
62
63 WHILE --loopcnt>=0
64 DO
65#ifdef DEBUG
66 printf("\ncontinue %X %D loopcnt=%D\n",userpc,execsig, loopcnt);
67#endif
68 IF runmode==SINGLE
69 THEN delbp(); /* hardware handles single-stepping */
70 ELSE /* continuing from a breakpoint is hard */
71 IF bkpt=scanbkpt(userpc)
72 THEN execbkpt(bkpt,execsig); execsig=0;
73 FI
74 setbp();
75 FI
76 ptrace(runmode,pid,userpc,execsig);
77 bpwait(); chkerr(); execsig=0; delbp(); readregs();
78
79 IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
80 THEN /* stopped by BPT instruction */
81#ifdef DEBUG
82 printf("\n BPT code; '%s'%o'%d",
83 bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
84#endif
85 dot=bkpt->loc;
86 IF bkpt->flag==BKPTEXEC
87 ORF ((bkpt->flag=BKPTEXEC)
88 ANDF bkpt->comm[0]!=EOR
89 ANDF command(bkpt->comm,':')
90 ANDF --bkpt->count)
91 THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
92 ELSE bkpt->count=bkpt->initcnt; rc=1;
93 FI
94 ELSE execsig=signo; rc=0;
95 FI
96 OD
97 return(rc);
98}
99
100#define BPOUT 0
101#define BPIN 1
102INT bpstate = BPOUT;
103
104endpcs()
105{
106 REG BKPTR bkptr;
107 IF pid
108 THEN ptrace(EXIT,pid); pid=0; userpc=1;
109 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
110 DO IF bkptr->flag
111 THEN bkptr->flag=BKPTSET;
112 FI
113 OD
114 FI
115 bpstate=BPOUT;
116}
117
118#ifdef VFORK
119nullsig()
120{
121
122}
123#endif
124
125setup()
126{
127 close(fsym); fsym = -1;
128#ifndef VFORK
129 IF (pid = fork()) == 0
130#else
131 IF (pid = vfork()) == 0
132#endif
133 THEN ptrace(SETTRC);
134#ifdef VFORK
135 signal(SIGTRAP,nullsig);
136#endif
137 signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
138 doexec(); exit(0);
139 ELIF pid == -1
140 THEN error(NOFORK);
141 ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0;
142 fsym=open(symfil,wtflag);
143 IF errflg
144 THEN printf("%s: cannot execute\n",symfil);
145 endpcs(); error(0);
146 FI
147 FI
148 bpstate=BPOUT;
149}
150
151execbkpt(bkptr,execsig)
152BKPTR bkptr;
153{
154#ifdef DEBUG
155 printf("exbkpt: %d\n",bkptr->count);
156#endif
157 delbp();
158 ptrace(SINGLE,pid,bkptr->loc,execsig);
159 bkptr->flag=BKPTSET;
160 bpwait(); chkerr(); readregs();
161}
162
163
164doexec()
165{
166 STRING argl[MAXARG];
167 CHAR args[LINSIZ];
168 REG STRING p, *ap, filnam;
169 extern STRING environ;
170
171 ap=argl; p=args;
172 *ap++=symfil;
173 REP IF rdc()==EOR THEN break; FI
174 *ap = p;
175 WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB DO *p++=lastc; readchar(); OD
176 *p++=0; filnam = *ap+1;
177 IF **ap=='<'
178 THEN close(0);
179 IF open(filnam,0)<0
180 THEN printf("%s: cannot open\n",filnam); _exit(0);
181 FI
182 ELIF **ap=='>'
183 THEN close(1);
184 IF creat(filnam,0666)<0
185 THEN printf("%s: cannot create\n",filnam); _exit(0);
186 FI
187 ELSE ap++;
188 FI
189 PER lastc!=EOR DONE
190 *ap++=0;
191 execve(symfil, argl, environ);
192 perror(symfil);
193}
194
195BKPTR scanbkpt(adr)
196ADDR adr;
197{
198 REG BKPTR bkptr;
199 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
200 DO IF bkptr->flag ANDF bkptr->loc==adr
201 THEN break;
202 FI
203 OD
204 return(bkptr);
205}
206
207delbp()
208{
209 REG ADDR a;
210 REG BKPTR bkptr;
211 IF bpstate!=BPOUT
212 THEN
213 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
214 DO IF bkptr->flag
215 THEN a=bkptr->loc;
216 IF a < txtmap.e1 THEN
217 ptrace(WIUSER,pid,a,bkptr->ins);
218 ELSE
219 ptrace(WDUSER,pid,a,bkptr->ins);
220 FI
221 FI
222 OD
223 bpstate=BPOUT;
224 FI
225}
226
227#if defined(vax)
228#define SETBP(ins) (BPT | ((ins) &~ 0xff))
229#else
230#define SETBP(ins) ((BPT<<24) | ((ins) & 0xffffff))
231#endif
232
233setbp()
234{
235 REG ADDR a;
236 REG BKPTR bkptr;
237
238 IF bpstate!=BPIN
239 THEN
240 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
241 DO IF bkptr->flag
242 THEN a = bkptr->loc;
243 IF a < txtmap.e1 THEN
244 bkptr->ins = ptrace(RIUSER, pid, a);
245 ptrace(WIUSER, pid, a, SETBP(bkptr->ins));
246 ELSE
247 bkptr->ins = ptrace(RDUSER, pid, a);
248 ptrace(WDUSER, pid, a, SETBP(bkptr->ins));
249 FI
250 IF errno
251 THEN printf("cannot set breakpoint: ");
252 psymoff(bkptr->loc,ISYM,"\n");
253 FI
254 FI
255 OD
256 bpstate=BPIN;
257 FI
258}
259
260bpwait()
261{
262 REG w;
263 ADDR stat;
264
265 signal(SIGINT, 1);
266 WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
267 signal(SIGINT,sigint);
268 IF w == -1
269 THEN pid=0;
270 errflg=BADWAIT;
271 ELIF (stat & 0177) != 0177
272 THEN sigcode = 0;
273 IF signo = stat&0177
274 THEN sigprint();
275 FI
276 IF stat&0200
277 THEN printf(" - core dumped");
278 close(fcor);
279 setcor();
280 FI
281 pid=0;
282 errflg=ENDPCS;
283 ELSE signo = stat>>8;
284 sigcode = ptrace(RUREGS, pid, &((struct user *)0)->u_code, 0);
285 IF signo!=SIGTRAP
286 THEN sigprint();
287 ELSE signo=0;
288 FI
289 flushbuf();
290 FI
291}
292
293readregs()
294{
295 /*get REG values from pcs*/
296 REG REGPTR p;
297
298 FOR p=reglist; p->rname; p++
299 DO *(ADDR *)(((ADDR)&u)+p->roffs) =
300 ptrace(RUREGS, pid, p->roffs, 0);
301 OD
302 userpc= *(ADDR *)(((ADDR)&u)+PC);
303}