xref: /original-bsd/old/adb/adb.tahoe/kstack.c (revision 049d63db)
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[] = "@(#)kstack.c	5.4 (Berkeley) 04/04/91";
10 #endif /* not lint */
11 
12 /*
13  * adb - routines to probe the kernel stack when debugging post-mortem
14  * crash dumps.
15  */
16 
17 #include "defs.h"
18 #include <ctype.h>
19 #include <machine/pte.h>
20 #include <machine/frame.h>
21 #include <tahoe/tahoe/rpb.h>
22 
23 struct	pte *sbr;
24 int	slr;
25 struct	pcb pcb;
26 
27 static caddr_t rpb, erpb;
28 static caddr_t intstack, eintstack;
29 static caddr_t ustack, eustack;
30 
31 char	*malloc();
32 
33 /*
34  * Convert a kernel virtual address to an (off_t) physical offset.
35  */
36 #define	kvtooff(a)	((off_t)(a) & ~KERNBASE)
37 
38 /*
39  * Check if an address is in one of the kernel's stacks:
40  * interrupt stack, rpb stack (during restart sequence),
41  * or u. stack.
42  */
43 #define	within(a, b, e) \
44 	((addr_t)(a) >= (addr_t)(b) && (addr_t)(a) < (addr_t)(e))
45 #define	kstackaddr(a) \
46 	(within(a, intstack, eintstack) || \
47 	 within(a, rpb + sizeof(struct rpb), erpb) || \
48 	 within(a, ustack, eustack))
49 
50 /*
51  * Determine whether we are looking at a kernel core dump, and if so,
52  * set sbr and slr and the current pcb.
53  */
54 getkcore() {
55 	struct nlist *sm, *ss, *mp;
56 
57 	if ((sm = lookup("_Sysmap")) == NULL ||
58 	    (ss = lookup("_Syssize")) == NULL ||
59 	    (mp = lookup("_masterpaddr")) == NULL)
60 		return (0);	/* a.out is not a vmunix */
61 	datmap.m1.b = 0;
62 	datmap.m1.e = -1L;
63 	/* must set sbr, slr before setpcb() */
64 	sbr = (struct pte *)sm->n_value;
65 	slr = ss->n_value;
66 	adbprintf("sbr %X slr %X\n", sbr, slr);
67 	setpcb((addr_t)mp->n_value);
68 	getpcb();
69 	findstackframe();
70 	return (1);
71 }
72 
73 /*
74  * A version of lookup that never returns failure, and which returns
75  * the n_value field of the symbol found.
76  */
77 static caddr_t
78 xlookup(sym)
79 	char *sym;
80 {
81 	struct nlist *sp;
82 
83 	if ((sp = lookup(sym)) == NULL) {
84 		adbprintf("symbol %s not found ... bad kernel core?\n", sym);
85 		exit(1);
86 	}
87 	return ((caddr_t)sp->n_value);
88 }
89 
90 /*
91  * Find the current stack frame when debugging the kernel.
92  * If we're looking at a crash dump and this was not a ``clean''
93  * crash, then we must search the interrupt stack carefully
94  * looking for a valid frame.
95  */
96 findstackframe()
97 {
98 	register char *cp;
99 	register int n;
100 	caddr_t addr;
101 	struct frame fr;
102 	char buf[256];
103 
104 	if (readcore(kvtooff(xlookup("_panicstr")), (caddr_t)&addr,
105 			sizeof(addr)) != sizeof(addr) || addr == 0)
106 		return;
107 	n = readcore(kvtooff(addr), buf, sizeof(buf));
108 	for (cp = buf; --n > 0 && *cp != 0; cp++)
109 		if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp)))
110 			*cp = '?';
111 	*cp = '\0';
112 	adbprintf("panic: %s\n", buf);
113 
114 	/*
115 	 * After a panic, look at the top of the rpb stack to find a stack
116 	 * frame.  If this was a clean crash, i.e. one which left the
117 	 * interrupt and kernel stacks in a reasonable state, then we should
118 	 * find a pointer to the proper stack frame here (at location
119 	 * intstack-8).  If we don't find a reasonable frame here, then we
120 	 * must search down through the interrupt stack.
121 	 */
122 	intstack = xlookup("_intstack");
123 	eintstack = xlookup("_Xdoadump");		/* XXX */
124 	rpb = xlookup("_rsstk");			/* XXX */
125 	erpb = rpb + NBPG - 2 * sizeof(long);
126 	ustack = xlookup("_u");
127 	eustack = ustack + ctob(UPAGES);
128 	ustack += (int)((struct user *)0)->u_stack;
129 	(void) readcore(kvtooff(intstack - 8), (caddr_t)&addr, sizeof(addr));
130 	if (!getframe(addr, &fr) && !checkintstack(&addr, &fr)) {
131 		/* search kernel stack? */
132 		prints("can't locate stack frame\n");
133 		return;
134 	}
135 	/* probably shouldn't clobber pcb, but for now this is easy */
136 	pcb.pcb_fp = (int)addr;
137 	pcb.pcb_pc = fr.fr_savpc;
138 }
139 
140 /*
141  * Search interrupt stack for a valid frame.  Return 1 if found,
142  * also setting *addr to the kernel address of the frame, and *frame
143  * to the frame at that address.
144  */
145 checkintstack(addr, frame)
146 	caddr_t *addr;
147 	struct frame *frame;
148 {
149 	register int ssize;
150 	register char *stack;
151 
152 	ssize = eintstack - intstack;
153 	if ((stack = malloc((u_int)ssize)) == NULL)
154 		return (0);
155 	if (readcore(kvtooff(intstack), stack, ssize) != ssize) {
156 		free(stack);
157 		return (0);
158 	}
159 	for (ssize -= sizeof(*frame); ssize >= 0; ssize -= 4) {
160 		if (goodframe((struct frame *)&stack[ssize])) {
161 			*addr = &intstack[ssize] + FRAMEOFF;
162 			*frame = *(struct frame *)&stack[ssize];
163 			free(stack);
164 			return (1);
165 		}
166 	}
167 	free(stack);
168 	return (0);
169 }
170 
171 /*
172  * Get a stack frame and verify that it looks like
173  * something which might be on a kernel stack.  Return 1 if OK.
174  */
175 getframe(addr, fp)
176 	caddr_t addr;
177 	struct frame *fp;
178 {
179 	off_t off;
180 	char *err = NULL;
181 
182 	if (!kstackaddr(addr))
183 		return (0);
184 	off = vtophys((addr_t)(addr - FRAMEOFF), &err);
185 	if (err || readcore(off, (caddr_t)fp, sizeof(*fp)) != sizeof(*fp))
186 		return (0);
187 	return (goodframe(fp));
188 }
189 
190 /*
191  * Check a call frame to see if it's ok as a kernel stack frame.
192  * It should have its parent frame in the kernel stack, and should
193  * return to kernel code.
194  */
195 goodframe(fr)
196 	register struct frame *fr;
197 {
198 
199 	return (kstackaddr(fr->fr_savfp) &&
200 		within(fr->fr_savpc, txtmap.m1.b, txtmap.m1.e));
201 }
202