Annotation of 43BSD/ucb/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.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: }

unix.superglobalmegacorp.com

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