xref: /original-bsd/old/adb/adb.vax/machdep.c (revision 125ffe57)
1 /*-
2  * Copyright (c) 1991 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.proprietary.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)machdep.c	5.4 (Berkeley) 04/04/91";
10 #endif /* not lint */
11 
12 /*
13  * adb - miscellaneous machine dependent routines.
14  */
15 
16 #define	RLOCALS			/* enable alternate $C stack trace */
17 
18 #include "defs.h"
19 #include "bkpt.h"
20 #include <machine/pte.h>
21 #include <machine/frame.h>
22 #include <machine/reg.h>
23 #include <machine/vmparam.h>
24 #include <sys/ptrace.h>
25 #include <sys/vmmac.h>
26 #include <stab.h>
27 
28 struct	pte *sbr;
29 int	slr;
30 struct	pcb pcb;
31 int	masterpcbb;
32 
33 /*
34  * Activation records.
35  */
36 
37 /*
38  * Set up a stack frame based on the registers in the core image
39  * (or in the kernel core file ... not yet!).
40  */
a_init(ap)41 a_init(ap)
42 	register struct activation *ap;
43 {
44 
45 	ap->a_valid = 1;
46 	if (kcore) {
47 		ap->a_ap = pcb.pcb_ap;
48 		ap->a_fp = pcb.pcb_fp;
49 		ap->a_pc = pcb.pcb_pc;
50 	} else {
51 		ap->a_ap = u.u_ar0[AP];
52 		ap->a_fp = u.u_ar0[FP];
53 		ap->a_pc = u.u_ar0[PC];
54 	}
55 }
56 
57 /*
58  * Back up one stack frame in the call stack.
59  * ap points to the activation record from the previous frame.
60  * Clear a_valid field if we ran out of frames.
61  */
a_back(ap)62 a_back(ap)
63 	register struct activation *ap;
64 {
65 	struct frame fr;
66 
67 	/*
68 	 * The magic constants below allow us to read just the part of
69 	 * the frame that we need.
70 	 */
71 	if (adbread(SP_DATA, ap->a_fp + 8, &fr.fr_savap, 12) != 12)
72 		ap->a_valid = 0;
73 	else {
74 		ap->a_ap = fr.fr_savap;
75 		ap->a_fp = fr.fr_savfp;
76 		ap->a_pc = fr.fr_savpc;
77 		if (ap->a_fp == 0)
78 			ap->a_valid = 0;
79 	}
80 }
81 
82 /*
83  * Evaluate a local symbol (N_LSYM or N_PSYM) using the activation
84  * record pointed to by ap.
85  */
86 addr_t
eval_localsym(sp,ap)87 eval_localsym(sp, ap)
88 	register struct nlist *sp;
89 	struct activation *ap;
90 {
91 	switch (sp->n_type) {
92 
93 	case N_LSYM:
94 		return (ap->a_fp - sp->n_value);	/* ??? */
95 
96 	case N_PSYM:
97 		return (ap->a_ap + sp->n_value);	/* ??? */
98 	}
99 	panic("eval_localsym");
100 	/* NOTREACHED */
101 }
102 
103 
104 /* true iff address a is in instruction space */
105 #define	ispace(a) ((a) < txtmap.m1.e)
106 
107 /*
108  * Delete a (single) breakpoint.  Return 0 on success.
109  */
110 int
clr_bpt(b)111 clr_bpt(b)
112 	struct bkpt *b;
113 {
114 	addr_t a = b->loc;
115 
116 	return (adbwrite(ispace(a) ? SP_INSTR : SP_DATA, a, &b->ins, 1) != 1);
117 }
118 
119 /*
120  * Set a (single) breakpoint.  Return 0 on success.
121  */
122 set_bpt(b)
123 	struct bkpt *b;
124 {
125 	addr_t a = b->loc;
126 	int space;
127 	char bpt = 0x03;		/* breakpoint instruction */
128 
129 	space = ispace(a) ? SP_INSTR : SP_DATA;
130 	return (adbread(space, a, &b->ins, 1) != 1 ||
131 		adbwrite(space, a, &bpt, 1) != 1);
132 }
133 
134 /*
135  * Check a float for `correctness' (reserved patterns, etc).  Return
136  * a pointer to a character string to be printed instead of the float,
137  * or NULL to print the float as-is.
138  *
139  * The string returned, if any, should be no longer than 16 characters.
140  *
141  * On the VAX, we can simply check the first two bytes.  Byte zero
142  * contains one bit of the exponent, and byte 1 has the remaining 7
143  * exponent bits and the sign bit.  If the sign bit is set and the
144  * exponent is zero, the value is reserved.
145  */
146 /* ARGSUSED */
147 char *
checkfloat(fp,isdouble)148 checkfloat(fp, isdouble)
149 	caddr_t fp;
150 	int isdouble;
151 {
152 
153 	return ((*(short *)fp & 0xff80) == 0x8000 ? "(reserved oprnd)" : NULL);
154 }
155 
156 /*
157  * Convert a value in `expr_t' format to float or double.
158  */
etofloat(e,fp,isdouble)159 etofloat(e, fp, isdouble)
160 	expr_t e;
161 	caddr_t fp;
162 	int isdouble;
163 {
164 
165 	if (isdouble)
166 		((int *)fp)[1] = 0;
167 	*(int *)fp = e;
168 }
169 
mch_init()170 mch_init()
171 {
172 
173 	mkioptab();
174 }
175 
176 /* quietly read object obj from address addr */
177 #define	GET(obj, addr)	(void) adbread(SP_DATA, addr, &(obj), sizeof(obj))
178 
179 /* set `current process' pcb */
setpcb(addr)180 setpcb(addr)
181 	addr_t addr;
182 {
183 	int pte;
184 
185 	GET(pte, addr);
186 	masterpcbb = (pte & PG_PFNUM) * NBPG;
187 }
188 
getpcb()189 getpcb()
190 {
191 
192 	/* maybe use adbread() here ... */
193 	(void) readcore((off_t)masterpcbb & ~KERNBASE,
194 		(char *)&pcb, sizeof(struct pcb));
195 	pcb.pcb_p0lr &= ~AST_CLR;
196 	adbprintf("p0br %R p0lr %R p1br %R p1lr %R\n",
197 	    pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr);
198 }
199 
200 /*
201  * Convert a kernel virtual address to a physical address,
202  * a la the VAX hardware.  Set *err if the resulting address
203  * is invalid.
204  */
205 addr_t
vtophys(addr,err)206 vtophys(addr, err)
207 	addr_t addr;
208 	char **err;
209 {
210 	register unsigned v = btop(addr & ~0xc0000000);
211 	register addr_t pteaddr;
212 	struct pte pte;
213 #define issys(a) ((a) & 0x80000000)
214 #define isp1(a) ((a) & 0x40000000)
215 
216 	if (issys(addr)) {
217 		/* system space: get system pte */
218 		if (isp1(addr) || v >= slr) {
219 	oor:
220 			*err = "address out of segment";
221 			return (0);
222 		}
223 		pteaddr = (addr_t)(sbr + v) & ~0x80000000;
224 	} else {
225 		if (isp1(addr)) {
226 			/* P1 space: must not be in shadow region */
227 			if (v < pcb.pcb_p1lr)
228 				goto oor;
229 			pteaddr = (addr_t)(pcb.pcb_p1br + v);
230 		} else {
231 			/* P0 space: must not be off end of region */
232 			if (v >= pcb.pcb_p0lr)
233 				goto oor;
234 			pteaddr = (addr_t)(pcb.pcb_p0br + v);
235 		}
236 		if (!issys(pteaddr) || isp1(pteaddr)) {
237 			*err = "bad p0br or p1br in pcb";
238 			return (0);
239 		}
240 		/* in either case, find system pte by recursing */
241 		pteaddr = vtophys(pteaddr, err);
242 		if (*err)
243 			return (0);
244 	}
245 
246 	/*
247 	 * Read system pte.  If valid or reclaimable,
248 	 * physical address is combination of its page number and
249 	 * the page offset of the original address.
250 	 */
251 	if (readcore((off_t)pteaddr, (caddr_t)&pte, 4) != 4) {
252 		*err = "page table botch";
253 		return (0);
254 	}
255 	/* SHOULD CHECK NOT I/O ADDRESS; NEED CPU TYPE! */
256 	if (pte.pg_v == 0 && (pte.pg_fod || pte.pg_pfnum == 0)) {
257 		*err = "page not valid/reclaimable";
258 		return (0);
259 	}
260 	return ((addr_t)(ptob(pte.pg_pfnum) + (addr & PGOFSET)));
261 }
262 
263 /*
264  * Print a stack trace ($c, $C).  Trace backwards through nback
265  * frames; if locals is set, print local variables.
266  */
printstack(locals,nback)267 printstack(locals, nback)
268 	int locals, nback;
269 {
270 	register int i;
271 	register addr_t a;
272 	struct nlist *sym;
273 	char *s;
274 /*	addr_t callpc;		/* pc that called this frame */
275 	struct activation cur;	/* this frame itself */
276 	struct frame fr;	/* the frame above this frame */
277 	u_char narg;		/* number of int-args to this frame */
278 	addr_t dummy;		/* a variable to scribble on */
279 #define	UNKNOWN	-1
280 
281 #ifdef RLOCALS
282 	/* if locals variables are broken, use an alternate strategy */
283 	register int r;
284 	addr_t sp, prev_sp;
285 	int regs[12];
286 	static char unknown[] = "<unknown>";
287 #endif
288 
289 	/* fr_savpc==UNKNOWN implies fr is invalid */
290 	fr.fr_savpc = UNKNOWN;
291 
292 #ifdef RLOCALS
293 	/* grab registers */
294 	bcopy((caddr_t)(kcore ? &pcb.pcb_r0 : &u.u_ar0[R0]), (caddr_t)regs,
295 		sizeof(regs));
296 #endif
297 
298 	/* set up the current stack frame */
299 	if (gavedot) {
300 		GET(fr, cur.a_fp = dot);
301 		checkerr();
302 		if (fr.fr_s) {	/* was a `calls'; can figure out ap */
303 			cur.a_ap = cur.a_fp + sizeof(fr) + fr.fr_spa;
304 			for (i = fr.fr_mask; i != 0; i >>= 1)
305 				if (i & 1)
306 					cur.a_ap += 4;
307 		} else		/* `callg': cannot find ap */
308 			cur.a_ap = UNKNOWN;
309 		cur.a_pc = UNKNOWN;
310 #ifdef RLOCALS
311 		sp = UNKNOWN;
312 #endif
313 	} else if (kcore) {
314 		cur.a_ap = pcb.pcb_ap;
315 		cur.a_fp = pcb.pcb_fp;
316 		cur.a_pc = pcb.pcb_pc;
317 #ifdef RLOCALS
318 		sp = pcb.pcb_ksp;
319 #endif
320 	} else {
321 		cur.a_ap = u.u_ar0[AP];
322 		cur.a_fp = u.u_ar0[FP];
323 		cur.a_pc = u.u_ar0[PC];
324 #ifdef RLOCALS
325 		sp = u.u_ar0[SP];
326 #endif
327 	}
328 
329 	/* now back up through the stack */
330 	while (nback--) {
331 		if (fr.fr_savpc == UNKNOWN)
332 			GET(fr, cur.a_fp);
333 
334 		/* where are we? ... if u. area, signal trampoline code */
335 		if ((int)cur.a_pc >= USRSTACK) {
336 /*			GET(callpc, cur.a_fp + 92);	/* XXX magic 92 */
337 			s = "sigtramp";
338 		} else {
339 /*			callpc = fr.fr_savpc; */
340 			if (cur.a_pc != UNKNOWN &&
341 			    (sym = findsym(cur.a_pc, SP_INSTR, &dummy)) != 0) {
342 				s = sym->n_un.n_name;
343 				if (eqstr(s, "start")) {
344 					errflag = NULL;
345 					break;
346 				}
347 			} else
348 				s = "?";
349 		}
350 		adbprintf("%s(", s);
351 		if ((a = cur.a_ap) != UNKNOWN) {
352 			GET(narg, a);
353 			for (i = narg > 20 ? 20 : narg; i;)
354 				prfrom(a += 4, --i ? ',' : 0);
355 		}
356 		printc(')');
357 		if (cur.a_pc != UNKNOWN) {
358 			prints(" at ");
359 			psymoff("%R", cur.a_pc, SP_INSTR, -(addr_t)1, "");
360 		}
361 		printc('\n');
362 
363 		/* local variables */
364 		if (locals) {
365 #ifdef busted
366 			if (cur.a_pc != UNKNOWN) {
367 				sym = findsym(cur.a_pc, SP_INSTR, &dummy);
368 				while ((sym = nextlocal(sym)) != NULL) {
369 					adbprintf("%8t");
370 					printlsym(sym->n_un.n_name);
371 					adbprintf(":%12t");
372 					prfrom(eval_localsym(sym, &cur), '\n');
373 				}
374 			}
375 #endif
376 #ifdef RLOCALS
377 			adbprintf("\
378 fp: %R\%16tap: %?s%?R%32tsp:  %?s%?R%48tpc:  %?s%?R\n\
379 r0: %R\%16tr1: %R\%32tr2:  %R\%48tr3:  %R\n\
380 r4: %R\%16tr5: %R\%32tr6:  %R\%48tr7:  %R\n\
381 r8: %R\%16tr9: %R\%32tr10: %R\%48tr11: %R\n",
382 #define q(s) s == UNKNOWN, unknown, s != UNKNOWN, s
383 			    cur.a_fp, q(cur.a_ap), q(sp), q(cur.a_pc),
384 #undef q
385 			    regs[0], regs[1], regs[2], regs[3],
386 			    regs[4], regs[5], regs[6], regs[7],
387 			    regs[8], regs[9], regs[10], regs[11]);
388 
389 			/* update registers, and find previous frame's sp */
390 			a = cur.a_fp + 16;
391 			for (r = 0, i = fr.fr_mask; i != 0; r++, i >>= 1)
392 				if (i & 1)
393 					GET(regs[r], a += 4);
394 			a += fr.fr_spa;
395 			if (fr.fr_s)
396 				a += narg * 4;
397 			prev_sp = a;
398 
399 			/* now print automatics */
400 			if (sp != UNKNOWN) {
401 #define	MAXPRINT 30		/* max # words to print */
402 				/* XXX should be settable */
403 				i = (cur.a_fp - sp) >> 2;
404 				if (i > MAXPRINT)
405 					i = MAXPRINT;
406 				for (a = cur.a_fp; --i >= 0;) {
407 					a -= 4;
408 					adbprintf("%R: %V(fp):%24t",
409 						a, a - cur.a_fp);
410 					prfrom(a, '\n');
411 				}
412 				if (a > sp)
413 					adbprintf("\
414 %R: %V(fp) .. %R: %V(fp) not displayed\n",
415 						a, a - cur.a_fp,
416 						sp, sp - cur.a_fp);
417 			}
418 #endif /* RLOCALS */
419 		}
420 
421 		errflag = NULL;		/* clobber any read errors */
422 
423 		/* back up one frame */
424 		if (fr.fr_savfp == 0)
425 			break;
426 		cur.a_ap = fr.fr_savap;
427 		cur.a_fp = fr.fr_savfp;
428 #ifdef RLOCALS
429 		sp = prev_sp;
430 #endif
431 		cur.a_pc = fr.fr_savpc;
432 		fr.fr_savpc = UNKNOWN;	/* until we read it again */
433 
434 		if (!gavedot && !INSTACK(cur.a_fp) && !kcore)
435 			break;
436 
437 		/* make sure we returned somewhere... */
438 		(void) adbread(kcore ? SP_DATA : SP_INSTR, cur.a_pc, &dummy, 1);
439 		checkerr();
440 	}
441 }
442 
443 /*
444  * Register offset to u. pointer, and register offset to ptrace value
445  */
446 #define	otoua(o) \
447 	((int *)(((o) < 0 ? (int)u.u_ar0 : (int)&u.u_pcb) + (o)))
448 #define	otopt(o) \
449 	((int *)((o) < 0 ? (o) + ctob(UPAGES) : (o)))
450 
451 /*
452  * Return the value of some register.
453  */
454 expr_t
getreg(reg)455 getreg(reg)
456 	register struct reglist *reg;
457 {
458 
459 	return (kcore ? *reg->r_pcbaddr : *otoua(reg->r_offset));
460 }
461 
462 
463 /*
464  * Set the value of some register.  Return 0 if all goes well.
465  */
setreg(reg,val)466 setreg(reg, val)
467 	register struct reglist *reg;
468 	expr_t val;
469 {
470 
471 	if (kcore)
472 		*reg->r_pcbaddr = val;
473 	else {
474 		*otoua(reg->r_offset) = val;
475 		if (pid) {
476 			errno = 0;
477 			if (ptrace(PT_WRITE_U, pid, otopt(reg->r_offset),
478 					(int)val) == -1 && errno)
479 				return (-1);
480 		}
481 	}
482 	return (0);
483 }
484 
485 /*
486  * Read registers from current process.
487  */
readregs()488 readregs()
489 {
490 	register struct reglist *reg;
491 	extern struct reglist reglist[];
492 
493 	for (reg = reglist; reg->r_name != NULL; reg++)
494 		*otoua(reg->r_offset) =
495 			ptrace(PT_READ_U, pid, otopt(reg->r_offset), 0);
496 }
497 
498 addr_t
getpc()499 getpc()
500 {
501 
502 	return (u.u_ar0[PC]);
503 }
504 
setpc(where)505 setpc(where)
506 	addr_t where;
507 {
508 
509 	u.u_ar0[PC] = where;
510 }
511 
512 /*
513  * udot returns true if u.u_pcb appears correct.  More extensive
514  * checking is possible....
515  */
udot()516 udot()
517 {
518 
519 	/* user stack should be in stack segment */
520 	if (!INSTACK(u.u_pcb.pcb_usp))
521 		return (0);
522 	/* kernel stack should be in u. area */
523 	if (u.u_pcb.pcb_ksp < USRSTACK)
524 		return (0);
525 	/* looks good to us... */
526 	return (1);
527 }
528 
sigprint()529 sigprint()
530 {
531 	extern char *sys_siglist[];
532 	extern char *illinames[], *fpenames[];
533 	extern int nillinames, nfpenames;
534 
535 	if ((u_int)signo - 1 < NSIG - 1)
536 		prints(sys_siglist[signo]);
537 	switch (signo) {
538 
539 	case SIGFPE:
540 		if ((u_int)sigcode < nfpenames)
541 			prints(fpenames[sigcode]);
542 		break;
543 
544 	case SIGILL:
545 		if ((u_int)sigcode < nillinames)
546 			prints(illinames[sigcode]);
547 		break;
548 	}
549 }
550