Annotation of researchv10no/cmd/adb/seq/mchframe.c, revision 1.1.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.