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