19661Slinton /* Copyright (c) 1982 Regents of the University of California */ 29661Slinton 3*18215Slinton static char sccsid[] = "@(#)coredump.c 1.7 (Berkeley) 03/01/85"; 49661Slinton 5*18215Slinton static char rcsid[] = "$Header: coredump.c,v 1.5 84/12/26 10:38:56 linton Exp $"; 6*18215Slinton 79661Slinton /* 89661Slinton * Deal with the core dump anachronism. 99661Slinton */ 109661Slinton 119661Slinton #include "defs.h" 129661Slinton #include "coredump.h" 139661Slinton #include "machine.h" 149661Slinton #include "object.h" 159661Slinton #include "main.h" 169661Slinton #include <sys/param.h> 179661Slinton #include <sys/dir.h> 189839Slinton #include <machine/psl.h> 199839Slinton #include <machine/pte.h> 209661Slinton #include <sys/user.h> 219661Slinton #include <sys/vm.h> 229839Slinton #include <machine/reg.h> 239661Slinton #include <a.out.h> 249661Slinton 259661Slinton #ifndef public 269661Slinton #define coredump_readin(m, r, s) coredump_xreadin(&(m), r, &(s)) 279661Slinton 289661Slinton #include "machine.h" 299661Slinton #endif 309661Slinton 319661Slinton #define MAXSTKADDR (0x80000000 - ctob(UPAGES)) /* highest stack address */ 329661Slinton 339661Slinton typedef struct { 349661Slinton Address begin; 359661Slinton Address end; 369661Slinton Address seekaddr; 379661Slinton } Map; 389661Slinton 399661Slinton private Map datamap, stkmap; 409661Slinton private File objfile; 419661Slinton private struct exec hdr; 429661Slinton 439661Slinton /* 44*18215Slinton * Special variables for debugging the kernel. 459661Slinton */ 469661Slinton 47*18215Slinton private integer masterpcbb; 48*18215Slinton private integer slr; 49*18215Slinton private struct pte *sbr; 50*18215Slinton private struct pcb pcb; 51*18215Slinton 52*18215Slinton private getpcb () 539661Slinton { 54*18215Slinton fseek(corefile, masterpcbb & ~0x80000000, 0); 55*18215Slinton get(corefile, pcb); 56*18215Slinton pcb.pcb_p0lr &= ~AST_CLR; 57*18215Slinton printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n", 58*18215Slinton pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr 59*18215Slinton ); 60*18215Slinton setreg(0, pcb.pcb_r0); 61*18215Slinton setreg(1, pcb.pcb_r1); 62*18215Slinton setreg(2, pcb.pcb_r2); 63*18215Slinton setreg(3, pcb.pcb_r3); 64*18215Slinton setreg(4, pcb.pcb_r4); 65*18215Slinton setreg(5, pcb.pcb_r5); 66*18215Slinton setreg(6, pcb.pcb_r6); 67*18215Slinton setreg(7, pcb.pcb_r7); 68*18215Slinton setreg(8, pcb.pcb_r8); 69*18215Slinton setreg(9, pcb.pcb_r9); 70*18215Slinton setreg(10, pcb.pcb_r10); 71*18215Slinton setreg(11, pcb.pcb_r11); 72*18215Slinton setreg(ARGP, pcb.pcb_ap); 73*18215Slinton setreg(FRP, pcb.pcb_fp); 74*18215Slinton setreg(STKP, pcb.pcb_ksp); 75*18215Slinton setreg(PROGCTR, pcb.pcb_pc); 76*18215Slinton } 779661Slinton 78*18215Slinton public coredump_getkerinfo () 79*18215Slinton { 80*18215Slinton Symbol s; 81*18215Slinton 82*18215Slinton s = lookup(identname("Sysmap", true)); 83*18215Slinton if (s == nil) { 84*18215Slinton panic("can't find 'Sysmap'"); 859661Slinton } 86*18215Slinton sbr = (struct pte *) (s->symvalue.offset); 87*18215Slinton s = lookup(identname("Syssize", true)); 88*18215Slinton if (s == nil) { 89*18215Slinton panic("can't find 'Syssize'"); 90*18215Slinton } 91*18215Slinton slr = (integer) (s->symvalue.offset); 92*18215Slinton printf("sbr %lx slr %lx\n", sbr, slr); 93*18215Slinton s = lookup(identname("masterpaddr", true)); 94*18215Slinton if (s == nil) { 95*18215Slinton panic("can't find 'masterpaddr'"); 96*18215Slinton } 97*18215Slinton fseek( 98*18215Slinton corefile, 99*18215Slinton datamap.seekaddr + s->symvalue.offset&0x7fffffff - datamap.begin, 100*18215Slinton 0 101*18215Slinton ); 102*18215Slinton get(corefile, masterpcbb); 103*18215Slinton masterpcbb = (masterpcbb&PG_PFNUM)*512; 104*18215Slinton getpcb(); 105*18215Slinton } 106*18215Slinton 107*18215Slinton private copyregs (savreg, reg) 108*18215Slinton Word savreg[], reg[]; 109*18215Slinton { 1109661Slinton reg[0] = savreg[R0]; 1119661Slinton reg[1] = savreg[R1]; 1129661Slinton reg[2] = savreg[R2]; 1139661Slinton reg[3] = savreg[R3]; 1149661Slinton reg[4] = savreg[R4]; 1159661Slinton reg[5] = savreg[R5]; 1169661Slinton reg[6] = savreg[R6]; 1179661Slinton reg[7] = savreg[R7]; 1189661Slinton reg[8] = savreg[R8]; 1199661Slinton reg[9] = savreg[R9]; 1209661Slinton reg[10] = savreg[R10]; 1219661Slinton reg[11] = savreg[R11]; 1229661Slinton reg[ARGP] = savreg[AP]; 1239661Slinton reg[FRP] = savreg[FP]; 1249661Slinton reg[STKP] = savreg[SP]; 1259661Slinton reg[PROGCTR] = savreg[PC]; 126*18215Slinton } 1279661Slinton 128*18215Slinton /* 129*18215Slinton * Read the user area information from the core dump. 130*18215Slinton */ 1319661Slinton 132*18215Slinton public coredump_xreadin(mask, reg, signo) 133*18215Slinton int *mask; 134*18215Slinton Word reg[]; 135*18215Slinton int *signo; 136*18215Slinton { 137*18215Slinton register struct user *up; 138*18215Slinton register Word *savreg; 139*18215Slinton union { 140*18215Slinton struct user u; 141*18215Slinton char dummy[ctob(UPAGES)]; 142*18215Slinton } ustruct; 143*18215Slinton Symbol s; 144*18215Slinton 145*18215Slinton objfile = fopen(objname, "r"); 146*18215Slinton if (objfile == nil) { 147*18215Slinton fatal("can't read \"%s\"", objname); 1489661Slinton } 149*18215Slinton get(objfile, hdr); 150*18215Slinton if (vaddrs) { 151*18215Slinton datamap.begin = 0; 152*18215Slinton datamap.end = 0xffffffff; 153*18215Slinton stkmap.begin = 0xffffffff; 154*18215Slinton stkmap.end = 0xffffffff; 155*18215Slinton } else { 156*18215Slinton up = &(ustruct.u); 157*18215Slinton fread(up, ctob(UPAGES), 1, corefile); 158*18215Slinton savreg = (Word *) &(ustruct.dummy[ctob(UPAGES)]); 159*18215Slinton *mask = savreg[PS]; 160*18215Slinton copyregs(savreg, reg); 161*18215Slinton *signo = up->u_arg[0]; 162*18215Slinton datamap.seekaddr = ctob(UPAGES); 163*18215Slinton stkmap.begin = MAXSTKADDR - ctob(up->u_ssize); 164*18215Slinton stkmap.end = MAXSTKADDR; 165*18215Slinton stkmap.seekaddr = datamap.seekaddr + ctob(up->u_dsize); 166*18215Slinton switch (hdr.a_magic) { 167*18215Slinton case OMAGIC: 168*18215Slinton datamap.begin = 0; 169*18215Slinton datamap.end = ctob(up->u_tsize) + ctob(up->u_dsize); 170*18215Slinton break; 171*18215Slinton 172*18215Slinton case NMAGIC: 173*18215Slinton case ZMAGIC: 174*18215Slinton datamap.begin = (Address) ptob(btop(ctob(up->u_tsize) - 1) + 1); 175*18215Slinton datamap.end = datamap.begin + ctob(up->u_dsize); 176*18215Slinton break; 177*18215Slinton 178*18215Slinton default: 179*18215Slinton fatal("bad magic number 0x%x", hdr.a_magic); 180*18215Slinton } 181*18215Slinton #ifdef UXMAG 182*18215Slinton /* 183*18215Slinton * Core dump not from this object file? 184*18215Slinton */ 185*18215Slinton if (hdr.a_magic != 0 and up->u_exdata.ux_mag != 0 and 186*18215Slinton hdr.a_magic != up->u_exdata.ux_mag) { 187*18215Slinton warning("core dump ignored"); 188*18215Slinton coredump = false; 189*18215Slinton fclose(corefile); 190*18215Slinton fclose(objfile); 191*18215Slinton start(nil, nil, nil); 192*18215Slinton } 193*18215Slinton #endif 194*18215Slinton } 1959661Slinton } 1969661Slinton 1979661Slinton public coredump_close() 1989661Slinton { 1999661Slinton fclose(objfile); 2009661Slinton } 2019661Slinton 2029661Slinton public coredump_readtext(buff, addr, nbytes) 2039661Slinton char *buff; 2049661Slinton Address addr; 2059661Slinton int nbytes; 2069661Slinton { 207*18215Slinton if (hdr.a_magic == OMAGIC or vaddrs) { 2089661Slinton coredump_readdata(buff, addr, nbytes); 2099661Slinton } else { 2109661Slinton fseek(objfile, N_TXTOFF(hdr) + addr, 0); 2119661Slinton fread(buff, nbytes, sizeof(Byte), objfile); 2129661Slinton } 2139661Slinton } 2149661Slinton 215*18215Slinton /* 216*18215Slinton * Map a virtual address to a physical address. 217*18215Slinton */ 218*18215Slinton 219*18215Slinton private Address vmap (addr) 220*18215Slinton Address addr; 221*18215Slinton { 222*18215Slinton Address r; 223*18215Slinton integer v, n; 224*18215Slinton struct pte pte; 225*18215Slinton 226*18215Slinton r = addr & ~0xc0000000; 227*18215Slinton v = btop(r); 228*18215Slinton switch (addr&0xc0000000) { 229*18215Slinton case 0xc0000000: 230*18215Slinton case 0x80000000: 231*18215Slinton /* 232*18215Slinton * In system space, so get system pte. 233*18215Slinton * If it is valid or reclaimable then the physical address 234*18215Slinton * is the combination of its page number and the page offset 235*18215Slinton * of the original address. 236*18215Slinton */ 237*18215Slinton if (v >= slr) { 238*18215Slinton error("address %x out of segment", addr); 239*18215Slinton } 240*18215Slinton r = ((long) (sbr + v)) & ~0x80000000; 241*18215Slinton goto simple; 242*18215Slinton 243*18215Slinton case 0x40000000: 244*18215Slinton /* 245*18215Slinton * In p1 space, must not be in shadow region. 246*18215Slinton */ 247*18215Slinton if (v < pcb.pcb_p1lr) { 248*18215Slinton error("address %x out of segment", addr); 249*18215Slinton } 250*18215Slinton r = (Address) (pcb.pcb_p1br + v); 251*18215Slinton break; 252*18215Slinton 253*18215Slinton case 0x00000000: 254*18215Slinton /* 255*18215Slinton * In p0 space, must not be off end of region. 256*18215Slinton */ 257*18215Slinton if (v >= pcb.pcb_p0lr) { 258*18215Slinton error("address %x out of segment", addr); 259*18215Slinton } 260*18215Slinton r = (Address) (pcb.pcb_p0br + v); 261*18215Slinton break; 262*18215Slinton 263*18215Slinton default: 264*18215Slinton /* do nothing */ 265*18215Slinton break; 266*18215Slinton } 267*18215Slinton /* 268*18215Slinton * For p0/p1 address, user-level page table should be in 269*18215Slinton * kernel virtual memory. Do second-level indirect by recursing. 270*18215Slinton */ 271*18215Slinton if ((r & 0x80000000) == 0) { 272*18215Slinton error("bad p0br or p1br in pcb"); 273*18215Slinton } 274*18215Slinton r = vmap(r); 275*18215Slinton simple: 276*18215Slinton /* 277*18215Slinton * "r" is now the address of the pte of the page 278*18215Slinton * we are interested in; get the pte and paste up the physical address. 279*18215Slinton */ 280*18215Slinton fseek(corefile, r, 0); 281*18215Slinton n = fread(&pte, sizeof(pte), 1, corefile); 282*18215Slinton if (n != 1) { 283*18215Slinton error("page table botch (fread at %x returns %d)", r, n); 284*18215Slinton } 285*18215Slinton if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) { 286*18215Slinton error("page no valid or reclamable"); 287*18215Slinton } 288*18215Slinton return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum)); 289*18215Slinton } 290*18215Slinton 2919661Slinton public coredump_readdata(buff, addr, nbytes) 2929661Slinton char *buff; 2939661Slinton Address addr; 2949661Slinton int nbytes; 2959661Slinton { 296*18215Slinton Address a; 297*18215Slinton 298*18215Slinton a = addr; 299*18215Slinton if (a < datamap.begin) { 30016608Ssam if (hdr.a_magic == OMAGIC) { 301*18215Slinton error("[data address 0x%x too low (lb = 0x%x)]", a, datamap.begin); 30216608Ssam } else { 303*18215Slinton coredump_readtext(buff, a, nbytes); 30416608Ssam } 305*18215Slinton } else if (a > stkmap.end) { 306*18215Slinton error("data address 0x%x too high (ub = 0x%x)", a, stkmap.end); 3079661Slinton } else { 308*18215Slinton if (vaddrs) { 309*18215Slinton vreadfromfile(corefile, a, buff, nbytes); 310*18215Slinton } else { 311*18215Slinton readfromfile(corefile, a, buff, nbytes); 312*18215Slinton } 3139661Slinton } 3149661Slinton } 315*18215Slinton 316*18215Slinton /* 317*18215Slinton * Read a block of data from a memory image, mapping virtual addresses. 318*18215Slinton * Have to watch out for page boundaries. 319*18215Slinton */ 320*18215Slinton 321*18215Slinton private vreadfromfile (corefile, v, buff, nbytes) 322*18215Slinton File corefile; 323*18215Slinton Address v; 324*18215Slinton char *buff; 325*18215Slinton integer nbytes; 326*18215Slinton { 327*18215Slinton Address a; 328*18215Slinton integer i, remainder, pagesize; 329*18215Slinton char *bufp; 330*18215Slinton 331*18215Slinton a = v; 332*18215Slinton pagesize = (integer) ptob(1); 333*18215Slinton remainder = pagesize - (a mod pagesize); 334*18215Slinton if (remainder >= nbytes) { 335*18215Slinton readfromfile(corefile, vmap(a), buff, nbytes); 336*18215Slinton } else { 337*18215Slinton readfromfile(corefile, vmap(a), buff, remainder); 338*18215Slinton a += remainder; 339*18215Slinton i = nbytes - remainder; 340*18215Slinton bufp = buff + remainder; 341*18215Slinton while (i > pagesize) { 342*18215Slinton readfromfile(corefile, vmap(a), bufp, pagesize); 343*18215Slinton a += pagesize; 344*18215Slinton bufp += pagesize; 345*18215Slinton i -= pagesize; 346*18215Slinton } 347*18215Slinton readfromfile(corefile, vmap(a), bufp, i); 348*18215Slinton } 349*18215Slinton } 350*18215Slinton 351*18215Slinton private readfromfile (f, a, buff, nbytes) 352*18215Slinton File f; 353*18215Slinton Address a; 354*18215Slinton char *buff; 355*18215Slinton integer nbytes; 356*18215Slinton { 357*18215Slinton integer fileaddr; 358*18215Slinton 359*18215Slinton if (a < stkmap.begin) { 360*18215Slinton fileaddr = datamap.seekaddr + a - datamap.begin; 361*18215Slinton } else { 362*18215Slinton fileaddr = stkmap.seekaddr + a - stkmap.begin; 363*18215Slinton } 364*18215Slinton fseek(f, fileaddr, 0); 365*18215Slinton fread(buff, nbytes, sizeof(Byte), f); 366*18215Slinton } 367