Annotation of 43BSD/ucb/dbx/coredump.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.