|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 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[] = "@(#)mappings.c 5.2 (Berkeley) 2/19/86"; ! 9: #endif not lint ! 10: ! 11: static char rcsid[] = "$Header: mappings.c,v 1.4 84/12/26 10:40:25 linton Exp $"; ! 12: ! 13: /* ! 14: * Source-to-object and vice versa mappings. ! 15: */ ! 16: ! 17: #include "defs.h" ! 18: #include "mappings.h" ! 19: #include "symbols.h" ! 20: #include "source.h" ! 21: #include "object.h" ! 22: #include "machine.h" ! 23: ! 24: #ifndef public ! 25: #include "machine.h" ! 26: #include "source.h" ! 27: #include "symbols.h" ! 28: ! 29: typedef struct { ! 30: Address addr; ! 31: String filename; ! 32: Lineno lineindex; /* index to first linetab entry */ ! 33: } Filetab; ! 34: ! 35: typedef struct { ! 36: Lineno line; ! 37: Address addr; ! 38: } Linetab; ! 39: ! 40: Filetab *filetab; ! 41: Linetab *linetab; ! 42: ! 43: #define NOADDR ((Address) -1) /* no address for line or procedure */ ! 44: ! 45: #endif ! 46: ! 47: /* ! 48: * Get the source file name associated with a given address. ! 49: */ ! 50: ! 51: public String srcfilename(addr) ! 52: Address addr; ! 53: { ! 54: register Address i, j, k; ! 55: Address a; ! 56: Filetab *ftp; ! 57: String s; ! 58: ! 59: s = nil; ! 60: if (nlhdr.nfiles != 0 and addr >= filetab[0].addr) { ! 61: i = 0; ! 62: j = nlhdr.nfiles - 1; ! 63: while (i < j) { ! 64: k = (i + j) / 2; ! 65: ftp = &filetab[k]; ! 66: a = ftp->addr; ! 67: if (a == addr) { ! 68: s = ftp->filename; ! 69: break; ! 70: } else if (addr > a) { ! 71: i = k + 1; ! 72: } else { ! 73: j = k - 1; ! 74: } ! 75: } ! 76: if (s == nil) { ! 77: if (addr >= filetab[i].addr) { ! 78: s = filetab[i].filename; ! 79: } else { ! 80: s = filetab[i-1].filename; ! 81: } ! 82: } ! 83: } ! 84: return s; ! 85: } ! 86: ! 87: /* ! 88: * Find the line associated with the given address. ! 89: * If the second parameter is true, then the address must match ! 90: * a source line exactly. Otherwise the nearest source line ! 91: * below the given address is returned. ! 92: * ! 93: * Return the index of the line table entry or -1 if none suitable. ! 94: */ ! 95: ! 96: private integer findline (addr, exact) ! 97: Address addr; ! 98: Boolean exact; ! 99: { ! 100: register Address i, j, k; ! 101: register Lineno r; ! 102: register Address a; ! 103: ! 104: if (nlhdr.nlines == 0) { ! 105: r = -1; ! 106: } else if (addr < linetab[0].addr) { ! 107: r = exact ? -1 : 0; ! 108: } else { ! 109: i = 0; ! 110: j = nlhdr.nlines - 1; ! 111: if (addr == linetab[i].addr) { ! 112: r = i; ! 113: } else if (addr == linetab[j].addr) { ! 114: r = j; ! 115: } else if (addr > linetab[j].addr) { ! 116: r = exact ? -1 : j; ! 117: } else { ! 118: do { ! 119: k = (i + j) div 2; ! 120: a = linetab[k].addr; ! 121: if (a == addr) break; ! 122: if (addr > a) { ! 123: i = k + 1; ! 124: } else { ! 125: j = k - 1; ! 126: } ! 127: } while (i <= j); ! 128: if (a == addr) { ! 129: r = k; ! 130: } else if (exact) { ! 131: r = -1; ! 132: } else if (addr > linetab[i].addr) { ! 133: r = i; ! 134: } else { ! 135: r = i - 1; ! 136: } ! 137: } ! 138: } ! 139: return r; ! 140: } ! 141: ! 142: /* ! 143: * Lookup the source line number nearest (from below) to an address. ! 144: * ! 145: * It is possible (unfortunately) that the compiler will generate ! 146: * code before line number for a procedure. Therefore we check ! 147: * to see that the found line is in the same procedure as the given address. ! 148: * If it isn't, then we walk forward until the first suitable line is found. ! 149: */ ! 150: ! 151: public Lineno srcline(addr) ! 152: Address addr; ! 153: { ! 154: integer i; ! 155: Lineno r; ! 156: Symbol f1, f2; ! 157: ! 158: i = findline(addr, false); ! 159: if (i == -1) { ! 160: r = 0; ! 161: } else { ! 162: r = linetab[i].line; ! 163: if (linetab[i].addr != addr) { ! 164: f1 = whatblock(addr); ! 165: if (nosource(f1)) { ! 166: r = 0; ! 167: } else { ! 168: f2 = whatblock(linetab[i].addr + 1); ! 169: if (f1 != f2) { ! 170: do { ! 171: ++i; ! 172: } while (linetab[i].addr < addr and i < nlhdr.nlines); ! 173: r = linetab[i].line; ! 174: } ! 175: } ! 176: } ! 177: } ! 178: return r; ! 179: } ! 180: ! 181: /* ! 182: * Look for a line exactly corresponding to the given address. ! 183: */ ! 184: ! 185: public Lineno linelookup(addr) ! 186: Address addr; ! 187: { ! 188: integer i; ! 189: Lineno r; ! 190: ! 191: i = findline(addr, true); ! 192: if (i == -1) { ! 193: r = 0; ! 194: } else { ! 195: r = linetab[i].line; ! 196: } ! 197: return r; ! 198: } ! 199: ! 200: /* ! 201: * Lookup the object address of a given line from the named file. ! 202: * ! 203: * Potentially all files in the file table need to be checked ! 204: * until the line is found since a particular file name may appear ! 205: * more than once in the file table (caused by includes). ! 206: */ ! 207: ! 208: public Address objaddr(line, name) ! 209: Lineno line; ! 210: String name; ! 211: { ! 212: register Filetab *ftp; ! 213: register Lineno i, j; ! 214: Boolean foundfile; ! 215: ! 216: if (nlhdr.nlines == 0) { ! 217: return NOADDR; ! 218: } ! 219: if (name == nil) { ! 220: name = cursource; ! 221: } ! 222: foundfile = false; ! 223: for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) { ! 224: if (streq(ftp->filename, name)) { ! 225: foundfile = true; ! 226: i = ftp->lineindex; ! 227: if (ftp == &filetab[nlhdr.nfiles-1]) { ! 228: j = nlhdr.nlines; ! 229: } else { ! 230: j = (ftp + 1)->lineindex; ! 231: } ! 232: while (i < j) { ! 233: if (linetab[i].line == line) { ! 234: return linetab[i].addr; ! 235: } ! 236: i++; ! 237: } ! 238: } ! 239: } ! 240: if (not foundfile) { ! 241: error("source file \"%s\" not compiled with -g", name); ! 242: } ! 243: return NOADDR; ! 244: } ! 245: ! 246: /* ! 247: * Table for going from object addresses to the functions in which they belong. ! 248: */ ! 249: ! 250: #define NFUNCS 500 /* initial size of function table */ ! 251: ! 252: typedef struct { ! 253: Symbol func; ! 254: Address addr; ! 255: } AddrOfFunc; ! 256: ! 257: private AddrOfFunc *functab; ! 258: private int nfuncs = 0; ! 259: private int functablesize = 0; ! 260: ! 261: /* ! 262: * Insert a new function into the table. ! 263: */ ! 264: ! 265: public newfunc(f, addr) ! 266: Symbol f; ! 267: Address addr; ! 268: { ! 269: register AddrOfFunc *af; ! 270: register int i; ! 271: AddrOfFunc *newfunctab; ! 272: ! 273: if (nfuncs >= functablesize) { ! 274: if (functablesize == 0) { ! 275: functab = newarr(AddrOfFunc, NFUNCS); ! 276: functablesize = NFUNCS; ! 277: } else { ! 278: functablesize *= 2; ! 279: newfunctab = newarr(AddrOfFunc, functablesize); ! 280: bcopy(functab, newfunctab, nfuncs * sizeof(AddrOfFunc)); ! 281: dispose(functab); ! 282: functab = newfunctab; ! 283: } ! 284: } ! 285: af = &functab[nfuncs]; ! 286: af->func = f; ! 287: af->addr = addr; ! 288: ++nfuncs; ! 289: } ! 290: ! 291: /* ! 292: * Return the function that begins at the given address. ! 293: */ ! 294: ! 295: public Symbol whatblock(addr) ! 296: Address addr; ! 297: { ! 298: register int i, j, k; ! 299: Address a; ! 300: ! 301: i = 0; ! 302: j = nfuncs - 1; ! 303: if (addr < functab[i].addr) { ! 304: return program; ! 305: } else if (addr == functab[i].addr) { ! 306: return functab[i].func; ! 307: } else if (addr >= functab[j].addr) { ! 308: return functab[j].func; ! 309: } ! 310: while (i <= j) { ! 311: k = (i + j) / 2; ! 312: a = functab[k].addr; ! 313: if (a == addr) { ! 314: return functab[k].func; ! 315: } else if (addr > a) { ! 316: i = k+1; ! 317: } else { ! 318: j = k-1; ! 319: } ! 320: } ! 321: if (addr > functab[i].addr) { ! 322: return functab[i].func; ! 323: } else { ! 324: return functab[i-1].func; ! 325: } ! 326: /* NOTREACHED */ ! 327: } ! 328: ! 329: /* ! 330: * Order the functab. ! 331: */ ! 332: ! 333: private int cmpfunc(f1, f2) ! 334: AddrOfFunc *f1, *f2; ! 335: { ! 336: register Address a1, a2; ! 337: ! 338: a1 = (*f1).addr; ! 339: a2 = (*f2).addr; ! 340: return ( (a1 < a2) ? -1 : ( (a1 == a2) ? 0 : 1 ) ); ! 341: } ! 342: ! 343: public ordfunctab() ! 344: { ! 345: qsort(functab, nfuncs, sizeof(AddrOfFunc), cmpfunc); ! 346: } ! 347: ! 348: /* ! 349: * Clear out the functab, used when re-reading the object information. ! 350: */ ! 351: ! 352: public clrfunctab() ! 353: { ! 354: nfuncs = 0; ! 355: } ! 356: ! 357: public dumpfunctab() ! 358: { ! 359: int i; ! 360: ! 361: for (i = 0; i < nfuncs; i++) { ! 362: psym(functab[i].func); ! 363: } ! 364: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.