|
|
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.3 (Berkeley) 1/12/88"; ! 9: #endif not lint ! 10: ! 11: static char rcsid[] = "$Header: mappings.c,v 1.3 87/03/26 19:41:55 donn 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 or addr < linetab[0].addr) { ! 105: r = -1; ! 106: } else { ! 107: i = 0; ! 108: j = nlhdr.nlines - 1; ! 109: if (addr == linetab[i].addr) { ! 110: r = i; ! 111: } else if (addr == linetab[j].addr) { ! 112: r = j; ! 113: } else if (addr > linetab[j].addr) { ! 114: r = exact ? -1 : j; ! 115: } else { ! 116: do { ! 117: k = (i + j) div 2; ! 118: a = linetab[k].addr; ! 119: if (a == addr) break; ! 120: if (addr > a) { ! 121: i = k + 1; ! 122: } else { ! 123: j = k - 1; ! 124: } ! 125: } while (i <= j); ! 126: if (a == addr) { ! 127: r = k; ! 128: } else if (exact) { ! 129: r = -1; ! 130: } else if (addr > linetab[i].addr) { ! 131: r = i; ! 132: } else { ! 133: r = i - 1; ! 134: } ! 135: } ! 136: } ! 137: return r; ! 138: } ! 139: ! 140: /* ! 141: * Lookup the source line number nearest (from below) to an address. ! 142: * ! 143: * It is possible (unfortunately) that the compiler will generate ! 144: * code before line number for a procedure. Therefore we check ! 145: * to see that the found line is in the same procedure as the given address. ! 146: * If it isn't, then we walk forward until the first suitable line is found. ! 147: */ ! 148: ! 149: public Lineno srcline (addr) ! 150: Address addr; ! 151: { ! 152: Lineno i, r; ! 153: Symbol f1, f2; ! 154: Address a; ! 155: ! 156: i = findline(addr, false); ! 157: if (i == -1) { ! 158: f1 = whatblock(addr); ! 159: if (f1 == nil or nosource(f1)) { ! 160: r = 0; ! 161: } else { ! 162: a = codeloc(f1); ! 163: for (;;) { ! 164: r = linelookup(a); ! 165: if (r != 0 or a >= CODESTART + objsize) { ! 166: break; ! 167: } ! 168: ++a; ! 169: } ! 170: } ! 171: } else { ! 172: r = linetab[i].line; ! 173: if (linetab[i].addr != addr) { ! 174: f1 = whatblock(addr); ! 175: if (nosource(f1)) { ! 176: r = 0; ! 177: } else { ! 178: f2 = whatblock(linetab[i].addr + 1); ! 179: if (f1 != f2) { ! 180: do { ! 181: ++i; ! 182: } while (linetab[i].addr < addr and i < nlhdr.nlines); ! 183: r = linetab[i].line; ! 184: } ! 185: } ! 186: } ! 187: } ! 188: return r; ! 189: } ! 190: ! 191: /* ! 192: * Look for a line exactly corresponding to the given address. ! 193: */ ! 194: ! 195: public Lineno linelookup(addr) ! 196: Address addr; ! 197: { ! 198: integer i; ! 199: Lineno r; ! 200: ! 201: i = findline(addr, true); ! 202: if (i == -1) { ! 203: r = 0; ! 204: } else { ! 205: r = linetab[i].line; ! 206: } ! 207: return r; ! 208: } ! 209: ! 210: /* ! 211: * Lookup the object address of a given line from the named file. ! 212: * ! 213: * Potentially all files in the file table need to be checked ! 214: * until the line is found since a particular file name may appear ! 215: * more than once in the file table (caused by includes). ! 216: */ ! 217: ! 218: public Address objaddr(line, name) ! 219: Lineno line; ! 220: String name; ! 221: { ! 222: register Filetab *ftp; ! 223: register Lineno i, j; ! 224: Boolean foundfile; ! 225: ! 226: if (nlhdr.nlines == 0) { ! 227: return NOADDR; ! 228: } ! 229: if (name == nil) { ! 230: name = cursource; ! 231: } ! 232: foundfile = false; ! 233: for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) { ! 234: if (streq(ftp->filename, name)) { ! 235: foundfile = true; ! 236: i = ftp->lineindex; ! 237: if (ftp == &filetab[nlhdr.nfiles-1]) { ! 238: j = nlhdr.nlines; ! 239: } else { ! 240: j = (ftp + 1)->lineindex; ! 241: } ! 242: while (i < j) { ! 243: if (linetab[i].line == line) { ! 244: return linetab[i].addr; ! 245: } ! 246: i++; ! 247: } ! 248: } ! 249: } ! 250: if (not foundfile) { ! 251: error("source file \"%s\" not compiled with -g", name); ! 252: } ! 253: return NOADDR; ! 254: } ! 255: ! 256: /* ! 257: * Table for going from object addresses to the functions in which they belong. ! 258: */ ! 259: ! 260: #define NFUNCS 500 /* initial size of function table */ ! 261: ! 262: typedef struct { ! 263: Symbol func; ! 264: Address addr; ! 265: } AddrOfFunc; ! 266: ! 267: private AddrOfFunc *functab; ! 268: private int nfuncs = 0; ! 269: private int functablesize = 0; ! 270: ! 271: /* ! 272: * Insert a new function into the table. ! 273: */ ! 274: ! 275: public newfunc(f, addr) ! 276: Symbol f; ! 277: Address addr; ! 278: { ! 279: register AddrOfFunc *af; ! 280: register int i; ! 281: AddrOfFunc *newfunctab; ! 282: ! 283: if (nfuncs >= functablesize) { ! 284: if (functablesize == 0) { ! 285: functab = newarr(AddrOfFunc, NFUNCS); ! 286: functablesize = NFUNCS; ! 287: } else { ! 288: functablesize *= 2; ! 289: newfunctab = newarr(AddrOfFunc, functablesize); ! 290: bcopy(functab, newfunctab, nfuncs * sizeof(AddrOfFunc)); ! 291: dispose(functab); ! 292: functab = newfunctab; ! 293: } ! 294: } ! 295: af = &functab[nfuncs]; ! 296: af->func = f; ! 297: af->addr = addr; ! 298: ++nfuncs; ! 299: } ! 300: ! 301: /* ! 302: * Return the function that begins at the given address. ! 303: */ ! 304: ! 305: public Symbol whatblock(addr) ! 306: Address addr; ! 307: { ! 308: register int i, j, k; ! 309: Address a; ! 310: ! 311: i = 0; ! 312: j = nfuncs - 1; ! 313: if (addr < functab[i].addr) { ! 314: return program; ! 315: } else if (addr == functab[i].addr) { ! 316: return functab[i].func; ! 317: } else if (addr >= functab[j].addr) { ! 318: return functab[j].func; ! 319: } ! 320: while (i <= j) { ! 321: k = (i + j) / 2; ! 322: a = functab[k].addr; ! 323: if (a == addr) { ! 324: return functab[k].func; ! 325: } else if (addr > a) { ! 326: i = k+1; ! 327: } else { ! 328: j = k-1; ! 329: } ! 330: } ! 331: if (addr > functab[i].addr) { ! 332: return functab[i].func; ! 333: } else { ! 334: return functab[i-1].func; ! 335: } ! 336: /* NOTREACHED */ ! 337: } ! 338: ! 339: /* ! 340: * Order the functab. ! 341: */ ! 342: ! 343: private int cmpfunc(f1, f2) ! 344: AddrOfFunc *f1, *f2; ! 345: { ! 346: register Address a1, a2; ! 347: ! 348: a1 = (*f1).addr; ! 349: a2 = (*f2).addr; ! 350: return ( (a1 < a2) ? -1 : ( (a1 == a2) ? 0 : 1 ) ); ! 351: } ! 352: ! 353: public ordfunctab() ! 354: { ! 355: qsort(functab, nfuncs, sizeof(AddrOfFunc), cmpfunc); ! 356: } ! 357: ! 358: /* ! 359: * Clear out the functab, used when re-reading the object information. ! 360: */ ! 361: ! 362: public clrfunctab() ! 363: { ! 364: nfuncs = 0; ! 365: } ! 366: ! 367: public dumpfunctab() ! 368: { ! 369: int i; ! 370: ! 371: for (i = 0; i < nfuncs; i++) { ! 372: psym(functab[i].func); ! 373: } ! 374: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.