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: }

Defined functions

docase defined in line 290; used 4 times
dofor defined in line 325; used 7 times
isendofproc defined in line 366; never used
nextaddr defined in line 35; never used

Defined variables

sccsid defined in line 8; never used
Last modified: 1985-06-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2849
Valid CSS Valid XHTML 1.0 Strict