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