Annotation of 43BSDTahoe/lib/old_compiler/dbx/mappings.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.