Bell 32V release
[unix-history] / usr / src / cmd / sdb / runpcs.c
CommitLineData
21a7399d
TL
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/*
84 printf("%s: running\n", symfil);
85*/
86 WHILE --loopcnt>=0
87 DO
88 if (debug) printf("\ncontinue %x %d\n",userpc,execsig);
89 IF runmode==SINGLE
90 THEN delbp(); /* hardware handles single-stepping */
91 ELSE /* continuing from a breakpoint is hard */
92 IF bkpt=scanbkpt(userpc)
93 THEN execbkpt(bkpt,execsig); execsig=0;
94 FI
95 setbp();
96 FI
97 ptrace(runmode,pid,userpc,execsig);
98 bpwait(); chkerr(); execsig=0; delbp(); readregs();
99
100 IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
101 THEN /* stopped by BPT instruction */
102 if (debug) printf("\n BPT code; '%s'%o'%o'%d",
103 bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
104 dot=bkpt->loc;
105 IF bkpt->flag==BKPTEXEC
106 ORF ((bkpt->flag=BKPTEXEC)
107 ANDF bkpt->comm[0]!=EOR
108 ANDF --bkpt->count)
109 THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
110 ELSE bkpt->count=bkpt->initcnt;
111 FI
112 ELSE execsig=signo;
113 FI
114 OD
115 if (debug) printf("Returning from runpcs\n");
116}
117
118#define BPOUT 0
119#define BPIN 1
120INT bpstate = BPOUT;
121
122endpcs()
123{
124 REG BKPTR bkptr;
125 if (debug) printf("Entering endpcs with pid=%d\n");
126 IF pid
127 THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1;
128 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
129 DO IF bkptr->flag
130 THEN bkptr->flag=BKPTSET;
131 FI
132 OD
133 FI
134 bpstate=BPOUT;
135}
136
137setup()
138{
139 close(fsym); fsym = -1;
140 IF (pid = fork()) == 0
141 THEN ptrace(SETTRC,0,0,0);
142 signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
143 if (debug) printf("About to doexec pid=%d\n",pid);
144 doexec(); exit(0);
145 ELIF pid == -1
146 THEN error(NOFORK);
147 ELSE bpwait(); readregs(); /******** lp[0]=EOR; lp[1]=0; */
148 if (debug) printf("About to open symfil = %s\n", symfil);
149 fsym=open(symfil,wtflag);
150 IF errflg
151 THEN printf("%s: cannot execute\n",symfil);
152 if (debug) printf("%d %s\n", errflg, errflg);
153 endpcs();
154 FI
155 FI
156 bpstate=BPOUT;
157}
158
159execbkpt(bkptr,execsig)
160BKPTR bkptr;
161{
162 if (debug) printf("exbkpt: %d\n",bkptr->count);
163 delbp();
164 ptrace(SINGLE,pid,bkptr->loc,execsig);
165 bkptr->flag=BKPTSET;
166 bpwait(); chkerr(); readregs();
167}
168
169extern STRING environ;
170
171doexec()
172{
173 STRING argl[MAXARG];
174 CHAR args[LINSIZ];
175 STRING p, *ap, filnam;
176 ap=argl; p=args;
177 *ap++=symfil;
178 REP IF rdc()==EOR THEN break; FI
179 *ap = p;
180 WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB DO *p++=lastc; readchar(); OD
181 *p++=0; filnam = *ap+1;
182 IF **ap=='<'
183 THEN close(0);
184 IF open(filnam,0)<0
185 THEN printf("%s: cannot open\n",filnam); exit(0);
186 FI
187 ELIF **ap=='>'
188 THEN close(1);
189 IF creat(filnam,0666)<0
190 THEN printf("%s: cannot create\n",filnam); exit(0);
191 FI
192 ELSE ap++;
193 FI
194 PER lastc!=EOR DONE
195 *ap++=0;
196 if (debug) printf("About to exect(%s, %d, %d)\n",symfil,argl,environ);
197 exect(symfil, argl, environ);
198 perror("Returned from exect");
199}
200
201BKPTR scanbkpt(adr)
202ADDR adr;
203{
204 REG BKPTR bkptr;
205 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
206 DO IF bkptr->flag ANDF bkptr->loc==adr
207 THEN break;
208 FI
209 OD
210 return(bkptr);
211}
212
213delbp()
214{
215 REG ADDR a;
216 REG BKPTR bkptr;
217 IF bpstate!=BPOUT
218 THEN
219 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
220 DO IF bkptr->flag
221 THEN a=bkptr->loc;
222 ptrace(WIUSER,pid,a,
223 (bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF));
224 FI
225 OD
226 bpstate=BPOUT;
227 FI
228}
229
230setbp()
231{
232 REG ADDR a;
233 REG BKPTR bkptr;
234
235 IF bpstate!=BPIN
236 THEN
237 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
238 DO IF bkptr->flag
239 THEN a = bkptr->loc;
240 bkptr->ins = ptrace(RIUSER, pid, a, 0);
241 ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF));
242 IF errno
243 THEN error("cannot set breakpoint: ");
244 printf("%s:%d @ %d\n", adrtoprocp(dot)->pname,
245 adrtolineno(dot), dot);
246/********
247 psymoff(bkptr->loc,ISYM,"\n");
248*/
249 FI
250 FI
251 OD
252 bpstate=BPIN;
253 FI
254}
255
256bpwait()
257{
258 REG ADDR w;
259 ADDR stat;
260
261 signal(SIGINT, 1);
262 if (debug) printf("Waiting for pid %d\n",pid);
263 WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
264 if (debug) printf("Ending wait\n");
265 if (debug) printf("w = %d; pid = %d; stat = %o;\n", w,pid,stat);
266 signal(SIGINT,sigint);
267 IF w == -1
268 THEN pid=0;
269 errflg=BADWAIT;
270 ELIF (stat & 0177) != 0177
271 THEN IF signo = stat&0177
272 THEN sigprint();
273 FI
274 IF stat&0200
275 THEN error(" - core dumped");
276 close(fcor);
277 setcor();
278 FI
279 pid=0;
280 errflg=ENDPCS;
281 ELSE signo = stat>>8;
282 if (debug) printf("PC = %d, dbsubn = %d\n",
283 ptrace(RUREGS, pid, PC, 0), extaddr("_dbsubn"));
284 IF signo!=SIGTRC ANDF
285 ptrace(RUREGS, pid, PC, 0) != extaddr("_dbsubn")
286 THEN sigprint();
287 ELSE signo=0;
288 FI
289 FI
290}
291
292readregs()
293{
294 /*get REG values from pcs*/
295 REG i;
296 FOR i=24; --i>=0;
297 DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
298 ptrace(RUREGS, pid, reglist[i].roffs, 0);
299 OD
300 userpc= *(ADDR *)(((ADDR)&u)+PC);
301}
302
303rdc()
304{ REP readchar();
305 PER lastc==SP ORF lastc==TB
306 DONE
307 return(lastc);
308}
309
310readchar() {
311 lastc = *argsp++;
312 if (lastc == '\0') lastc = '\n';
313}