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