xref: /original-bsd/old/sdb/docomm.c (revision 264c46cb)
1 static	char sccsid[] = "@(#)docomm.c 4.2 08/17/82";
2 #include <signal.h>
3 #include "head.h"
4 #include <a.out.h>
5 #include <stab.h>
6 
7 struct user u;
8 L_INT 	cntval;
9 INT	signo;
10 INT	adrflg;
11 INT	pid;
12 ADDR	userpc;
13 char	*s;
14 enum	{NOCOM, PRCOM, DSCOM, DSICOM} lastcom;
15 		/* last command: nothing noteworthy, print source,
16 			display variable, display instruction */
17 
18 docommand() {
19 	register char	*p;
20 	register int	i;
21 	register ADDR	addr, bkaddr;
22 	struct proct 	*procp;
23 	char s[4];
24 
25 	cntval = 1;
26 	adrflg = 0;
27 	errflg = 0;
28 
29 	if (scallf) {
30 		doscall();
31 		setcur(1);
32 		lastcom = NOCOM;
33 		return;
34 	}
35 
36 	if (reflag) {  /* search for regular expression */
37 		dore();
38 		lastcom = PRCOM;
39 		return;
40 	}
41 
42 	if (cmd == '\0') {
43 		if (integ != 0 && var[0] != '\0') {
44 			error("Invalid command (1)");
45 			return;
46 		}
47 		if (integ != 0) { /* print line number */
48 			ffind(integ);
49 			fprint();
50 			lastcom = PRCOM;
51 			return;
52 		}
53 		if (var[0] != 0) {
54 			printf("Unexpected null command\n");
55 			return;
56 		}
57 	}
58 
59 	switch (cmd) {
60 
61 	case 'Y':
62 		debug = !debug;
63 		break;
64 
65 	case 'V':
66 		version();
67 		break;
68 
69 	case 'M':
70 		if (args[0]) {
71 			setmap(args);
72 		} else {
73 			printmap("? map", &txtmap);
74 			printmap("/ map", &datmap);
75 		}
76 		break;
77 
78 	case 'x':
79 		printregs();
80 		break;
81 
82 	case 'X':
83 		printpc();
84 		break;
85 
86 	case 'a':
87 		if (integ) {
88 			cpstr(args, "l\n");
89 		} else if (proc[0]) {
90 			cpall(args, "T\n");
91 		} else {
92 			error("Bad arguments");
93 			break;
94 		}
95 		goto setbrk;
96 		break;
97 
98 	case 'l':
99 		setcur(1);
100 		lastcom = NOCOM;
101 		break;
102 
103 	case 'T':
104 		prfrx(1);
105 		lastcom = NOCOM;
106 		break;
107 
108 	case 't':
109 		prframe();
110 		lastcom = NOCOM;
111 		break;
112 
113 	case 'e':
114 		p = args;
115 		if (*p == '\0') {
116 #ifndef FLEXNAMES
117 			printf("%.16s() in \"%s\"\n",
118 				curproc()->pname, curfile);
119 #else
120 			printf("%s() in \"%s\"\n",
121 				curproc()->pname, curfile);
122 #endif
123 			break;
124 		}
125 
126 		while (*p != '\0')
127 			if (*p++ == '.') goto l1;
128 		/* argument is procedure name */
129 		procp = findproc(args);
130 		if ((procp->pname[0] != '\0') && (procp->sfptr != badfile)) {
131 			finit(adrtofilep(procp->paddr)->sfilename);
132 			ffind(procp->lineno);
133 		}
134 		else printf("Can't find %s\n", args);
135 #ifndef FLEXNAMES
136 		printf("%.16s() in \"%s\"\n", curproc()->pname, curfile);
137 #else
138 		printf("%s() in \"%s\"\n", curproc()->pname, curfile);
139 #endif
140 		lastcom = PRCOM;
141 		break;
142 
143 	l1:	/* argument is filename */
144 		finit(args);
145 		printf("\"%s\"\n", curfile);
146 		lastcom = PRCOM;
147 		break;
148 
149 	case 'p':
150 		if (integ) ffind(integ);
151 		fprint();
152 		lastcom = PRCOM;
153 		break;
154 
155 	case 'q':
156 		exit(0);
157 
158 	case 'w':
159 		if (integ) ffind(integ);
160 		i = fline;
161 		fback(WINDOW/2);
162 		fprintn(WINDOW);
163 		ffind(i);
164 		lastcom = PRCOM;
165 		break;
166 
167 	case 'Q':
168 		prdebug();
169 		break;
170 
171 	case 'z':
172 		if (integ) ffind(integ);
173 		fprintn(WINDOW);
174 		lastcom = PRCOM;
175 		break;
176 
177 	case '-':
178 		fback(integ ? integ : 1);
179 		fpargs();
180 		lastcom = PRCOM;
181 		break;
182 
183 	case '+':
184 		fforward(integ ? integ : 1);
185 		fpargs();
186 		lastcom = PRCOM;
187 		break;
188 
189 	case '\n':
190 		switch (lastcom) {
191 		case PRCOM:
192 			fforward(1);
193 			fprint();
194 			break;
195 		case DSCOM:
196 			oaddr += oincr ? oincr : typetosize(otype, WORDSIZE);
197 			printf("0x%x/ ", oaddr);
198 			dispf((ADDR) oaddr, odesc,
199 			    oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP);
200 			break;
201 		case DSICOM:
202 			dot += oincr;
203 			prisploc();
204 			dispi(dot, odesc, N_GSYM, 0, 0);
205 			break;
206 		}
207 		break;
208 
209 	case '\004':
210 		if (!isatty(0))
211 			exit(0);
212 		switch (lastcom) {
213 		case PRCOM:
214 			fforward(1);
215 			printf("\b");
216 			fprintn(WINDOW);
217 			lastcom = PRCOM;
218 			break;
219 		case DSICOM:
220 			printf("\b");
221 			for (i=0; i<WINDOW; i++) {
222 				dot += oincr;
223 				prisploc();
224 				if (dispi(dot, odesc, N_GSYM, 0, 0) == -1)
225 					break;
226 			}
227 			break;
228 		case DSCOM:
229 			printf("\b");
230 			for (i=0; i<WINDOW; i++) {
231 				oaddr += oincr ?
232 					oincr : typetosize(otype, WORDSIZE);
233 				printf("0x%x/ ", oaddr);
234 				if (dispf((ADDR) oaddr, odesc,
235 					oclass == N_RSYM ? oclass :
236 					N_GSYM, otype, 0, 0, DSP) == -1)
237 					break;
238 			}
239 			break;
240 		default:
241 			printf("\n");
242 		}
243 		break;
244 
245 	case 'r':
246 		if (args[0] == '\0') getargs();
247 	case 'R':
248 		signo = 0;
249 		cpstr(oldargs, args);
250 		if (debug) error("calling dopcs");
251 		if (integ) cntval = integ;
252 		if (!executing) {
253 			executing = TRUE;
254 			if (integ) cntval = integ;
255 			dopcs('r');
256 			executing = FALSE;
257 		}
258 		if (debug) error("exiting dopcs");
259 		bkaddr = -1;
260 		goto f1;
261 
262 	case 'c':
263 		signo = 0;
264 	case 'C':
265 		if (proc[0] != '\0' || integ != 0) {
266 			setdot();
267 			if (dot == -1) {
268 				error("Cannot set temporary breakpoint");
269 				break;
270 			}
271 			dopcs('b');
272 			bkaddr = dot;
273 		} else
274 			bkaddr = -1;
275 		integ = atoi(args);
276 
277 f1:		if (debug) error("calling dopcs");
278 		if (integ) cntval = integ;
279 		dopcs('c');
280 		if (debug) error("exiting dopcs");
281 		if (bkaddr != -1) {
282 			ADDR dotsave;
283 			dotsave = dot;
284 			dot = bkaddr;
285 			dopcs('d');
286 			dot = dotsave;
287 		}
288 		if (!signo) printf("Breakpoint");
289 		printf(" at\n");
290 		setcur(1);
291 		lastcom = NOCOM;
292 		break;
293 
294 	case 'S':
295 	case 's':
296 		signo = 0;
297 		integ = atoi(args);
298 		singstep(integ ? integ : 1, cmd);
299 		if (signo) printf("\n");
300 		setcur(1);
301 		lastcom = NOCOM;
302 		break;
303 
304 	case 'g':
305 		if (pid == 0  ||  signo) {
306 			error("Not stopped at breakpoint");
307 			break;
308 		}
309 		setdot();
310 		if (dot == -1) {
311 			error("Bad address");
312 			break;
313 		}
314 		adrflg = 1;
315 		integ = atoi(args);
316 		if (integ) cntval = integ;
317 		dopcs('c');
318 		if (!signo) printf("Breakpoint");
319 		printf(" at\n");
320 		setcur(1);
321 		lastcom = NOCOM;
322 		break;
323 
324 	case 'k':
325 		if (scallx) {
326 	 		userpc = dot = *(ADDR *)(((ADDR)&u)+PC) = pcs;
327 	 		*(ADDR *)(((ADDR)&u)+FP) = fps;
328 	 		*(ADDR *)(((ADDR)&u)+AP) = aps;
329 			if (bkpts)
330 				bkpts->flag = flagss;
331 			scallx = 0;
332 			error("Procedure killed");
333 			longjmp(env, 0);
334 		} else {
335 			dopcs('k');
336 			printf("\n");
337 			lastcom = NOCOM;
338 			break;
339 		}
340 
341 	case 'B':
342 		prbkpt();
343 		break;
344 
345 	case 'b':
346 	setbrk:
347 		if (proc[0] == '\0' && integ == 0) {
348 			integ = fline;
349 		}
350 		setdot();
351 		if (dot == -1 || dot == 0) {
352 			error("Cannot set breakpoint");
353 			break;
354 		}
355 		dopcs('b');
356 		s[0] = ' ';
357 		s[1] = cmd;
358 		s[2] = '\n';
359 		s[3] = 0;
360 		s[1] = cmd;
361 		printbkpt(s, adrtoprocp(dot), dot);
362 		break;
363 
364 	case 'd':
365 		if (proc[0] == '\0' && integ == 0) {
366 			idbkpt();
367 			break;
368 		}
369 		setdot();
370 		if (dot == -1) {
371 			error("Non existent breakpoint");
372 			break;
373 		}
374 		dopcs('d');
375 		break;
376 
377 	case 'D':
378 		dabkpt();
379 		error("All breakpoints deleted");
380 		break;
381 
382 	case 'm':
383 		addr = varaddr(proc[0] ? proc : curproc()->pname, var);
384 		printf("stopped with value %d\n", monex(addr, 'd'));
385 		setcur(1);
386 		lastcom = NOCOM;
387 		break;
388 
389 	case '?':
390 		if (!(var[0] == '.' && var[1] == '\0'))
391 			setdot();
392 		if (errflg) {
393 			error(errflg);
394 			break;
395 		}
396 		prisploc();
397 		dispi(dot, args[0] ? args : "i", N_GSYM, 0, 0);
398 		lastcom = DSICOM;
399 		break;
400 
401 	case '/':
402 		if (var[0] == '.' && var[1] == '\0') {
403 			if (integ == 0) integ = oaddr;
404 			dispf((ADDR) integ, args[0] ? args : odesc,
405 			    oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP);
406 			oaddr = integ;
407 		} else
408 		if (integ && (var[0] == '\0')) {
409 			dispf((ADDR) integ, args, N_GSYM, 0, 0, 0, DSP);
410 			oaddr = integ;
411 			cpstr(odesc, args);
412 			oclass = N_GSYM;
413 			otype = 0;
414 		} else
415 			dispvar(proc, var, args);
416 		lastcom = DSCOM;
417 		break;
418 
419 	case '=':
420 		if (var[0] == '\0') {
421 			if (proc[0]) {
422 				addr = getaddr(proc, integ);
423 				if (addr == -1) {
424 					error("Unknown address");
425 					break;
426 				}
427 			}
428 			else
429 				addr = integ;
430 			dispf(addr, args[0] ? args : "x", 0, -1, 0, 0, DSP);
431 		} else
432 			findvar(proc, var, args[0] ? args : "x", 2);
433 		break;
434 
435 	case '!':
436 		if (var[0] == '\0')
437 			addr = getaddr(proc, integ);
438 		else
439 			addr = varaddr(proc, var);
440 		if (addr == -1)
441 			error("Unknown variable");
442 		else {
443 			if (number(args[0]) || eqany(args[0], ".-")) {
444 				char *p;
445 				double atof();
446 				union {
447 					struct{
448 						int w1, w2;
449 					} ww;
450 					double d;
451 				} dbl;
452 
453 				p = (args[0] == '-') ? args+1 : args;
454 				for (; *p != '.' && *p != 'e'; p++) {
455 					if (!number(*p)) goto l2;
456 				}
457 				dbl.d = atof(args);
458 				putval(addr, 'd', dbl.ww.w1);
459 				if (typetodesc(sl_type,0)[0] == 'g')
460 					putval(addr+WORDSIZE, 'd', dbl.ww.w2);
461 				break;
462 			}
463 l2:			if (percentflag)
464 				*(ADDR *)(((ADDR)&u)+addr) = argvalue(args);
465 			else if (sl_class == N_RSYM && addr < 16)
466 				putreg(addr,typetodesc(sl_type,subflag)[0],
467 						argvalue(args));
468 			else
469 				putval(addr,typetodesc(sl_type,subflag)[0],
470 						argvalue(args));
471 		}
472 		lastcom = NOCOM;
473 		break;
474 
475 	case '"':
476 		printf(args);
477 		break;
478 	}
479 }
480 
481 fpargs() {
482 	register int i;
483 
484 	switch(args[0]) {
485 	case 'p':
486 	case '\0':
487 		fprint();
488 		break;
489 case 'w':
490 		i = fline;
491 		fback(WINDOW/2);
492 		fprintn(WINDOW);
493 		ffind(i);
494 		break;
495 	case 'z':
496 		fprintn(WINDOW);
497 		break;
498 	}
499 }
500 
501 MSG	BADTXT;
502 /* Used by a, b, c, C, d and g commands to find linenumber */
503 setdot() {
504 	if (ncolonflag) {
505 		dot = integ;
506 		get(dot, ISP);
507 		if (errflg)
508 			dot = -1;
509 	} else {
510 		dot = getaddr(proc, integ);
511 		if (dot == -1)
512 			errflg = "Bad line number";
513 	}
514 }
515