Annotation of 43BSDReno/pgrm/dbx/mappings.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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