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