Annotation of 43BSDTahoe/lib/old_compiler/dbx/object.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[] = "@(#)object.c   5.2 (Berkeley) 1/12/88";
                      9: #endif not lint
                     10: 
                     11: static char rcsid[] = "$Header: object.c,v 1.5 87/03/26 20:24:58 donn Exp $";
                     12: 
                     13: /*
                     14:  * Object code interface, mainly for extraction of symbolic information.
                     15:  */
                     16: 
                     17: #include "defs.h"
                     18: #include "object.h"
                     19: #include "stabstring.h"
                     20: #include "main.h"
                     21: #include "symbols.h"
                     22: #include "names.h"
                     23: #include "languages.h"
                     24: #include "mappings.h"
                     25: #include "lists.h"
                     26: #include <a.out.h>
                     27: #include <stab.h>
                     28: #include <ctype.h>
                     29: 
                     30: #ifndef public
                     31: 
                     32: struct {
                     33:     unsigned int stringsize;   /* size of the dumped string table */
                     34:     unsigned int nsyms;                /* number of symbols */
                     35:     unsigned int nfiles;       /* number of files */
                     36:     unsigned int nlines;       /* number of lines */
                     37: } nlhdr;
                     38: 
                     39: #include "languages.h"
                     40: #include "symbols.h"
                     41: 
                     42: #endif
                     43: 
                     44: #ifndef N_MOD2
                     45: #    define N_MOD2 0x50
                     46: #endif
                     47: 
                     48: public String objname = "a.out";
                     49: public integer objsize;
                     50: 
                     51: public Language curlang;
                     52: public Symbol curmodule;
                     53: public Symbol curparam;
                     54: public Symbol curcomm;
                     55: public Symbol commchain;
                     56: 
                     57: private char *stringtab;
                     58: private struct nlist *curnp;
                     59: private Boolean warned;
                     60: private Boolean strip_ = false;
                     61: 
                     62: private Filetab *filep;
                     63: private Linetab *linep, *prevlinep;
                     64: 
                     65: public String curfilename ()
                     66: {
                     67:     return ((filep-1)->filename);
                     68: }
                     69: 
                     70: /*
                     71:  * Blocks are figured out on the fly while reading the symbol table.
                     72:  */
                     73: 
                     74: #define MAXBLKDEPTH 25
                     75: 
                     76: public Symbol curblock;
                     77: 
                     78: private Symbol blkstack[MAXBLKDEPTH];
                     79: private integer curlevel;
                     80: private integer bnum, nesting;
                     81: private Address addrstk[MAXBLKDEPTH];
                     82: 
                     83: public pushBlock (b)
                     84: Symbol b;
                     85: {
                     86:     if (curlevel >= MAXBLKDEPTH) {
                     87:        fatal("nesting depth too large (%d)", curlevel);
                     88:     }
                     89:     blkstack[curlevel] = curblock;
                     90:     ++curlevel;
                     91:     curblock = b;
                     92:     if (traceblocks) {
                     93:        printf("entering block %s\n", symname(b));
                     94:     }
                     95: }
                     96: 
                     97: /*
                     98:  * Change the current block with saving the previous one,
                     99:  * since it is assumed that the symbol for the current one is to be deleted.
                    100:  */
                    101: 
                    102: public changeBlock (b)
                    103: Symbol b;
                    104: {
                    105:     curblock = b;
                    106: }
                    107: 
                    108: public enterblock (b)
                    109: Symbol b;
                    110: {
                    111:     if (curblock == nil) {
                    112:        b->level = 1;
                    113:     } else {
                    114:        b->level = curblock->level + 1;
                    115:     }
                    116:     b->block = curblock;
                    117:     pushBlock(b);
                    118: }
                    119: 
                    120: public exitblock ()
                    121: {
                    122:     if (curblock->class == FUNC or curblock->class == PROC) {
                    123:        if (prevlinep != linep) {
                    124:            curblock->symvalue.funcv.src = true;
                    125:        }
                    126:     }
                    127:     if (curlevel <= 0) {
                    128:        panic("nesting depth underflow (%d)", curlevel);
                    129:     }
                    130:     --curlevel;
                    131:     if (traceblocks) {
                    132:        printf("exiting block %s\n", symname(curblock));
                    133:     }
                    134:     curblock = blkstack[curlevel];
                    135: }
                    136: 
                    137: /*
                    138:  * Enter a source line or file name reference into the appropriate table.
                    139:  * Expanded inline to reduce procedure calls.
                    140:  *
                    141:  * private enterline (linenumber, address)
                    142:  * Lineno linenumber;
                    143:  * Address address;
                    144:  *  ...
                    145:  */
                    146: 
                    147: #define enterline(linenumber, address) \
                    148: { \
                    149:     register Linetab *lp; \
                    150:  \
                    151:     lp = linep - 1; \
                    152:     if (linenumber != lp->line) { \
                    153:        if (address != lp->addr) { \
                    154:            ++lp; \
                    155:        } \
                    156:        lp->line = linenumber; \
                    157:        lp->addr = address; \
                    158:        linep = lp + 1; \
                    159:     } \
                    160: }
                    161: 
                    162: /*
                    163:  * Read in the namelist from the obj file.
                    164:  *
                    165:  * Reads and seeks are used instead of fread's and fseek's
                    166:  * for efficiency sake; there's a lot of data being read here.
                    167:  */
                    168: 
                    169: public readobj (file)
                    170: String file;
                    171: {
                    172:     Fileid f;
                    173:     struct exec hdr;
                    174:     struct nlist nlist;
                    175: 
                    176:     f = open(file, 0);
                    177:     if (f < 0) {
                    178:        fatal("can't open %s", file);
                    179:     }
                    180:     read(f, &hdr, sizeof(hdr));
                    181:     if (N_BADMAG(hdr)) {
                    182:        objsize = 0;
                    183:        nlhdr.nsyms = 0;
                    184:        nlhdr.nfiles = 0;
                    185:        nlhdr.nlines = 0;
                    186:     } else {
                    187:        objsize = hdr.a_text;
                    188:        nlhdr.nsyms = hdr.a_syms / sizeof(nlist);
                    189:        nlhdr.nfiles = nlhdr.nsyms;
                    190:        nlhdr.nlines = nlhdr.nsyms;
                    191:     }
                    192:     if (nlhdr.nsyms > 0) {
                    193:        lseek(f, (long) N_STROFF(hdr), 0);
                    194:        read(f, &(nlhdr.stringsize), sizeof(nlhdr.stringsize));
                    195:        nlhdr.stringsize -= 4;
                    196:        stringtab = newarr(char, nlhdr.stringsize);
                    197:        read(f, stringtab, nlhdr.stringsize);
                    198:        allocmaps(nlhdr.nfiles, nlhdr.nlines);
                    199:        lseek(f, (long) N_SYMOFF(hdr), 0);
                    200:        readsyms(f);
                    201:        ordfunctab();
                    202:        setnlines();
                    203:        setnfiles();
                    204:     } else {
                    205:        initsyms();
                    206:     }
                    207:     close(f);
                    208: }
                    209: 
                    210: /*
                    211:  * Found the beginning of the externals in the object file
                    212:  * (signified by the "-lg" or find an external), close the
                    213:  * block for the last procedure.
                    214:  */
                    215: 
                    216: private foundglobals ()
                    217: {
                    218:     if (curblock->class != PROG) {
                    219:        exitblock();
                    220:        if (curblock->class != PROG) {
                    221:            exitblock();
                    222:        }
                    223:     }
                    224:     enterline(0, (linep-1)->addr + 1);
                    225: }
                    226: 
                    227: /*
                    228:  * Read in symbols from object file.
                    229:  */
                    230: 
                    231: private readsyms (f)
                    232: Fileid f;
                    233: {
                    234:     struct nlist *namelist;
                    235:     register struct nlist *np, *ub;
                    236:     register String name;
                    237:     boolean afterlg, foundstab;
                    238:     integer index;
                    239:     char *lastchar;
                    240: 
                    241:     initsyms();
                    242:     namelist = newarr(struct nlist, nlhdr.nsyms);
                    243:     read(f, namelist, nlhdr.nsyms * sizeof(struct nlist));
                    244:     afterlg = false;
                    245:     foundstab = false;
                    246:     ub = &namelist[nlhdr.nsyms];
                    247:     curnp = &namelist[0];
                    248:     np = curnp;
                    249:     while (np < ub) {
                    250:        index = np->n_un.n_strx;
                    251:        if (index != 0) {
                    252:            name = &stringtab[index - 4];
                    253:            /*
                    254:              *  If the program contains any .f files a trailing _ is stripped
                    255:                     *  from the name on the assumption it was added by the compiler.
                    256:             *  This only affects names that follow the sdb N_SO entry with
                    257:              *  the .f name. 
                    258:              */
                    259:             if (strip_ and name[0] != '\0' ) {
                    260:                lastchar = &name[strlen(name) - 1];
                    261:                if (*lastchar == '_') {
                    262:                    *lastchar = '\0';
                    263:                }
                    264:             }
                    265:        } else {
                    266:            name = nil;
                    267:        } 
                    268: 
                    269:        /*
                    270:         * Assumptions:
                    271:         *      not an N_STAB   ==> name != nil
                    272:         *      name[0] == '-'  ==> name == "-lg"
                    273:         *      name[0] != '_'  ==> filename or invisible
                    274:         *
                    275:         * The "-lg" signals the beginning of global loader symbols.
                    276:          *
                    277:         */
                    278:        if ((np->n_type&N_STAB) != 0) {
                    279:            foundstab = true;
                    280:            enter_nl(name, np);
                    281:        } else if (name[0] == '-') {
                    282:            afterlg = true;
                    283:            foundglobals();
                    284:        } else if (afterlg) {
                    285:            check_global(name, np);
                    286:        } else if ((np->n_type&N_EXT) == N_EXT) {
                    287:            afterlg = true;
                    288:            foundglobals();
                    289:            check_global(name, np);
                    290:        } else if (name[0] == '_') {
                    291:            check_local(&name[1], np);
                    292:        } else if ((np->n_type&N_TEXT) == N_TEXT) {
                    293:            check_filename(name);
                    294:        }
                    295:        ++curnp;
                    296:        np = curnp;
                    297:     }
                    298:     if (not foundstab) {
                    299:        warning("no source compiled with -g");
                    300:     }
                    301:     dispose(namelist);
                    302: }
                    303: 
                    304: /*
                    305:  * Get a continuation entry from the name list.
                    306:  * Return the beginning of the name.
                    307:  */
                    308: 
                    309: public String getcont ()
                    310: {
                    311:     register integer index;
                    312:     register String name;
                    313: 
                    314:     ++curnp;
                    315:     index = curnp->n_un.n_strx;
                    316:     if (index == 0) {
                    317:        name = "";
                    318:     } else {
                    319:        name = &stringtab[index - 4];
                    320:     }
                    321:     return name;
                    322: }
                    323: 
                    324: /*
                    325:  * Initialize symbol information.
                    326:  */
                    327: 
                    328: private initsyms ()
                    329: {
                    330:     curblock = nil;
                    331:     curlevel = 0;
                    332:     nesting = 0;
                    333:     program = insert(identname("", true));
                    334:     program->class = PROG;
                    335:     program->language = primlang;
                    336:     program->symvalue.funcv.beginaddr = CODESTART;
                    337:     program->symvalue.funcv.inline = false;
                    338:     newfunc(program, codeloc(program));
                    339:     findbeginning(program);
                    340:     enterblock(program);
                    341:     curmodule = program;
                    342: }
                    343: 
                    344: /*
                    345:  * Free all the object file information that's being stored.
                    346:  */
                    347: 
                    348: public objfree ()
                    349: {
                    350:     symbol_free();
                    351:     /* keywords_free(); */
                    352:     /* names_free(); */
                    353:     /* dispose(stringtab); */
                    354:     clrfunctab();
                    355: }
                    356: 
                    357: /*
                    358:  * Enter a namelist entry.
                    359:  */
                    360: 
                    361: private enter_nl (name, np)
                    362: String name;
                    363: register struct nlist *np;
                    364: {
                    365:     register Symbol s;
                    366:     register Name n;
                    367: 
                    368:     s = nil;
                    369:     switch (np->n_type) {
                    370:        /*
                    371:         * Build a symbol for the FORTRAN common area.  All GSYMS that follow
                    372:         * will be chained in a list with the head kept in common.offset, and
                    373:         * the tail in common.chain.
                    374:         */
                    375:        case N_BCOMM:
                    376:            if (curcomm) {
                    377:                curcomm->symvalue.common.chain = commchain;
                    378:            }
                    379:            n = identname(name, true);
                    380:            curcomm = lookup(n);
                    381:            if (curcomm == nil) {
                    382:                curcomm = insert(n);
                    383:                curcomm->class = COMMON;
                    384:                curcomm->block = curblock;
                    385:                curcomm->level = program->level;
                    386:                curcomm->symvalue.common.chain = nil;
                    387:            }
                    388:            commchain = curcomm->symvalue.common.chain;
                    389:            break;
                    390: 
                    391:        case N_ECOMM:
                    392:            if (curcomm) {
                    393:                curcomm->symvalue.common.chain = commchain;
                    394:                curcomm = nil;
                    395:            }
                    396:            break;
                    397: 
                    398:        case N_LBRAC:
                    399:            ++nesting;
                    400:            addrstk[nesting] = (linep - 1)->addr;
                    401:            break;
                    402: 
                    403:        case N_RBRAC:
                    404:            --nesting;
                    405:            if (addrstk[nesting] == NOADDR) {
                    406:                exitblock();
                    407:                newfunc(curblock, (linep - 1)->addr);
                    408:                addrstk[nesting] = (linep - 1)->addr;
                    409:            }
                    410:            break;
                    411: 
                    412:        case N_SLINE:
                    413:            enterline((Lineno) np->n_desc, (Address) np->n_value);
                    414:            break;
                    415: 
                    416:        /*
                    417:         * Source files.
                    418:         */
                    419:        case N_SO:
                    420:            n = identname(name, true);
                    421:            enterSourceModule(n, (Address) np->n_value);
                    422:            break;
                    423: 
                    424:        /*
                    425:         * Textually included files.
                    426:         */
                    427:        case N_SOL:
                    428:            enterfile(name, (Address) np->n_value);
                    429:            break;
                    430: 
                    431:        /*
                    432:         * These symbols are assumed to have non-nil names.
                    433:         */
                    434:        case N_GSYM:
                    435:        case N_FUN:
                    436:        case N_STSYM:
                    437:        case N_LCSYM:
                    438:        case N_RSYM:
                    439:        case N_PSYM:
                    440:        case N_LSYM:
                    441:        case N_SSYM:
                    442:        case N_LENG:
                    443:            if (index(name, ':') == nil) {
                    444:                if (not warned) {
                    445:                    warned = true;
                    446:                    printf("warning: old style symbol information ");
                    447:                    printf("found in \"%s\"\n", curfilename());
                    448:                }
                    449:            } else {
                    450:                entersym(name, np);
                    451:            }
                    452:            break;
                    453: 
                    454:        case N_PC:
                    455:        case N_MOD2:
                    456:            break;
                    457: 
                    458:        default:
                    459:            printf("warning:  stab entry unrecognized: ");
                    460:            if (name != nil) {
                    461:                printf("name %s,", name);
                    462:            }
                    463:            printf("ntype %2x, desc %x, value %x'\n",
                    464:                np->n_type, np->n_desc, np->n_value);
                    465:            break;
                    466:     }
                    467: }
                    468: 
                    469: /*
                    470:  * Try to find the symbol that is referred to by the given name.  Since it's
                    471:  * an external, we need to follow a level or two of indirection.
                    472:  */
                    473: 
                    474: private Symbol findsym (n, var_isextref)
                    475: Name n;
                    476: boolean *var_isextref;
                    477: {
                    478:     register Symbol r, s;
                    479: 
                    480:     *var_isextref = false;
                    481:     find(s, n) where
                    482:        (
                    483:            s->level == program->level and (
                    484:                s->class == EXTREF or s->class == VAR or
                    485:                s->class == PROC or s->class == FUNC
                    486:            )
                    487:        ) or (
                    488:            s->block == program and s->class == MODULE
                    489:        )
                    490:     endfind(s);
                    491:     if (s == nil) {
                    492:        r = nil;
                    493:     } else if (s->class == EXTREF) {
                    494:        *var_isextref = true;
                    495:        r = s->symvalue.extref;
                    496:        delete(s);
                    497: 
                    498:        /*
                    499:         * Now check for another level of indirection that could come from
                    500:         * a forward reference in procedure nesting information.  In this case
                    501:         * the symbol has already been deleted.
                    502:         */
                    503:        if (r != nil and r->class == EXTREF) {
                    504:            r = r->symvalue.extref;
                    505:        }
                    506: /*
                    507:     } else if (s->class == MODULE) {
                    508:        s->class = FUNC;
                    509:        s->level = program->level;
                    510:        r = s;
                    511:  */
                    512:     } else {
                    513:        r = s;
                    514:     }
                    515:     return r;
                    516: }
                    517: 
                    518: /*
                    519:  * Create a symbol for a text symbol with no source information.
                    520:  * We treat it as an assembly language function.
                    521:  */
                    522: 
                    523: private Symbol deffunc (n)
                    524: Name n;
                    525: {
                    526:     Symbol f;
                    527: 
                    528:     f = insert(n);
                    529:     f->language = findlanguage(".s");
                    530:     f->class = FUNC;
                    531:     f->type = t_int;
                    532:     f->block = curblock;
                    533:     f->level = program->level;
                    534:     f->symvalue.funcv.src = false;
                    535:     f->symvalue.funcv.inline = false;
                    536:     if (f->chain != nil) {
                    537:        panic("chain not nil in deffunc");
                    538:     }
                    539:     return f;
                    540: }
                    541: 
                    542: /*
                    543:  * Create a symbol for a data or bss symbol with no source information.
                    544:  * We treat it as an assembly language variable.
                    545:  */
                    546: 
                    547: private Symbol defvar (n)
                    548: Name n;
                    549: {
                    550:     Symbol v;
                    551: 
                    552:     v = insert(n);
                    553:     v->language = findlanguage(".s");
                    554:     v->storage = EXT;
                    555:     v->class = VAR;
                    556:     v->type = t_int;
                    557:     v->level = program->level;
                    558:     v->block = curblock;
                    559:     return v;
                    560: }
                    561: 
                    562: /*
                    563:  * Update a symbol entry with a text address.
                    564:  */
                    565: 
                    566: private updateTextSym (s, name, addr)
                    567: Symbol s;
                    568: char *name;
                    569: Address addr;
                    570: {
                    571:     if (s->class == VAR) {
                    572:        s->symvalue.offset = addr;
                    573:     } else {
                    574:        s->symvalue.funcv.beginaddr = addr;
                    575:        if (name[0] == '_') {
                    576:            newfunc(s, codeloc(s));
                    577:            findbeginning(s);
                    578:        }
                    579:     }
                    580: }
                    581: 
                    582: /*
                    583:  * Avoid seeing Pascal labels as text symbols.
                    584:  */
                    585: 
                    586: private boolean PascalLabel (n)
                    587: Name n;
                    588: {
                    589:     boolean b;
                    590:     register char *p;
                    591: 
                    592:     b = false;
                    593:     if (curlang == findlanguage(".p")) {
                    594:        p = ident(n);
                    595:        while (*p != '\0') {
                    596:            if (*p == '_' and *(p+1) == '$') {
                    597:                b = true;
                    598:                break;
                    599:            }
                    600:            ++p;
                    601:        }
                    602:     }
                    603:     return b;
                    604: }
                    605: 
                    606: /*
                    607:  * Check to see if a global _name is already in the symbol table,
                    608:  * if not then insert it.
                    609:  */
                    610: 
                    611: private check_global (name, np)
                    612: String name;
                    613: register struct nlist *np;
                    614: {
                    615:     register Name n;
                    616:     register Symbol t, u;
                    617:     char buf[4096];
                    618:     boolean isextref;
                    619:     integer count;
                    620: 
                    621:     if (not streq(name, "_end")) {
                    622:        if (name[0] == '_') {
                    623:            n = identname(&name[1], true);
                    624:        } else {
                    625:            n = identname(name, true);
                    626:            if (lookup(n) != nil) {
                    627:                sprintf(buf, "$%s", name);
                    628:                n = identname(buf, false);
                    629:            }
                    630:        }
                    631:        if ((np->n_type&N_TYPE) == N_TEXT) {
                    632:            count = 0;
                    633:            t = findsym(n, &isextref);
                    634:            while (isextref) {
                    635:                ++count;
                    636:                updateTextSym(t, name, np->n_value);
                    637:                t = findsym(n, &isextref);
                    638:            }
                    639:            if (count == 0) {
                    640:                if (t == nil) {
                    641:                    if (not PascalLabel(n)) {
                    642:                        t = deffunc(n);
                    643:                        updateTextSym(t, name, np->n_value);
                    644:                        if (tracesyms) {
                    645:                            printdecl(t);
                    646:                        }
                    647:                    }
                    648:                } else {
                    649:                    if (t->class == MODULE) {
                    650:                        u = t;
                    651:                        t = deffunc(n);
                    652:                        t->block = u;
                    653:                        if (tracesyms) {
                    654:                            printdecl(t);
                    655:                        }
                    656:                    }
                    657:                    updateTextSym(t, name, np->n_value);
                    658:                }
                    659:            }
                    660:        } else if ((np->n_type&N_TYPE) == N_BSS or (np->n_type&N_TYPE) == N_DATA) {
                    661:            find(t, n) where
                    662:                t->class == COMMON
                    663:            endfind(t);
                    664:            if (t != nil) {
                    665:                u = (Symbol) t->symvalue.common.offset;
                    666:                while (u != nil) {
                    667:                    u->symvalue.offset = u->symvalue.common.offset+np->n_value;
                    668:                    u = u->symvalue.common.chain;
                    669:                }
                    670:             } else {
                    671:                check_var(np, n);
                    672:            }
                    673:         } else {
                    674:            check_var(np, n);
                    675:        }
                    676:     }
                    677: }
                    678: 
                    679: /*
                    680:  * Check to see if a namelist entry refers to a variable.
                    681:  * If not, create a variable for the entry.  In any case,
                    682:  * set the offset of the variable according to the value field
                    683:  * in the entry.
                    684:  *
                    685:  * If the external name has been referred to by several other symbols,
                    686:  * we must update each of them.
                    687:  */
                    688: 
                    689: private check_var (np, n)
                    690: struct nlist *np;
                    691: register Name n;
                    692: {
                    693:     register Symbol t, u, next;
                    694:     Symbol conflict;
                    695: 
                    696:     t = lookup(n);
                    697:     if (t == nil) {
                    698:        t = defvar(n);
                    699:        t->symvalue.offset = np->n_value;
                    700:        if (tracesyms) {
                    701:            printdecl(t);
                    702:        }
                    703:     } else {
                    704:        conflict = nil;
                    705:        do {
                    706:            next = t->next_sym;
                    707:            if (t->name == n) {
                    708:                if (t->class == MODULE and t->block == program) {
                    709:                    conflict = t;
                    710:                } else if (t->class == EXTREF and t->level == program->level) {
                    711:                    u = t->symvalue.extref;
                    712:                    while (u != nil and u->class == EXTREF) {
                    713:                        u = u->symvalue.extref;
                    714:                    }
                    715:                    u->symvalue.offset = np->n_value;
                    716:                    delete(t);
                    717:                } else if (t->level == program->level and
                    718:                    (t->class == VAR or t->class == PROC or t->class == FUNC)
                    719:                ) {
                    720:                    conflict = nil;
                    721:                    t->symvalue.offset = np->n_value;
                    722:                }
                    723:            }
                    724:            t = next;
                    725:        } while (t != nil);
                    726:        if (conflict != nil) {
                    727:            u = defvar(n);
                    728:            u->block = conflict;
                    729:            u->symvalue.offset = np->n_value;
                    730:        }
                    731:     }
                    732: }
                    733: 
                    734: /*
                    735:  * Check to see if a local _name is known in the current scope.
                    736:  * If not then enter it.
                    737:  */
                    738: 
                    739: private check_local (name, np)
                    740: String name;
                    741: register struct nlist *np;
                    742: {
                    743:     register Name n;
                    744:     register Symbol t, cur;
                    745: 
                    746:     n = identname(name, true);
                    747:     cur = ((np->n_type&N_TYPE) == N_TEXT) ? curmodule : curblock;
                    748:     find(t, n) where t->block == cur endfind(t);
                    749:     if (t == nil) {
                    750:        t = insert(n);
                    751:        t->language = findlanguage(".s");
                    752:        t->type = t_int;
                    753:        t->block = cur;
                    754:        t->storage = EXT;
                    755:        t->level = cur->level;
                    756:        if ((np->n_type&N_TYPE) == N_TEXT) {
                    757:            t->class = FUNC;
                    758:            t->symvalue.funcv.src = false;
                    759:            t->symvalue.funcv.inline = false;
                    760:            t->symvalue.funcv.beginaddr = np->n_value;
                    761:            newfunc(t, codeloc(t));
                    762:            findbeginning(t);
                    763:        } else {
                    764:            t->class = VAR;
                    765:            t->symvalue.offset = np->n_value;
                    766:        }
                    767:     }
                    768: }
                    769: 
                    770: /*
                    771:  * Check to see if a symbol corresponds to a object file name.
                    772:  * For some reason these are listed as in the text segment.
                    773:  */
                    774: 
                    775: private check_filename (name)
                    776: String name;
                    777: {
                    778:     register String mname;
                    779:     register integer i;
                    780:     Name n;
                    781:     Symbol s;
                    782: 
                    783:     mname = strdup(name);
                    784:     i = strlen(mname) - 2;
                    785:     if (i >= 0 and mname[i] == '.' and mname[i+1] == 'o') {
                    786:        mname[i] = '\0';
                    787:        --i;
                    788:        while (mname[i] != '/' and i >= 0) {
                    789:            --i;
                    790:        }
                    791:        n = identname(&mname[i+1], true);
                    792:        find(s, n) where s->block == program and s->class == MODULE endfind(s);
                    793:        if (s == nil) {
                    794:            s = insert(n);
                    795:            s->language = findlanguage(".s");
                    796:            s->class = MODULE;
                    797:            s->symvalue.funcv.beginaddr = 0;
                    798:            findbeginning(s);
                    799:        }
                    800:        if (curblock->class != PROG) {
                    801:            exitblock();
                    802:            if (curblock->class != PROG) {
                    803:                exitblock();
                    804:            }
                    805:        }
                    806:        enterblock(s);
                    807:        curmodule = s;
                    808:     }
                    809: }
                    810: 
                    811: /*
                    812:  * Check to see if a symbol is about to be defined within an unnamed block.
                    813:  * If this happens, we create a procedure for the unnamed block, make it
                    814:  * "inline" so that tracebacks don't associate an activation record with it,
                    815:  * and enter it into the function table so that it will be detected
                    816:  * by "whatblock".
                    817:  */
                    818: 
                    819: public chkUnnamedBlock ()
                    820: {
                    821:     register Symbol s;
                    822:     static int bnum = 0;
                    823:     char buf[100];
                    824:     Address startaddr;
                    825: 
                    826:     if (nesting > 0 and addrstk[nesting] != NOADDR) {
                    827:        startaddr = (linep - 1)->addr;
                    828:        ++bnum;
                    829:        sprintf(buf, "$b%d", bnum);
                    830:        s = insert(identname(buf, false));
                    831:        s->language = curlang;
                    832:        s->class = PROC;
                    833:        s->symvalue.funcv.src = false;
                    834:        s->symvalue.funcv.inline = true;
                    835:        s->symvalue.funcv.beginaddr = startaddr;
                    836:        enterblock(s);
                    837:        newfunc(s, startaddr);
                    838:        addrstk[nesting] = NOADDR;
                    839:     }
                    840: }
                    841: 
                    842: /*
                    843:  * Compilation unit.  C associates scope with filenames
                    844:  * so we treat them as "modules".  The filename without
                    845:  * the suffix is used for the module name.
                    846:  *
                    847:  * Because there is no explicit "end-of-block" mark in
                    848:  * the object file, we must exit blocks for the current
                    849:  * procedure and module.
                    850:  */
                    851: 
                    852: private enterSourceModule (n, addr)
                    853: Name n;
                    854: Address addr;
                    855: {
                    856:     register Symbol s;
                    857:     Name nn;
                    858:     String mname, suffix;
                    859: 
                    860:     mname = strdup(ident(n));
                    861:     if (rindex(mname, '/') != nil) {
                    862:        mname = rindex(mname, '/') + 1;
                    863:     }
                    864:     suffix = rindex(mname, '.');
                    865:     if (suffix > mname && *(suffix-1) == '.') {
                    866:        /* special hack for C++ */
                    867:        --suffix;
                    868:     }
                    869:     curlang = findlanguage(suffix);
                    870:     if (curlang == findlanguage(".f")) {
                    871:        strip_ = true;
                    872:     } 
                    873:     if (suffix != nil) {
                    874:        *suffix = '\0';
                    875:     }
                    876:     if (not (*language_op(curlang, L_HASMODULES))()) {
                    877:        if (curblock->class != PROG) {
                    878:            exitblock();
                    879:            if (curblock->class != PROG) {
                    880:                exitblock();
                    881:            }
                    882:        }
                    883:        nn = identname(mname, true);
                    884:        if (curmodule == nil or curmodule->name != nn) {
                    885:            s = insert(nn);
                    886:            s->class = MODULE;
                    887:            s->symvalue.funcv.beginaddr = 0;
                    888:            findbeginning(s);
                    889:        } else {
                    890:            s = curmodule;
                    891:        }
                    892:        s->language = curlang;
                    893:        enterblock(s);
                    894:        curmodule = s;
                    895:     }
                    896:     if (program->language == nil) {
                    897:        program->language = curlang;
                    898:     }
                    899:     warned = false;
                    900:     enterfile(ident(n), addr);
                    901:     initTypeTable();
                    902: }
                    903: 
                    904: /*
                    905:  * Allocate file and line tables and initialize indices.
                    906:  */
                    907: 
                    908: private allocmaps (nf, nl)
                    909: integer nf, nl;
                    910: {
                    911:     if (filetab != nil) {
                    912:        dispose(filetab);
                    913:     }
                    914:     if (linetab != nil) {
                    915:        dispose(linetab);
                    916:     }
                    917:     filetab = newarr(Filetab, nf);
                    918:     linetab = newarr(Linetab, nl);
                    919:     filep = filetab;
                    920:     linep = linetab;
                    921: }
                    922: 
                    923: /*
                    924:  * Add a file to the file table.
                    925:  *
                    926:  * If the new address is the same as the previous file address
                    927:  * this routine used to not enter the file, but this caused some
                    928:  * problems so it has been removed.  It's not clear that this in
                    929:  * turn may not also cause a problem.
                    930:  */
                    931: 
                    932: private enterfile (filename, addr)
                    933: String filename;
                    934: Address addr;
                    935: {
                    936:     filep->addr = addr;
                    937:     filep->filename = filename;
                    938:     filep->lineindex = linep - linetab;
                    939:     ++filep;
                    940: }
                    941: 
                    942: /*
                    943:  * Since we only estimated the number of lines (and it was a poor
                    944:  * estimation) and since we need to know the exact number of lines
                    945:  * to do a binary search, we set it when we're done.
                    946:  */
                    947: 
                    948: private setnlines ()
                    949: {
                    950:     nlhdr.nlines = linep - linetab;
                    951: }
                    952: 
                    953: /*
                    954:  * Similarly for nfiles ...
                    955:  */
                    956: 
                    957: private setnfiles ()
                    958: {
                    959:     nlhdr.nfiles = filep - filetab;
                    960:     setsource(filetab[0].filename);
                    961: }

unix.superglobalmegacorp.com

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