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: }

Defined functions

clrfunctab defined in line 352; used 1 times
cmpfunc defined in line 333; used 1 times
dumpfunctab defined in line 357; used 1 times
findline defined in line 96; used 2 times
linelookup defined in line 185; used 4 times
newfunc defined in line 265; used 6 times
objaddr defined in line 208; used 2 times
ordfunctab defined in line 343; used 1 times

Defined variables

functablesize defined in line 259; used 5 times
nfuncs defined in line 258; used 8 times
rcsid defined in line 11; never used
sccsid defined in line 8; never used

Defined macros

NFUNCS defined in line 250; used 2 times
NOADDR defined in line 43; used 2 times
Last modified: 1986-02-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 992
Valid CSS Valid XHTML 1.0 Strict