Annotation of 43BSDTahoe/lib/old_compiler/dbx/mappings.c, revision 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.