|
|
1.1 ! root 1: /* Copyright (c) 1982 Regents of the University of California */ ! 2: ! 3: static char sccsid[] = "@(#)mappings.c 1.4 8/10/83"; ! 4: ! 5: /* ! 6: * Source-to-object and vice versa mappings. ! 7: */ ! 8: ! 9: #include "defs.h" ! 10: #include "mappings.h" ! 11: #include "symbols.h" ! 12: #include "source.h" ! 13: #include "object.h" ! 14: #include "machine.h" ! 15: ! 16: #ifndef public ! 17: #include "machine.h" ! 18: #include "source.h" ! 19: #include "symbols.h" ! 20: ! 21: typedef struct { ! 22: Address addr; ! 23: String filename; ! 24: Lineno lineindex; /* index to first linetab entry */ ! 25: } Filetab; ! 26: ! 27: typedef struct { ! 28: Lineno line; ! 29: Address addr; ! 30: } Linetab; ! 31: ! 32: Filetab *filetab; ! 33: Linetab *linetab; ! 34: ! 35: #define NOADDR ((Address) -1) /* no address for line or procedure */ ! 36: ! 37: #endif ! 38: ! 39: /* ! 40: * Get the source file name associated with a given address. ! 41: */ ! 42: ! 43: public String srcfilename(addr) ! 44: Address addr; ! 45: { ! 46: register Address i, j, k; ! 47: Address a; ! 48: Filetab *ftp; ! 49: String s; ! 50: ! 51: s = nil; ! 52: if (nlhdr.nfiles != 0 and addr >= filetab[0].addr) { ! 53: i = 0; ! 54: j = nlhdr.nfiles - 1; ! 55: while (i < j) { ! 56: k = (i + j) / 2; ! 57: ftp = &filetab[k]; ! 58: a = ftp->addr; ! 59: if (a == addr) { ! 60: s = ftp->filename; ! 61: break; ! 62: } else if (addr > a) { ! 63: i = k + 1; ! 64: } else { ! 65: j = k - 1; ! 66: } ! 67: } ! 68: if (s == nil) { ! 69: if (addr >= filetab[i].addr) { ! 70: s = filetab[i].filename; ! 71: } else { ! 72: s = filetab[i-1].filename; ! 73: } ! 74: } ! 75: } ! 76: return s; ! 77: } ! 78: ! 79: /* ! 80: * Find the line associated with the given address. ! 81: * If the second parameter is true, then the address must match ! 82: * a source line exactly. Otherwise the nearest source line ! 83: * below the given address is returned. In any case, if no suitable ! 84: * line exists, 0 is returned. ! 85: */ ! 86: ! 87: private Lineno findline(addr, exact) ! 88: Address addr; ! 89: Boolean exact; ! 90: { ! 91: register Address i, j, k; ! 92: register Lineno r; ! 93: register Address a; ! 94: ! 95: if (nlhdr.nlines == 0 or addr < linetab[0].addr) { ! 96: r = 0; ! 97: } else { ! 98: i = 0; ! 99: j = nlhdr.nlines - 1; ! 100: if (addr == linetab[i].addr) { ! 101: r = linetab[i].line; ! 102: } else if (addr == linetab[j].addr) { ! 103: r = linetab[j].line; ! 104: } else if (addr > linetab[j].addr) { ! 105: r = exact ? 0 : linetab[j].line; ! 106: } else { ! 107: do { ! 108: k = (i + j) div 2; ! 109: a = linetab[k].addr; ! 110: if (a == addr) break; ! 111: if (addr > a) { ! 112: i = k + 1; ! 113: } else { ! 114: j = k - 1; ! 115: } ! 116: } while (i <= j); ! 117: if (a == addr) { ! 118: r = linetab[k].line; ! 119: } else if (exact) { ! 120: r = 0; ! 121: } else if (addr > linetab[i].addr) { ! 122: r = linetab[i].line; ! 123: } else { ! 124: r = linetab[i-1].line; ! 125: } ! 126: } ! 127: } ! 128: return r; ! 129: } ! 130: ! 131: /* ! 132: * Lookup the source line number nearest from below to an address. ! 133: */ ! 134: ! 135: public Lineno srcline(addr) ! 136: Address addr; ! 137: { ! 138: return findline(addr, false); ! 139: } ! 140: ! 141: /* ! 142: * Look for a line exactly corresponding to the given address. ! 143: */ ! 144: ! 145: public Lineno linelookup(addr) ! 146: Address addr; ! 147: { ! 148: return findline(addr, true); ! 149: } ! 150: ! 151: /* ! 152: * Lookup the object address of a given line from the named file. ! 153: * ! 154: * Potentially all files in the file table need to be checked ! 155: * until the line is found since a particular file name may appear ! 156: * more than once in the file table (caused by includes). ! 157: */ ! 158: ! 159: public Address objaddr(line, name) ! 160: Lineno line; ! 161: String name; ! 162: { ! 163: register Filetab *ftp; ! 164: register Lineno i, j; ! 165: Boolean foundfile; ! 166: ! 167: if (nlhdr.nlines == 0) { ! 168: return NOADDR; ! 169: } ! 170: if (name == nil) { ! 171: name = cursource; ! 172: } ! 173: foundfile = false; ! 174: for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) { ! 175: if (streq(ftp->filename, name)) { ! 176: foundfile = true; ! 177: i = ftp->lineindex; ! 178: if (ftp == &filetab[nlhdr.nfiles-1]) { ! 179: j = nlhdr.nlines; ! 180: } else { ! 181: j = (ftp + 1)->lineindex; ! 182: } ! 183: while (i < j) { ! 184: if (linetab[i].line == line) { ! 185: return linetab[i].addr; ! 186: } ! 187: i++; ! 188: } ! 189: } ! 190: } ! 191: if (not foundfile) { ! 192: error("unknown source file \"%s\"", name); ! 193: } ! 194: return NOADDR; ! 195: } ! 196: ! 197: /* ! 198: * Table for going from object addresses to the functions in which they belong. ! 199: */ ! 200: ! 201: #define MAXNFUNCS 1001 /* maximum number of functions allowed */ ! 202: ! 203: typedef struct { ! 204: Symbol func; ! 205: Address addr; ! 206: } AddrOfFunc; ! 207: ! 208: private AddrOfFunc functab[MAXNFUNCS]; ! 209: private int nfuncs; ! 210: ! 211: /* ! 212: * Insert a new function into the table. ! 213: * The table is ordered by object address. ! 214: */ ! 215: ! 216: public newfunc(f, addr) ! 217: Symbol f; ! 218: Address addr; ! 219: { ! 220: register AddrOfFunc *af; ! 221: ! 222: if (nfuncs >= MAXNFUNCS) { ! 223: panic("too many procedures/functions"); ! 224: } ! 225: af = &functab[nfuncs]; ! 226: af->func = f; ! 227: af->addr = addr; ! 228: ++nfuncs; ! 229: } ! 230: ! 231: /* ! 232: * Return the function that begins at the given address. ! 233: */ ! 234: ! 235: public Symbol whatblock(addr) ! 236: Address addr; ! 237: { ! 238: register int i, j, k; ! 239: Address a; ! 240: ! 241: i = 0; ! 242: j = nfuncs - 1; ! 243: if (addr < functab[i].addr) { ! 244: return program; ! 245: } else if (addr == functab[i].addr) { ! 246: return functab[i].func; ! 247: } else if (addr >= functab[j].addr) { ! 248: return functab[j].func; ! 249: } ! 250: while (i <= j) { ! 251: k = (i + j) / 2; ! 252: a = functab[k].addr; ! 253: if (a == addr) { ! 254: return functab[k].func; ! 255: } else if (addr > a) { ! 256: i = k+1; ! 257: } else { ! 258: j = k-1; ! 259: } ! 260: } ! 261: if (addr > functab[i].addr) { ! 262: return functab[i].func; ! 263: } else { ! 264: return functab[i-1].func; ! 265: } ! 266: /* NOTREACHED */ ! 267: } ! 268: ! 269: /* ! 270: * Order the functab. ! 271: */ ! 272: ! 273: private int cmpfunc(f1, f2) ! 274: AddrOfFunc *f1, *f2; ! 275: { ! 276: register Address a1, a2; ! 277: ! 278: a1 = (*f1).addr; ! 279: a2 = (*f2).addr; ! 280: return ( (a1 < a2) ? -1 : ( (a1 == a2) ? 0 : 1 ) ); ! 281: } ! 282: ! 283: public ordfunctab() ! 284: { ! 285: qsort(functab, nfuncs, sizeof(AddrOfFunc), cmpfunc); ! 286: } ! 287: ! 288: /* ! 289: * Clear out the functab, used when re-reading the object information. ! 290: */ ! 291: ! 292: public clrfunctab() ! 293: { ! 294: nfuncs = 0; ! 295: } ! 296: ! 297: public dumpfunctab() ! 298: { ! 299: int i; ! 300: ! 301: for (i = 0; i < nfuncs; i++) { ! 302: psym(functab[i].func); ! 303: } ! 304: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.