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

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

unix.superglobalmegacorp.com

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