|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.