xref: /original-bsd/old/sdb/runpcs.c (revision 0a83ae40)
1 static	char sccsid[] = "@(#)runpcs.c 4.2 08/17/82";
2 #
3 /*
4  *
5  *	UNIX debugger
6  *
7  */
8 
9 #include "head.h"
10 #include <a.out.h>
11 #include <stab.h>
12 struct user u;
13 #include <stdio.h>
14 
15 #ifndef SIGTRAP
16 #define	SIGTRAP SIGTRC
17 #endif
18 
19 MSG		NOFORK;
20 MSG		ENDPCS;
21 MSG		BADWAIT;
22 
23 ADDR		sigint;
24 ADDR		sigqit;
25 ADDR		userpc;
26 
27 /* breakpoints */
28 BKPTR		bkpthead;
29 
30 CHAR		lastc;
31 
32 INT		fcor;
33 INT		fsym;
34 STRING		errflg;
35 int		errno;
36 INT		signo;
37 
38 L_INT		dot;
39 STRING		symfil;
40 INT		wtflag;
41 INT		pid;
42 INT		adrflg;
43 L_INT		loopcnt;
44 
45 
46 
47 
48 
49 
50 getsig(sig)
51 {	return(sig);
52 }
53 
54 runpcs(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
96 INT bpstate;
97 
98 endpcs()
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
114 nullsig()
115 {
116 
117 }
118 #endif
119 
120 setup()
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 
149 execbkpt(bkptr,execsig)
150 BKPTR	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 
159 extern STRING environ;
160 
161 doexec()
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 
222 BKPTR	scanbkpt(adr)
223 ADDR 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 
234 delbp()
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 
251 setbp()
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 
274 bpwait()
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 
310 REGLIST reglist[];
311 readregs()
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 
322 char
323 readchar() {
324 	lastc = *argsp++;
325 	if (lastc == '\0') lastc = '\n';
326 	return(lastc);
327 }
328 
329 char
330 rdc()
331 {
332 	register char c;
333 
334 	c = *argsp++;
335 	return(c == '\0' ? '\n' : c);
336 }
337