Annotation of 42BSD/ucb/pascal/pdx/machine/nextaddr.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1982 Regents of the University of California */
                      2: 
                      3: static char sccsid[] = "@(#)nextaddr.c 1.4 3/8/82";
                      4: 
                      5: /*
                      6:  * Calculate the next address that will be executed from the current one.
                      7:  *
                      8:  * If the next address depends on runtime data (e.g. a conditional
                      9:  * branch will depend on the value on top of the stack),
                     10:  * we must execute up to the given address with "stepto".
                     11:  *
                     12:  * If the second argument is TRUE, we treat a CALL instruction as
                     13:  * straight line rather than following it as a branch.
                     14:  */
                     15: 
                     16: #include "defs.h"
                     17: #include "machine.h"
                     18: #include "process.h"
                     19: #include "breakpoint.h"
                     20: #include "sym.h"
                     21: #include "pxops.h"
                     22: #include "optab.h"
                     23: #include "mappings.h"
                     24: #include "runtime.h"
                     25: #include "process/pxinfo.h"
                     26: #include "process/process.rep"
                     27: 
                     28: LOCAL ADDRESS docase(), dofor();
                     29: 
                     30: ADDRESS nextaddr(beginaddr, isnext)
                     31: ADDRESS beginaddr;
                     32: BOOLEAN isnext;
                     33: {
                     34:     register PXOP op;
                     35:     ADDRESS addr;
                     36:     short offset;
                     37:     int nextbyte;
                     38:     SYM *s;
                     39:     union {
                     40:        short word;
                     41:        char byte[2];
                     42:     } o;
                     43: 
                     44:     addr = beginaddr;
                     45:     iread(&o.word, addr, sizeof(o.word));
                     46:     op = (PXOP) o.byte[0];
                     47:     nextbyte = o.byte[1];
                     48:     addr += sizeof(short);
                     49:     switch(op) {
                     50: 
                     51: #   if (isvaxpx)
                     52:     /*
                     53:      * The version of px on the VAX assumes that the instruction
                     54:      * at the entry point of a function is a TRA4 to the beginning
                     55:      * of the block.
                     56:      */
                     57: #   endif
                     58:        case O_CALL: {
                     59:            ADDRESS eaddr;
                     60: 
                     61:            if (isnext) {
                     62:                addr += sizeof(int);
                     63:            } else {
                     64: #               if (isvaxpx)
                     65:                    iread(&eaddr, addr, sizeof(eaddr));
                     66:                    addr = eaddr + sizeof(short);
                     67:                    iread(&addr, addr, sizeof(addr));
                     68: #               else
                     69:                    iread(&offset, addr, sizeof(offset));
                     70:                    addr += offset;
                     71: #               endif
                     72:                stepto(addr);
                     73:                if (linelookup(addr) == 0) {
                     74:                    bpact();
                     75:                    addr = pc;
                     76:                }
                     77:                if (ss_lines && trcond()) {
                     78:                    s = whatblock(addr);
                     79:                    if (s == NIL) {
                     80:                        panic("bad call addr");
                     81:                    }
                     82:                    printentry(s);
                     83:                }
                     84:            }
                     85:            break;
                     86:        }
                     87: 
                     88: #   if (isvaxpx)
                     89:        case O_FCALL: {
                     90:            ADDRESS eaddr;
                     91:            ADDRESS *fparam;
                     92: 
                     93:            if (!isnext) {
                     94:                stepto(addr - sizeof(short));
                     95:                dread(&fparam, process->sp + sizeof(ADDRESS), sizeof(fparam));
                     96:                dread(&eaddr, fparam, sizeof(eaddr));
                     97:                addr = eaddr - ENDOFF;
                     98:                stepto(addr);
                     99:                if (linelookup(addr) == 0) {
                    100:                    bpact();
                    101:                    addr = pc;
                    102:                }
                    103:                if (ss_lines && trcond()) {
                    104:                    s = whatblock(addr);
                    105:                    if (s == NIL) {
                    106:                        panic("bad call addr");
                    107:                    }
                    108:                    printentry(s);
                    109:                }
                    110:            }
                    111:            break;
                    112:        }
                    113: #   endif
                    114: 
                    115:        case O_END:
                    116:            if ((addr - sizeof(short)) == lastaddr()) {
                    117:                stepto(addr - sizeof(short));
                    118:                endprogram();
                    119:            } else {
                    120:                addr = return_addr();
                    121:                s = whatblock(pc);
                    122:                stepto(addr);
                    123:                if (ss_lines && trcond()) {
                    124:                    printexit(s);
                    125:                }
                    126:                if (linelookup(addr) == 0) {
                    127:                    bpact();
                    128:                    addr = pc;
                    129:                }
                    130:            }
                    131:            break;
                    132: 
                    133: #   if (isvaxpx)
                    134:        case O_TRA4:
                    135:        case O_GOTO:
                    136:            iread(&addr, addr, sizeof(addr));
                    137:            break;
                    138: #   endif
                    139: 
                    140:        case O_TRA:
                    141:            iread(&offset, addr, sizeof(offset));
                    142:            addr += offset;
                    143:            break;
                    144: 
                    145:        case O_CON: {
                    146:            short consize;
                    147: 
                    148:            if (nextbyte == 0) {
                    149:                iread(&consize, addr, sizeof(consize));
                    150:                addr += sizeof(consize);
                    151:            } else {
                    152:                consize = nextbyte;
                    153:            }
                    154:            addr += consize;
                    155:            break;
                    156:        }
                    157: 
                    158:        case O_CASE1OP:
                    159:            addr = docase(nextbyte, 1, addr);
                    160:            break;
                    161: 
                    162:        case O_CASE2OP:
                    163:            addr = docase(nextbyte, 2, addr);
                    164:            break;
                    165: 
                    166:        case O_CASE4OP:
                    167:            addr = docase(nextbyte, 4, addr);
                    168:            break;
                    169: 
                    170:        case O_FOR1U:
                    171:            addr = dofor(2, addr, nextbyte, 1);
                    172:            break;
                    173: 
                    174:        case O_FOR2U:
                    175:            addr = dofor(2, addr, nextbyte, 1);
                    176:            break;
                    177: 
                    178:        case O_FOR4U:
                    179:            addr = dofor(4, addr, nextbyte, 1);
                    180:            break;
                    181: 
                    182:        case O_FOR1D:
                    183:            addr = dofor(2, addr, nextbyte, -1);
                    184:            break;
                    185: 
                    186:        case O_FOR2D:
                    187:            addr = dofor(2, addr, nextbyte, -1);
                    188:            break;
                    189: 
                    190:        case O_FOR4D:
                    191:            addr = dofor(4, addr, nextbyte, -1);
                    192:            break;
                    193: 
                    194:        case O_IF:
                    195:            stepto(addr - sizeof(short));
                    196:            dread(&offset, process->sp, sizeof(offset));
                    197:            if (offset == 0) {
                    198:                iread(&offset, addr, sizeof(offset));
                    199:                addr += offset;
                    200:            } else {
                    201:                addr += sizeof(offset);
                    202:            }
                    203:            break;
                    204: 
                    205:        default: {
                    206: #   if (isvaxpx)
                    207:            int i;
                    208: 
                    209:            for (i = 0; optab[op].argtype[i] != 0; i++) {
                    210:                switch(optab[op].argtype[i]) {
                    211:                    case ADDR4:
                    212:                    case LWORD:
                    213:                        addr += 4;
                    214:                        break;
                    215: 
                    216:                    case SUBOP:
                    217:                        break;
                    218: 
                    219:                    case ADDR2:
                    220:                    case HWORD:
                    221:                    case PSUBOP:
                    222:                    case DISP:
                    223:                    case VLEN:
                    224:                        if (i != 0 || nextbyte == 0) {
                    225:                            addr += sizeof(short);
                    226:                        }
                    227:                        break;
                    228: 
                    229:                    case STRING: {
                    230:                        char c;
                    231: 
                    232:                        while (nextbyte > 0) {
                    233:                            iread(&c, addr, 1);
                    234:                            if (c == '\0') {
                    235:                                break;
                    236:                            }
                    237:                            nextbyte--;
                    238:                            addr++;
                    239:                        }
                    240:                        addr++;
                    241:                        if ((addr&1) != 0) {
                    242:                            addr++;
                    243:                        }
                    244:                        break;
                    245:                    }
                    246: 
                    247:                    default:
                    248:                        panic("bad argtype");
                    249:                        /*NOTREACHED*/
                    250:                }
                    251:            }
                    252: #   else
                    253:            int oplen;
                    254: 
                    255:            oplen = optab[op].nargs;
                    256:            if (oplen < 0) {
                    257:                oplen = (-oplen) - 1;
                    258:            } else  if (oplen > 0 && nextbyte != 0) {
                    259:                oplen--;
                    260:            }
                    261:            oplen *= sizeof(int);
                    262:            switch (op) {
                    263:                case O_BEG:
                    264:                case O_NODUMP:
                    265:                    oplen += 10;
                    266:                    break;
                    267: 
                    268:                case O_CON:
                    269:                    oplen += ((nextbyte + 1)&~1);
                    270:                    break;
                    271:            }
                    272:            addr += oplen;
                    273: #   endif
                    274:            break;
                    275:        }
                    276:     }
                    277:     return addr;
                    278: }
                    279: 
                    280: /*
                    281:  * Find the next address that will be executed after the
                    282:  * case statement at the given address.
                    283:  */
                    284: 
                    285: LOCAL ADDRESS docase(ncases, size, addr)
                    286: int ncases;
                    287: int size;
                    288: ADDRESS addr;
                    289: {
                    290:     register ADDRESS i;
                    291:     ADDRESS firstval, lastval, jmptable;
                    292:     short offset;
                    293:     long swtval, caseval;
                    294: 
                    295:     stepto(addr - 2);
                    296:     if (ncases == 0) {
                    297:        iread(&ncases, addr, sizeof(ncases));
                    298:        addr += sizeof(short);
                    299:     }
                    300:     jmptable = addr;
                    301:     firstval = jmptable + ncases*sizeof(short);
                    302:     lastval = firstval + ncases*size;
                    303:     if (size <= 2) {
                    304:        dread(&swtval, process->sp, 2);
                    305:     } else {
                    306:        dread(&swtval, process->sp, size);
                    307:     }
                    308:     for (i = firstval; i < lastval; i += size) {
                    309:        iread(&caseval, i, size);
                    310:        if (cmp(&swtval, &caseval, size) == 0) {
                    311:            i = ((i - firstval) / size) * sizeof(offset);
                    312:            iread(&offset, jmptable + i, sizeof(offset));
                    313:            addr = jmptable + offset;
                    314:            return addr;
                    315:        }
                    316:     }
                    317:     return((lastval+1)&~1);
                    318: }
                    319: 
                    320: LOCAL ADDRESS dofor(size, addr, subop, incr)
                    321: int size;
                    322: ADDRESS addr;
                    323: short subop;
                    324: int incr;
                    325: {
                    326:     register PROCESS *p;
                    327:     long i, limit, lower;
                    328:     ADDRESS valaddr;
                    329:     short offset;
                    330: 
                    331:     stepto(addr - sizeof(short));
                    332:     p = process;
                    333:     i = limit = 0;
                    334:     if (subop == 0) {
                    335:        addr += size;
                    336:     }
                    337:     dread(&valaddr, p->sp, sizeof(valaddr));
                    338:     dread(&i, valaddr, size);
                    339:     dread(&limit, p->sp + sizeof(valaddr), size);
                    340:     i += (incr << (8*(sizeof(i) - size)));
                    341:     addr += size;
                    342: 
                    343: /*
                    344:  * It is very slow to go through the loop again and again.
                    345:  * If it is desired to just skip to the end, the next 4 lines
                    346:  * should be skipped.
                    347:  */
                    348:     if ((incr > 0 && i < limit) || (incr < 0 && i > limit)) {
                    349:        iread(&offset, addr, sizeof(offset));
                    350:        return(addr + offset);
                    351:     } else {
                    352:        return(addr + sizeof(short));
                    353:     }
                    354: }
                    355: 
                    356: /*
                    357:  * Determine whether or not the given address corresponds to the
                    358:  * end of a procedure.
                    359:  */
                    360: 
                    361: BOOLEAN isendofproc(addr)
                    362: ADDRESS addr;
                    363: {
                    364:     PXOP op;
                    365: 
                    366:     iread(&op, addr, sizeof(op));
                    367:     return (op == O_END);
                    368: }

unix.superglobalmegacorp.com

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