|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.