Annotation of researchv10no/cmd/adb/seq/mchframe.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * machine-dependent code for
        !             3:  * looking in stack frames
        !             4:  * sequent/32032 version
        !             5:  */
        !             6: 
        !             7: #include "defs.h"
        !             8: #include "space.h"
        !             9: #include <sys/param.h>
        !            10: #include "regs.h"
        !            11: #include <a.out.h>
        !            12: #include "sym.h"
        !            13: #include <signal.h>
        !            14: 
        !            15: int maxargs = 20;
        !            16: 
        !            17: /*
        !            18:  * stuff in the stack frame
        !            19:  */
        !            20: 
        !            21: #define        F_HACKPC 48     /* signal handler hack */
        !            22: #define        F_ARG1  8       /* first argument */
        !            23: #define        F_PC    4
        !            24: #define        F_FP    0
        !            25: 
        !            26: /*
        !            27:  * how to find out the number of arguments to a procedure call:
        !            28:  * look at the instruction after the call (cxp)
        !            29:  * it should be an adjspb with an immediate operand
        !            30:  * the operand (the following byte) is the (negative) number of
        !            31:  * bytes to be popped off the stack after the call;
        !            32:  * i.e. the amount of space taken by parameters
        !            33:  */
        !            34: 
        !            35: #define        adjspbi(x)      (((x) & 0xffff) == 0xa57c)
        !            36: #define        adjoff(x)       ((((x) & 0xff0000) >> 16) | 0xffffff00)
        !            37: 
        !            38: /*
        !            39:  * return an address for a local variable
        !            40:  * no register vars, unfortunately, as we can't provide an address
        !            41:  * gn is the procedure; ln the local name
        !            42:  */
        !            43: 
        !            44: extern WORD expv;
        !            45: extern int expsp;
        !            46: 
        !            47: localaddr(gn, ln)
        !            48: char *gn, *ln;
        !            49: {
        !            50:        WORD fp;
        !            51:        ADDR laddr();
        !            52: 
        !            53:        if (gn) {
        !            54:                if (findrtn(gn) == 0)
        !            55:                        error("function not found");
        !            56:        }
        !            57:        else {
        !            58:                findsym((WORD)atow(rget(PC)), INSTSP);
        !            59:                if (cursym == NULL)
        !            60:                        error("function not found");
        !            61:        }
        !            62:        if (findframe(&fp) == 0)
        !            63:                error("function not found");
        !            64:        if (ln == NULL) {
        !            65:                expsp = 0;
        !            66:                expv = fp;
        !            67:                return;
        !            68:        }
        !            69:        while (localsym()) {
        !            70:                if (strcmp(ln, cursym->y_name) != 0)
        !            71:                        continue;
        !            72:                expv = laddr(cursym, fp, fp + F_ARG1);
        !            73:                if (cursym->y_ltype == S_RSYM)
        !            74:                        expsp = REGSP;
        !            75:                else
        !            76:                        expsp = NOSP;
        !            77:                return;
        !            78:        }
        !            79:        error("local var not found");
        !            80:        /* NOTREACHED */
        !            81: }
        !            82: 
        !            83: /*
        !            84:  * print a stack traceback
        !            85:  * give locals if possible
        !            86:  */
        !            87: 
        !            88: ctrace(modif)
        !            89: char modif;
        !            90: {
        !            91:        register ADDR fp, ap, callpc;
        !            92:        register int narg;
        !            93:        ADDR ofp;
        !            94:        ADDR newpc;
        !            95:        WORD w;
        !            96: 
        !            97:        if (adrflg) {
        !            98:                fp = adrval;
        !            99:                callpc = atow(aget(fp + F_PC, CORF|DATASP));
        !           100:        } else {
        !           101:                fp = (ADDR)rtow(rget(FP));
        !           102:                callpc = (ADDR)rtow(rget(PC));
        !           103:        }
        !           104:        clrraddr();
        !           105:        ofp = fp;
        !           106:        while (cntval--) {
        !           107:                chkerr();
        !           108:                findsym(callpc, INSTSP);
        !           109:                if (cursym == NULL)
        !           110:                        printf("?(");
        !           111:                else if (strcmp("start", cursym->y_name) == 0)
        !           112:                        break;
        !           113:                else
        !           114:                        printf("%s(", cursym->y_name);
        !           115:                if (strcmp("sigcode", cursym->y_name) == 0) {
        !           116:                        printf(") from %R\n", callpc);
        !           117:                        callpc = ltow(lget(ofp + F_HACKPC, CORF|DATASP));
        !           118:                        /* ignore saved r0 r1 r2 for now */
        !           119:                        continue;
        !           120:                }
        !           121:                newpc = atow(aget(fp + F_PC, CORF|DATASP));
        !           122:                w = ltow(lget(newpc, SYMF|INSTSP));
        !           123:                if (!adjspbi(w))
        !           124:                        narg = 0;
        !           125:                else
        !           126:                        narg = -adjoff(w)/4;
        !           127:                for (ap = fp + F_ARG1; --narg >= 0; ap += SZREG) {
        !           128:                        printf("%R", ltow(lget(ap, CORF|DATASP)));
        !           129:                        if (narg != 0)
        !           130:                                printc(',');
        !           131:                }
        !           132:                printf(") from %R\n", callpc);
        !           133:                if (modif == 'C')
        !           134:                        locals(fp, fp + F_ARG1);
        !           135:                setraddr(callpc, fp);
        !           136:                callpc = newpc;
        !           137:                ofp = fp;
        !           138:                fp = atow(aget(fp + F_FP, CORF|DATASP));
        !           139:                if (fp == 0)
        !           140:                        break;
        !           141:        }
        !           142:        clrraddr();
        !           143: }
        !           144: 
        !           145: static
        !           146: locals(fp, ap)
        !           147: ADDR fp, ap;
        !           148: {
        !           149:        WORD val;
        !           150:        register int sp;
        !           151:        ADDR laddr();
        !           152: 
        !           153:        while (localsym()) {
        !           154:                sp = CORF | DATASP;
        !           155:                if (cursym->y_ltype == S_RSYM)
        !           156:                        sp = CORF | REGSP;
        !           157:                val = ltow(lget(laddr(cursym, fp, ap), sp));
        !           158:                if (errflg == 0)
        !           159:                        printf("%8t%s/%10t%R\n", cursym->y_name, val);
        !           160:                else {
        !           161:                        printf("%8t%s/%10t?\n", cursym->y_name);
        !           162:                        errflg = 0;
        !           163:                }
        !           164:        }
        !           165: }
        !           166: 
        !           167: ADDR
        !           168: laddr(sp, fp, ap)
        !           169: struct sym *sp;
        !           170: ADDR fp, ap;
        !           171: {
        !           172: 
        !           173:        switch (sp->y_ltype) {
        !           174:        case S_STSYM:
        !           175:                return (sp->y_value);
        !           176: 
        !           177:        case S_LSYM:
        !           178:                return (fp - sp->y_value);
        !           179: 
        !           180:        case S_PSYM:
        !           181:                return (ap + sp->y_value);
        !           182: 
        !           183:        case S_RSYM:
        !           184:                return (sp->y_value * SZREG);
        !           185:        }
        !           186:        error("bad local symbol");
        !           187:        /* NOTREACHED */
        !           188: }
        !           189: 
        !           190: int
        !           191: findframe(fpp)
        !           192: ADDR *fpp;
        !           193: {
        !           194:        register ADDR fp, pc;
        !           195:        struct sym *svcur;
        !           196: 
        !           197:        svcur = cursym;
        !           198:        fp = rtow(rget(FP));
        !           199:        pc = rtow(rget(PC));
        !           200:        if (errflg)
        !           201:                return (0);
        !           202:        clrraddr();
        !           203:        for (;;) {
        !           204:                findsym(pc, INSTSP);
        !           205:                if (cursym == svcur)
        !           206:                        break;
        !           207:                if (cursym && strcmp(cursym->y_name, "start") == 0) {
        !           208:                        clrraddr();
        !           209:                        return (0);
        !           210:                }
        !           211:                setraddr(cursym->y_value, fp);
        !           212:                pc = atow(aget(fp + F_PC, CORF|DATASP));
        !           213:                fp = atow(aget(fp + F_FP, CORF|DATASP));
        !           214:                /* sigtramp? */
        !           215:                if (errflg) {
        !           216:                        clrraddr();
        !           217:                        return (0);
        !           218:                }
        !           219:        }
        !           220:        *fpp = fp;
        !           221:        return (1);
        !           222: }
        !           223: 
        !           224: /*
        !           225:  * set addresses for saved registers for this frame
        !           226:  * the mask is that from an `enter' instruction
        !           227:  */
        !           228: 
        !           229: extern ADDR raddr[];
        !           230: 
        !           231: setraddr(pc, fp)
        !           232: ADDR pc;
        !           233: register ADDR fp;
        !           234: {
        !           235:        register int r;
        !           236:        register int i;
        !           237:        int roff;
        !           238:        register int mask;
        !           239: 
        !           240:        if ((mask = regmask(pc, &roff)) == 0)
        !           241:                return;
        !           242:        fp += roff;
        !           243:        for (r = 7, i = 0; mask; r--)
        !           244:                if (mask & (1 << r)) {
        !           245:                        if (MINREG <= r && r <= MAXREG)
        !           246:                                raddr[r - MINREG] = fp + i * SZREG;
        !           247:                        i++;
        !           248:                        mask &=~ (1 << r);
        !           249:                }
        !           250: }
        !           251: 
        !           252: clrraddr()
        !           253: {
        !           254:        register int i;
        !           255: 
        !           256:        for (i = 0; i <= MAXREG - MINREG; i++)
        !           257:                raddr[i] = 0;
        !           258: }
        !           259: 
        !           260: /*
        !           261:  * find the mask of saved registers for this routine
        !           262:  *
        !           263:  * pc is the entry point.
        !           264:  * if the code was run through c2, the first instruction will be `enter';
        !           265:  * grab the mask.
        !           266:  * set *rp to the number of bytes of local storage on the stack
        !           267:  * (the registers are pushed AFTER local storage)
        !           268:  * if it wasn't put through c2, the first instruction will be a branch.
        !           269:  * the instruction branched to will be the `enter.'
        !           270:  *
        !           271:  * awful but how else to do it?
        !           272:  */
        !           273: 
        !           274: #define        enter(w)        (((w)&0xff) == 0x82)
        !           275: #define        entmsk(w)       (((w)>>8) & 0xff)
        !           276: #define        br(w)           (((w)&0xff) == 0xea)
        !           277: 
        !           278: int
        !           279: regmask(pc, rp)
        !           280: ADDR pc;
        !           281: int *rp;
        !           282: {
        !           283:        register WORD w;
        !           284:        long disp();
        !           285: 
        !           286:        *rp = 0;
        !           287:        w = ltow(lget(pc, SYMF|INSTSP));
        !           288:        if (enter(w)) {
        !           289:                *rp = disp(pc + 2);
        !           290:                return (entmsk(w));
        !           291:        }
        !           292:        if (!br(w))
        !           293:                return (0);
        !           294:        w = ltow(lget(pc + disp(pc + 1), SYMF|INSTSP));
        !           295:        if (enter(w))
        !           296:                return (entmsk(w));
        !           297:        return (0);
        !           298: }
        !           299: 
        !           300: static
        !           301: disp(pc)
        !           302: ADDR pc;
        !           303: {
        !           304:        register WORD w;
        !           305: 
        !           306:        w = ltow(lget(pc, SYMF|INSTSP));
        !           307:        if ((w & 0x80) == 0) {
        !           308:                w &= 0x7f;
        !           309:                if (w & 0x40)
        !           310:                        w |= 0xffffffc0;
        !           311:        }
        !           312:        else if ((w & 0x40) == 0) {
        !           313:                w = ((w << 8) & 0x3f00) | ((w >> 8) & 0xff);
        !           314:                if (w & 0x2000)
        !           315:                        w |= 0xffffc000;
        !           316:        }
        !           317:        else {
        !           318:                w = ((w << 24) & 0x3f000000)
        !           319:                  | ((w << 8)  & 0xff0000)
        !           320:                  | ((w >> 8)  & 0xff00)
        !           321:                  | ((w >> 24) & 0xff);
        !           322:                if (w & 0x20000000)
        !           323:                        w |= 0xc0000000;
        !           324:        }
        !           325:        return (w);
        !           326: }

unix.superglobalmegacorp.com

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