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