Annotation of 43BSD/bin/adb/setup.c, revision 1.1.1.1

1.1       root        1: static char sccsid[] = "@(#)setup.c    4.10 (Berkeley) 85/05/09";
                      2: /*
                      3:  * adb - routines to read a.out+core at startup
                      4:  */
                      5: #include "defs.h"
                      6: #include <frame.h>
                      7: #include <ctype.h>
                      8: #include <sys/stat.h>
                      9: #include <sys/file.h>
                     10: #include <vax/rpb.h>
                     11: 
                     12: off_t  datbas;                 /* offset of the base of the data segment */
                     13: off_t  stksiz;                 /* stack size in the core image */
                     14: INT    sigcode;        /* belongs in head.h */
                     15: 
                     16: char   *symfil = "a.out";
                     17: char   *corfil = "core";
                     18: 
                     19: setsym()
                     20: {
                     21:        off_t loc;
                     22:        struct exec hdr;
                     23:        register struct nlist *sp;
                     24:        int ssiz;
                     25:        char *strtab;
                     26: 
                     27:        fsym = getfile(symfil, 1);
                     28:        txtmap.ufd = fsym;
                     29:        if (read(fsym, (char *)&hdr, sizeof hdr) != sizeof hdr ||
                     30:            N_BADMAG(hdr)) {
                     31:                txtmap.e1 = MAXFILE;
                     32:                return;
                     33:        }
                     34:        filhdr = hdr;
                     35:        loc = filhdr.a_text+filhdr.a_data;
                     36:        txtmap.f1 = txtmap.f2 = N_TXTOFF(filhdr);
                     37:        txtmap.b1 = 0;
                     38:        switch (filhdr.a_magic) {
                     39: 
                     40:        case OMAGIC:
                     41:                txtmap.b1 = txtmap.e1 = 0;
                     42:                txtmap.b2 = datbas = 0;
                     43:                txtmap.e2 = loc;
                     44:                break;
                     45: 
                     46:        case ZMAGIC:
                     47:        case NMAGIC:
                     48:                txtmap.e1 = filhdr.a_text;
                     49:                txtmap.b2 = datbas = round(filhdr.a_text, PAGSIZ);
                     50:                txtmap.e2 = datbas + filhdr.a_data;
                     51:                txtmap.f2 += txtmap.e1;
                     52:        }
                     53:        loc = N_SYMOFF(filhdr);
                     54:        symtab = (struct nlist *) malloc(filhdr.a_syms);
                     55:        esymtab = &symtab[filhdr.a_syms / sizeof (struct nlist)];
                     56:        if (symtab == NULL)
                     57:                goto nospac;
                     58:        lseek(fsym, loc, L_SET);
                     59:        if (filhdr.a_syms == 0)
                     60:                goto nosymt;
                     61:        /* SHOULD SQUISH OUT STABS HERE!!! */
                     62:        if (read(fsym, symtab, filhdr.a_syms) != filhdr.a_syms)
                     63:                goto readerr;
                     64:        if (read(fsym, &ssiz, sizeof (ssiz)) != sizeof (ssiz))
                     65:                goto oldfmt;
                     66:        strtab = (char *) malloc(ssiz);
                     67:        if (strtab == 0)
                     68:                goto nospac;
                     69:        *(int *)strtab = ssiz;
                     70:        ssiz -= sizeof (ssiz);
                     71:        if (read(fsym, strtab + sizeof (ssiz), ssiz) != ssiz)
                     72:                goto readerr;
                     73:        for (sp = symtab; sp < esymtab; sp++)
                     74:                if (sp->n_strx)
                     75:                        /* SHOULD PERFORM RANGE CHECK HERE */
                     76:                        sp->n_un.n_name = strtab + sp->n_un.n_strx;
                     77: nosymt:
                     78:        if (INKERNEL(filhdr.a_entry)) {
                     79:                txtmap.b1 += KERNOFF;
                     80:                txtmap.e1 += KERNOFF;
                     81:                txtmap.b2 += KERNOFF;
                     82:                txtmap.e2 += KERNOFF;
                     83:        }
                     84:        return;
                     85: readerr:
                     86:        printf("Error reading symbol|string table\n");
                     87:        exit(1);
                     88: nospac:
                     89:        printf("Not enough space for symbol|string table\n");
                     90:        exit(1);
                     91: oldfmt:
                     92:        printf("Old format a.out - no string table\n");
                     93:        exit(1);
                     94: }
                     95: 
                     96: setcor()
                     97: {
                     98: 
                     99:        fcor = datmap.ufd = getfile(corfil,2);
                    100:        if (kernel && fcor != -1 && INKERNEL(filhdr.a_entry)) {
                    101:                struct stat stb;
                    102: 
                    103:                kcore = 1;
                    104:                fstat(fcor, &stb);
                    105:                datmap.b1 = 0;
                    106:                datmap.e1 = -1;
                    107:                if (kernel == 0 && (stb.st_mode & S_IFREG))
                    108:                        datmap.b1 = 0x80000000;
                    109:                lookup("_Sysmap");
                    110:                sbr = cursym->n_value;
                    111:                lookup("_Syssize");
                    112:                slr = cursym->n_value;
                    113:                printf("sbr %x slr %x\n", sbr, slr);
                    114:                lookup("_masterpaddr");
                    115:                physrw(fcor, KVTOPH(cursym->n_value), &masterpcbb, 1);
                    116:                masterpcbb = (masterpcbb&PG_PFNUM)*NBPG;
                    117:                getpcb();
                    118:                findstackframe();
                    119:                return;
                    120:        }
                    121:        if (read(fcor, (char *)&u, ctob(UPAGES))!=ctob(UPAGES) ||
                    122:           !INUDOT(u.u_pcb.pcb_ksp) || !INSTACK(u.u_pcb.pcb_usp)) {
                    123:                datmap.e1 = MAXFILE;
                    124:                return;
                    125:        }
                    126:        signo = u.u_arg[0];
                    127:        sigcode = u.u_code;
                    128:        filhdr.a_text = ctob(u.u_tsize);
                    129:        filhdr.a_data = ctob(u.u_dsize);
                    130:        stksiz = ctob(u.u_ssize);
                    131:        switch (filhdr.a_magic) {
                    132: 
                    133:        case OMAGIC:
                    134:                datmap.b1 = 0;
                    135:                datmap.e1 = filhdr.a_text+filhdr.a_data;
                    136:                datmap.f2 = ctob(UPAGES) + datmap.e1;
                    137:                break;
                    138: 
                    139:        case NMAGIC:
                    140:        case ZMAGIC:
                    141:                datmap.b1 = round(filhdr.a_text, PAGSIZ);
                    142:                datmap.e1 = datmap.b1 + filhdr.a_data;
                    143:                datmap.f2 = ctob(UPAGES) + filhdr.a_data;
                    144:                break;
                    145:        }
                    146:        datbas = datmap.b1;
                    147:        datmap.f1 = ctob(UPAGES);
                    148:        datmap.b2 = MAXSTOR - stksiz;
                    149:        datmap.e2 = MAXSTOR;
                    150: }
                    151: 
                    152: getpcb()
                    153: {
                    154: 
                    155:        lseek(fcor, KVTOPH(masterpcbb), L_SET);
                    156:        read(fcor, &pcb, sizeof (struct pcb));
                    157:        pcb.pcb_p0lr &= ~AST_CLR;
                    158:        printf("p0br %x p0lr %x p1br %x p1lr %x\n",
                    159:            pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr);
                    160: }
                    161: 
                    162: caddr_t        rpb, scb;
                    163: caddr_t        intstack, eintstack;
                    164: caddr_t        ustack, eustack;
                    165: struct frame *getframe();
                    166: struct frame *checkintstack();
                    167: 
                    168: /*
                    169:  * Find the current stack frame when debugging the kernel.
                    170:  * If we're looking at a crash dump and this was not a ``clean''
                    171:  * crash, then we must search the interrupt stack carefully
                    172:  * looking for a valid frame.
                    173:  */
                    174: findstackframe()
                    175: {
                    176:        char *panicstr, buf[256];
                    177:        register struct frame *fp;
                    178:        caddr_t addr;
                    179:        register char *cp;
                    180:        int mask;
                    181: 
                    182:        if (lookup("_panicstr") == 0)
                    183:                return;
                    184:        lseek(fcor, KVTOPH(cursym->n_value), L_SET);
                    185:        read(fcor, &panicstr, sizeof (panicstr));
                    186:        if (panicstr == 0)
                    187:                return;
                    188:        lseek(fcor, KVTOPH((off_t)panicstr), L_SET);
                    189:        read(fcor, buf, sizeof (buf));
                    190:        for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++)
                    191:                if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp)))
                    192:                        *cp = '?';
                    193:        if (*cp)
                    194:                *cp = '\0';
                    195:        printf("panic: %s\n", buf);
                    196:        /*
                    197:         * After a panic, look at the top of the rpb stack to
                    198:         * find a stack frame.  If this was a clean crash,
                    199:         * i.e. one which left the interrupt and kernel stacks
                    200:         * in a reasonable state, then we should find a pointer
                    201:         * to the proper stack frame here (at location scb-4).
                    202:         * If we don't find a reasonable frame here, then we
                    203:         * must search down through the interrupt stack.
                    204:         */
                    205:        intstack = lookup("_intstack")->n_value;
                    206: #define        NISP    3                       /* from locore.s */
                    207:        eintstack = intstack + NISP*NBPG;
                    208:        rpb = lookup("_rpb")->n_value;
                    209:        scb = lookup("_scb")->n_value;
                    210:        lookup("_u");
                    211:        ustack = cursym->n_value + (int)&((struct user *)0)->u_stack[0];
                    212:        eustack = cursym->n_value + ctob(UPAGES);
                    213:        physrw(fcor, KVTOPH((int)scb - sizeof (caddr_t)), &addr, 1);
                    214:        fp = getframe(fcor, addr);
                    215:        if (fp == 0)
                    216:                fp = checkintstack();
                    217:        /* search kernel stack? */
                    218:        if (fp == 0) {
                    219:                printf("can't locate stack frame\n");
                    220:                return;
                    221:        }
                    222:        /* probably shouldn't clobber pcb, but for now this is easy */
                    223:        pcb.pcb_fp = addr;
                    224:        pcb.pcb_pc = fp->fr_savpc;
                    225:        pcb.pcb_ap = addr + sizeof (struct frame) + fp->fr_spa;
                    226:        for (mask = fp->fr_mask; mask; mask >>= 1)
                    227:                if (mask & 01)
                    228:                        pcb.pcb_ap += sizeof (caddr_t);
                    229: }
                    230: 
                    231: /*
                    232:  * Search interrupt stack for a valid frame.
                    233:  */
                    234: struct frame *
                    235: checkintstack(fcor)
                    236: {
                    237:        char stack[NISP*NBPG];
                    238:        off_t off = vtophys(intstack);
                    239:        struct frame *fp;
                    240:        register caddr_t addr;
                    241: 
                    242:        if (off == -1 || lseek(fcor, off, L_SET) != off ||
                    243:            read(fcor, stack, sizeof (stack)) != sizeof (stack))
                    244:                return ((struct frame *)0);
                    245:        addr = eintstack;
                    246:        do {
                    247:                addr -= sizeof (caddr_t);
                    248:                fp = (struct frame *)&stack[addr - intstack];
                    249:        } while (addr >= intstack + sizeof (struct frame) &&
                    250:            !checkframe(fp));
                    251:        return (addr < intstack+sizeof (struct frame) ? (struct frame *)0 : fp);
                    252: }
                    253: 
                    254: /*
                    255:  * Get a stack frame and verify it looks like
                    256:  * something which might be on a kernel stack.
                    257:  */
                    258: struct frame *
                    259: getframe(fcor, fp)
                    260:        int fcor;
                    261:        caddr_t fp;
                    262: {
                    263:        static struct frame frame;
                    264:        off_t off;
                    265: 
                    266:        if (!kstackaddr(fp) || (off = vtophys(fp)) == -1)
                    267:                return ((struct frame *)0);
                    268:        if (lseek(fcor, off, L_SET) != off ||
                    269:            read(fcor, &frame, sizeof (frame)) != sizeof (frame))
                    270:                return ((struct frame *)0);
                    271:        if (!checkframe(&frame))
                    272:                return ((struct frame *)0);
                    273:        return (&frame);
                    274: }
                    275: 
                    276: /*
                    277:  * Check a call frame to see if it's ok as
                    278:  * a kernel stack frame.
                    279:  */
                    280: checkframe(fp)
                    281:        register struct frame *fp;
                    282: {
                    283: 
                    284:        if (fp->fr_handler != 0 || fp->fr_s == 0)
                    285:                return (0);
                    286:        if (!kstackaddr(fp->fr_savap) || !kstackaddr(fp->fr_savfp))
                    287:                return (0);
                    288:        return (within(fp->fr_savpc, txtmap.b1, txtmap.e1));
                    289: }
                    290: 
                    291: /*
                    292:  * Check if an address is in one of the kernel's stacks:
                    293:  * interrupt stack, rpb stack (during restart sequence),
                    294:  * or u. stack.
                    295:  */
                    296: kstackaddr(addr)
                    297:        caddr_t addr;
                    298: {
                    299: 
                    300:        return (within(addr, intstack, eintstack) ||
                    301:            within(addr, rpb + sizeof (struct rpb), scb) ||
                    302:            within(addr, ustack, eustack));
                    303: }
                    304: 
                    305: create(f)
                    306:        char *f;
                    307: {
                    308:        register int fd;
                    309: 
                    310:        fd = creat(f, 0644);
                    311:        if (fd < 0)
                    312:                return (-1);
                    313:        close(fd);
                    314:        return (open(f, wtflag));
                    315: }
                    316: 
                    317: getfile(filnam, cnt)
                    318:        char *filnam;
                    319: {
                    320:        register int fsym;
                    321: 
                    322:        if (eqstr(filnam, "-"))
                    323:                return (-1);
                    324:        fsym = open(filnam, wtflag);
                    325:        if (fsym < 0 && xargc > cnt) {
                    326:                if (wtflag)
                    327:                        fsym = create(filnam);
                    328:                if (fsym < 0)
                    329:                        printf("cannot open `%s'\n", filnam);
                    330:        }
                    331:        return (fsym);
                    332: }
                    333: 
                    334: setvar()
                    335: {
                    336: 
                    337:        var[varchk('b')] = datbas;
                    338:        var[varchk('d')] = filhdr.a_data;
                    339:        var[varchk('e')] = filhdr.a_entry;
                    340:        var[varchk('m')] = filhdr.a_magic;
                    341:        var[varchk('s')] = stksiz;
                    342:        var[varchk('t')] = filhdr.a_text;
                    343: }

unix.superglobalmegacorp.com

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