Annotation of 43BSDReno/pgrm/dbx/mappings.c, revision 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.