136560Sbostic #ifndef lint 2*45982Sbostic static char sccsid[] = "@(#)kstack.c 5.3 (Berkeley) 01/17/91"; 336560Sbostic #endif 436560Sbostic 536560Sbostic /* 636560Sbostic * adb - routines to probe the kernel stack when debugging post-mortem 736560Sbostic * crash dumps. 836560Sbostic */ 936560Sbostic 1036560Sbostic #include "defs.h" 1136560Sbostic #include <ctype.h> 1236560Sbostic #include <machine/pte.h> 1336560Sbostic #include <machine/frame.h> 14*45982Sbostic #include <tahoe/tahoe/rpb.h> 1536560Sbostic 1636560Sbostic struct pte *sbr; 1736560Sbostic int slr; 1836560Sbostic struct pcb pcb; 1936560Sbostic 2036560Sbostic static caddr_t rpb, erpb; 2136560Sbostic static caddr_t intstack, eintstack; 2236560Sbostic static caddr_t ustack, eustack; 2336560Sbostic 2436560Sbostic char *malloc(); 2536560Sbostic 2636560Sbostic /* 2736560Sbostic * Convert a kernel virtual address to an (off_t) physical offset. 2836560Sbostic */ 2936560Sbostic #define kvtooff(a) ((off_t)(a) & ~KERNBASE) 3036560Sbostic 3136560Sbostic /* 3236560Sbostic * Check if an address is in one of the kernel's stacks: 3336560Sbostic * interrupt stack, rpb stack (during restart sequence), 3436560Sbostic * or u. stack. 3536560Sbostic */ 3636560Sbostic #define within(a, b, e) \ 3736560Sbostic ((addr_t)(a) >= (addr_t)(b) && (addr_t)(a) < (addr_t)(e)) 3836560Sbostic #define kstackaddr(a) \ 3936560Sbostic (within(a, intstack, eintstack) || \ 4036560Sbostic within(a, rpb + sizeof(struct rpb), erpb) || \ 4136560Sbostic within(a, ustack, eustack)) 4236560Sbostic 4336560Sbostic /* 4436560Sbostic * Determine whether we are looking at a kernel core dump, and if so, 4536560Sbostic * set sbr and slr and the current pcb. 4636560Sbostic */ 4736560Sbostic getkcore() { 4836560Sbostic struct nlist *sm, *ss, *mp; 4936560Sbostic 5036560Sbostic if ((sm = lookup("_Sysmap")) == NULL || 5136560Sbostic (ss = lookup("_Syssize")) == NULL || 5236560Sbostic (mp = lookup("_masterpaddr")) == NULL) 5336560Sbostic return (0); /* a.out is not a vmunix */ 5436560Sbostic datmap.m1.b = 0; 5536560Sbostic datmap.m1.e = -1L; 5636560Sbostic /* must set sbr, slr before setpcb() */ 5736560Sbostic sbr = (struct pte *)sm->n_value; 5836560Sbostic slr = ss->n_value; 5936560Sbostic adbprintf("sbr %X slr %X\n", sbr, slr); 6036560Sbostic setpcb((addr_t)mp->n_value); 6136560Sbostic getpcb(); 6236560Sbostic findstackframe(); 6336560Sbostic return (1); 6436560Sbostic } 6536560Sbostic 6636560Sbostic /* 6736560Sbostic * A version of lookup that never returns failure, and which returns 6836560Sbostic * the n_value field of the symbol found. 6936560Sbostic */ 7036560Sbostic static caddr_t 7136560Sbostic xlookup(sym) 7236560Sbostic char *sym; 7336560Sbostic { 7436560Sbostic struct nlist *sp; 7536560Sbostic 7636560Sbostic if ((sp = lookup(sym)) == NULL) { 7736560Sbostic adbprintf("symbol %s not found ... bad kernel core?\n", sym); 7836560Sbostic exit(1); 7936560Sbostic } 8036560Sbostic return ((caddr_t)sp->n_value); 8136560Sbostic } 8236560Sbostic 8336560Sbostic /* 8436560Sbostic * Find the current stack frame when debugging the kernel. 8536560Sbostic * If we're looking at a crash dump and this was not a ``clean'' 8636560Sbostic * crash, then we must search the interrupt stack carefully 8736560Sbostic * looking for a valid frame. 8836560Sbostic */ 8936560Sbostic findstackframe() 9036560Sbostic { 9136560Sbostic register char *cp; 9236560Sbostic register int n; 9336560Sbostic caddr_t addr; 9436560Sbostic struct frame fr; 9536560Sbostic char buf[256]; 9636560Sbostic 9736560Sbostic if (readcore(kvtooff(xlookup("_panicstr")), (caddr_t)&addr, 9836560Sbostic sizeof(addr)) != sizeof(addr) || addr == 0) 9936560Sbostic return; 10036560Sbostic n = readcore(kvtooff(addr), buf, sizeof(buf)); 10136560Sbostic for (cp = buf; --n > 0 && *cp != 0; cp++) 10236560Sbostic if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp))) 10336560Sbostic *cp = '?'; 10436560Sbostic *cp = '\0'; 10536560Sbostic adbprintf("panic: %s\n", buf); 10636560Sbostic 10736560Sbostic /* 10836560Sbostic * After a panic, look at the top of the rpb stack to find a stack 10936560Sbostic * frame. If this was a clean crash, i.e. one which left the 11036560Sbostic * interrupt and kernel stacks in a reasonable state, then we should 11136560Sbostic * find a pointer to the proper stack frame here (at location 11236560Sbostic * intstack-8). If we don't find a reasonable frame here, then we 11336560Sbostic * must search down through the interrupt stack. 11436560Sbostic */ 11536560Sbostic intstack = xlookup("_intstack"); 11636560Sbostic eintstack = xlookup("_Xdoadump"); /* XXX */ 11736560Sbostic rpb = xlookup("_rsstk"); /* XXX */ 11836560Sbostic erpb = rpb + NBPG - 2 * sizeof(long); 11936560Sbostic ustack = xlookup("_u"); 12036560Sbostic eustack = ustack + ctob(UPAGES); 12136560Sbostic ustack += (int)((struct user *)0)->u_stack; 12236560Sbostic (void) readcore(kvtooff(intstack - 8), (caddr_t)&addr, sizeof(addr)); 12336560Sbostic if (!getframe(addr, &fr) && !checkintstack(&addr, &fr)) { 12436560Sbostic /* search kernel stack? */ 12536560Sbostic prints("can't locate stack frame\n"); 12636560Sbostic return; 12736560Sbostic } 12836560Sbostic /* probably shouldn't clobber pcb, but for now this is easy */ 12936560Sbostic pcb.pcb_fp = (int)addr; 13036560Sbostic pcb.pcb_pc = fr.fr_savpc; 13136560Sbostic } 13236560Sbostic 13336560Sbostic /* 13436560Sbostic * Search interrupt stack for a valid frame. Return 1 if found, 13536560Sbostic * also setting *addr to the kernel address of the frame, and *frame 13636560Sbostic * to the frame at that address. 13736560Sbostic */ 13836560Sbostic checkintstack(addr, frame) 13936560Sbostic caddr_t *addr; 14036560Sbostic struct frame *frame; 14136560Sbostic { 14236560Sbostic register int ssize; 14336560Sbostic register char *stack; 14436560Sbostic 14536560Sbostic ssize = eintstack - intstack; 14636560Sbostic if ((stack = malloc((u_int)ssize)) == NULL) 14736560Sbostic return (0); 14836560Sbostic if (readcore(kvtooff(intstack), stack, ssize) != ssize) { 14936560Sbostic free(stack); 15036560Sbostic return (0); 15136560Sbostic } 15236560Sbostic for (ssize -= sizeof(*frame); ssize >= 0; ssize -= 4) { 15336560Sbostic if (goodframe((struct frame *)&stack[ssize])) { 15436560Sbostic *addr = &intstack[ssize] + FRAMEOFF; 15536560Sbostic *frame = *(struct frame *)&stack[ssize]; 15636560Sbostic free(stack); 15736560Sbostic return (1); 15836560Sbostic } 15936560Sbostic } 16036560Sbostic free(stack); 16136560Sbostic return (0); 16236560Sbostic } 16336560Sbostic 16436560Sbostic /* 16536560Sbostic * Get a stack frame and verify that it looks like 16636560Sbostic * something which might be on a kernel stack. Return 1 if OK. 16736560Sbostic */ 16836560Sbostic getframe(addr, fp) 16936560Sbostic caddr_t addr; 17036560Sbostic struct frame *fp; 17136560Sbostic { 17236560Sbostic off_t off; 17336560Sbostic char *err = NULL; 17436560Sbostic 17536560Sbostic if (!kstackaddr(addr)) 17636560Sbostic return (0); 17736560Sbostic off = vtophys((addr_t)(addr - FRAMEOFF), &err); 17836560Sbostic if (err || readcore(off, (caddr_t)fp, sizeof(*fp)) != sizeof(*fp)) 17936560Sbostic return (0); 18036560Sbostic return (goodframe(fp)); 18136560Sbostic } 18236560Sbostic 18336560Sbostic /* 18436560Sbostic * Check a call frame to see if it's ok as a kernel stack frame. 18536560Sbostic * It should have its parent frame in the kernel stack, and should 18636560Sbostic * return to kernel code. 18736560Sbostic */ 18836560Sbostic goodframe(fr) 18936560Sbostic register struct frame *fr; 19036560Sbostic { 19136560Sbostic 19236560Sbostic return (kstackaddr(fr->fr_savfp) && 19336560Sbostic within(fr->fr_savpc, txtmap.m1.b, txtmap.m1.e)); 19436560Sbostic } 195