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: }

Defined functions

copyregs defined in line 113; used 1 times
coredump_close defined in line 203; used 1 times
coredump_getkerinfo defined in line 84; used 1 times
coredump_readdata defined in line 297; used 2 times
coredump_readtext defined in line 208; used 2 times
coredump_xreadin defined in line 138; used 1 times
  • in line 32
getpcb defined in line 58; used 1 times
readfromfile defined in line 357; used 5 times
vmap defined in line 225; used 5 times
vreadfromfile defined in line 327; used 1 times

Defined variables

hdr defined in line 47; used 8 times
masterpcbb defined in line 53; used 4 times
pcb defined in line 56; used 26 times
rcsid defined in line 11; never used
sbr defined in line 55; used 3 times
sccsid defined in line 8; never used
slr defined in line 54; used 3 times

Defined macros

MAXSTKADDR defined in line 37; used 2 times
coredump_readin defined in line 32; never used
Last modified: 1985-05-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 934
Valid CSS Valid XHTML 1.0 Strict