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

unix.superglobalmegacorp.com

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