1: /* 2: * Copyright (c) 1983 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #ifndef lint 8: static char sccsid[] = "@(#)coredump.c 5.1 (Berkeley) 5/31/85"; 9: #endif not lint 10: 11: static char rcsid[] = "$Header: coredump.c,v 1.5 84/12/26 10:38:56 linton Exp $"; 12: 13: /* 14: * Deal with the core dump anachronism. 15: */ 16: 17: #include "defs.h" 18: #include "coredump.h" 19: #include "machine.h" 20: #include "object.h" 21: #include "main.h" 22: #include <sys/param.h> 23: #include <sys/dir.h> 24: #include <machine/psl.h> 25: #include <machine/pte.h> 26: #include <sys/user.h> 27: #include <sys/vm.h> 28: #include <machine/reg.h> 29: #include <a.out.h> 30: 31: #ifndef public 32: #define coredump_readin(m, r, s) coredump_xreadin(&(m), r, &(s)) 33: 34: #include "machine.h" 35: #endif 36: 37: #define MAXSTKADDR (0x80000000 - ctob(UPAGES)) /* highest stack address */ 38: 39: typedef struct { 40: Address begin; 41: Address end; 42: Address seekaddr; 43: } Map; 44: 45: private Map datamap, stkmap; 46: private File objfile; 47: private struct exec hdr; 48: 49: /* 50: * Special variables for debugging the kernel. 51: */ 52: 53: private integer masterpcbb; 54: private integer slr; 55: private struct pte *sbr; 56: private struct pcb pcb; 57: 58: private getpcb () 59: { 60: fseek(corefile, masterpcbb & ~0x80000000, 0); 61: get(corefile, pcb); 62: pcb.pcb_p0lr &= ~AST_CLR; 63: printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n", 64: pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr 65: ); 66: setreg(0, pcb.pcb_r0); 67: setreg(1, pcb.pcb_r1); 68: setreg(2, pcb.pcb_r2); 69: setreg(3, pcb.pcb_r3); 70: setreg(4, pcb.pcb_r4); 71: setreg(5, pcb.pcb_r5); 72: setreg(6, pcb.pcb_r6); 73: setreg(7, pcb.pcb_r7); 74: setreg(8, pcb.pcb_r8); 75: setreg(9, pcb.pcb_r9); 76: setreg(10, pcb.pcb_r10); 77: setreg(11, pcb.pcb_r11); 78: setreg(ARGP, pcb.pcb_ap); 79: setreg(FRP, pcb.pcb_fp); 80: setreg(STKP, pcb.pcb_ksp); 81: setreg(PROGCTR, pcb.pcb_pc); 82: } 83: 84: public coredump_getkerinfo () 85: { 86: Symbol s; 87: 88: s = lookup(identname("Sysmap", true)); 89: if (s == nil) { 90: panic("can't find 'Sysmap'"); 91: } 92: sbr = (struct pte *) (s->symvalue.offset); 93: s = lookup(identname("Syssize", true)); 94: if (s == nil) { 95: panic("can't find 'Syssize'"); 96: } 97: slr = (integer) (s->symvalue.offset); 98: printf("sbr %lx slr %lx\n", sbr, slr); 99: s = lookup(identname("masterpaddr", true)); 100: if (s == nil) { 101: panic("can't find 'masterpaddr'"); 102: } 103: fseek( 104: corefile, 105: datamap.seekaddr + s->symvalue.offset&0x7fffffff - datamap.begin, 106: 0 107: ); 108: get(corefile, masterpcbb); 109: masterpcbb = (masterpcbb&PG_PFNUM)*512; 110: getpcb(); 111: } 112: 113: private copyregs (savreg, reg) 114: Word savreg[], reg[]; 115: { 116: reg[0] = savreg[R0]; 117: reg[1] = savreg[R1]; 118: reg[2] = savreg[R2]; 119: reg[3] = savreg[R3]; 120: reg[4] = savreg[R4]; 121: reg[5] = savreg[R5]; 122: reg[6] = savreg[R6]; 123: reg[7] = savreg[R7]; 124: reg[8] = savreg[R8]; 125: reg[9] = savreg[R9]; 126: reg[10] = savreg[R10]; 127: reg[11] = savreg[R11]; 128: reg[ARGP] = savreg[AP]; 129: reg[FRP] = savreg[FP]; 130: reg[STKP] = savreg[SP]; 131: reg[PROGCTR] = savreg[PC]; 132: } 133: 134: /* 135: * Read the user area information from the core dump. 136: */ 137: 138: public coredump_xreadin(mask, reg, signo) 139: int *mask; 140: Word reg[]; 141: int *signo; 142: { 143: register struct user *up; 144: register Word *savreg; 145: union { 146: struct user u; 147: char dummy[ctob(UPAGES)]; 148: } ustruct; 149: Symbol s; 150: 151: objfile = fopen(objname, "r"); 152: if (objfile == nil) { 153: fatal("can't read \"%s\"", objname); 154: } 155: get(objfile, hdr); 156: if (vaddrs) { 157: datamap.begin = 0; 158: datamap.end = 0xffffffff; 159: stkmap.begin = 0xffffffff; 160: stkmap.end = 0xffffffff; 161: } else { 162: up = &(ustruct.u); 163: fread(up, ctob(UPAGES), 1, corefile); 164: savreg = (Word *) &(ustruct.dummy[ctob(UPAGES)]); 165: *mask = savreg[PS]; 166: copyregs(savreg, reg); 167: *signo = up->u_arg[0]; 168: datamap.seekaddr = ctob(UPAGES); 169: stkmap.begin = MAXSTKADDR - ctob(up->u_ssize); 170: stkmap.end = MAXSTKADDR; 171: stkmap.seekaddr = datamap.seekaddr + ctob(up->u_dsize); 172: switch (hdr.a_magic) { 173: case OMAGIC: 174: datamap.begin = 0; 175: datamap.end = ctob(up->u_tsize) + ctob(up->u_dsize); 176: break; 177: 178: case NMAGIC: 179: case ZMAGIC: 180: datamap.begin = (Address) ptob(btop(ctob(up->u_tsize) - 1) + 1); 181: datamap.end = datamap.begin + ctob(up->u_dsize); 182: break; 183: 184: default: 185: fatal("bad magic number 0x%x", hdr.a_magic); 186: } 187: #ifdef UXMAG 188: /* 189: * Core dump not from this object file? 190: */ 191: if (hdr.a_magic != 0 and up->u_exdata.ux_mag != 0 and 192: hdr.a_magic != up->u_exdata.ux_mag) { 193: warning("core dump ignored"); 194: coredump = false; 195: fclose(corefile); 196: fclose(objfile); 197: start(nil, nil, nil); 198: } 199: #endif 200: } 201: } 202: 203: public coredump_close() 204: { 205: fclose(objfile); 206: } 207: 208: public coredump_readtext(buff, addr, nbytes) 209: char *buff; 210: Address addr; 211: int nbytes; 212: { 213: if (hdr.a_magic == OMAGIC or vaddrs) { 214: coredump_readdata(buff, addr, nbytes); 215: } else { 216: fseek(objfile, N_TXTOFF(hdr) + addr, 0); 217: fread(buff, nbytes, sizeof(Byte), objfile); 218: } 219: } 220: 221: /* 222: * Map a virtual address to a physical address. 223: */ 224: 225: private Address vmap (addr) 226: Address addr; 227: { 228: Address r; 229: integer v, n; 230: struct pte pte; 231: 232: r = addr & ~0xc0000000; 233: v = btop(r); 234: switch (addr&0xc0000000) { 235: case 0xc0000000: 236: case 0x80000000: 237: /* 238: * In system space, so get system pte. 239: * If it is valid or reclaimable then the physical address 240: * is the combination of its page number and the page offset 241: * of the original address. 242: */ 243: if (v >= slr) { 244: error("address %x out of segment", addr); 245: } 246: r = ((long) (sbr + v)) & ~0x80000000; 247: goto simple; 248: 249: case 0x40000000: 250: /* 251: * In p1 space, must not be in shadow region. 252: */ 253: if (v < pcb.pcb_p1lr) { 254: error("address %x out of segment", addr); 255: } 256: r = (Address) (pcb.pcb_p1br + v); 257: break; 258: 259: case 0x00000000: 260: /* 261: * In p0 space, must not be off end of region. 262: */ 263: if (v >= pcb.pcb_p0lr) { 264: error("address %x out of segment", addr); 265: } 266: r = (Address) (pcb.pcb_p0br + v); 267: break; 268: 269: default: 270: /* do nothing */ 271: break; 272: } 273: /* 274: * For p0/p1 address, user-level page table should be in 275: * kernel virtual memory. Do second-level indirect by recursing. 276: */ 277: if ((r & 0x80000000) == 0) { 278: error("bad p0br or p1br in pcb"); 279: } 280: r = vmap(r); 281: simple: 282: /* 283: * "r" is now the address of the pte of the page 284: * we are interested in; get the pte and paste up the physical address. 285: */ 286: fseek(corefile, r, 0); 287: n = fread(&pte, sizeof(pte), 1, corefile); 288: if (n != 1) { 289: error("page table botch (fread at %x returns %d)", r, n); 290: } 291: if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) { 292: error("page no valid or reclamable"); 293: } 294: return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum)); 295: } 296: 297: public coredump_readdata(buff, addr, nbytes) 298: char *buff; 299: Address addr; 300: int nbytes; 301: { 302: Address a; 303: 304: a = addr; 305: if (a < datamap.begin) { 306: if (hdr.a_magic == OMAGIC) { 307: error("[data address 0x%x too low (lb = 0x%x)]", a, datamap.begin); 308: } else { 309: coredump_readtext(buff, a, nbytes); 310: } 311: } else if (a > stkmap.end) { 312: error("data address 0x%x too high (ub = 0x%x)", a, stkmap.end); 313: } else { 314: if (vaddrs) { 315: vreadfromfile(corefile, a, buff, nbytes); 316: } else { 317: readfromfile(corefile, a, buff, nbytes); 318: } 319: } 320: } 321: 322: /* 323: * Read a block of data from a memory image, mapping virtual addresses. 324: * Have to watch out for page boundaries. 325: */ 326: 327: private vreadfromfile (corefile, v, buff, nbytes) 328: File corefile; 329: Address v; 330: char *buff; 331: integer nbytes; 332: { 333: Address a; 334: integer i, remainder, pagesize; 335: char *bufp; 336: 337: a = v; 338: pagesize = (integer) ptob(1); 339: remainder = pagesize - (a mod pagesize); 340: if (remainder >= nbytes) { 341: readfromfile(corefile, vmap(a), buff, nbytes); 342: } else { 343: readfromfile(corefile, vmap(a), buff, remainder); 344: a += remainder; 345: i = nbytes - remainder; 346: bufp = buff + remainder; 347: while (i > pagesize) { 348: readfromfile(corefile, vmap(a), bufp, pagesize); 349: a += pagesize; 350: bufp += pagesize; 351: i -= pagesize; 352: } 353: readfromfile(corefile, vmap(a), bufp, i); 354: } 355: } 356: 357: private readfromfile (f, a, buff, nbytes) 358: File f; 359: Address a; 360: char *buff; 361: integer nbytes; 362: { 363: integer fileaddr; 364: 365: if (a < stkmap.begin) { 366: fileaddr = datamap.seekaddr + a - datamap.begin; 367: } else { 368: fileaddr = stkmap.seekaddr + a - stkmap.begin; 369: } 370: fseek(f, fileaddr, 0); 371: fread(buff, nbytes, sizeof(Byte), f); 372: }