Annotation of coherent/b/bin/as/sym.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Symbol table functions.
        !             3:  */
        !             4: #include <asm.h>
        !             5: #include <symtab.h>
        !             6: #include <y_tab.h>
        !             7: 
        !             8: #define SHASH  ((unsigned short)1021)  /* symbol table hash */
        !             9: sym    **symhash;                      /* macros equs and symbols */
        !            10: static char    *lastSym;               /* last symbol defined */
        !            11: 
        !            12: /*
        !            13:  * This routine is called early in the
        !            14:  * game to set up the hashtable.
        !            15:  */
        !            16: void
        !            17: symInit()
        !            18: {
        !            19:        register psym  *sp;
        !            20:        register unsigned short ht;
        !            21: 
        !            22:        symhash = (sym **)alloc(SHASH * sizeof(sp));
        !            23: 
        !            24:        /* init symbol table */
        !            25:        for(sp = symtab;  sp < symtab  + SYMCOUNT; sp++) {
        !            26:                if (rswitch && ('%' == sp->name[0]) && sp->name[1])
        !            27:                        sp->name++;
        !            28:                sp->next = symhash[ht = hash(sp->name) % SHASH];
        !            29:                symhash[ht] = (sym *)sp;
        !            30:        }
        !            31: 
        !            32:        lastSym = "";   /* last symbol defined is null */
        !            33: }
        !            34: 
        !            35: /*
        !            36:  * Free macro space.
        !            37:  */
        !            38: freeMac(mp)
        !            39: register macro *mp;
        !            40: {
        !            41:        freeList((parm *)mp->first);    /* free lines */
        !            42:        freeList(mp->names);            /* free parms */
        !            43:        free((char *)mp);               /* free macro */
        !            44: }
        !            45: 
        !            46: /*
        !            47:  * Returns a 1 if this symbol should not be output
        !            48:  * to the symbol table.
        !            49:  */
        !            50: static
        !            51: notSym(sp)
        !            52: register sym *sp;
        !            53: {
        !            54:        /* don't out put symbols given numbers already */
        !            55:        if (sp->num)
        !            56:                return (1);
        !            57: 
        !            58:        /* don't output unused .globls */
        !            59:        if ((sp->flag & S_EXREF) && !(sp->flag & S_USED))
        !            60:                return (1);
        !            61: 
        !            62:        if (!(sp->flag & (S_EXREF|S_EXDEF))) {
        !            63:                register char *p;
        !            64: 
        !            65:                /* don't output non global symbols if -x option */
        !            66:                if (xswitch)
        !            67:                        return (1);
        !            68: 
        !            69:                p = SYMNAME(sp);
        !            70: 
        !            71:                /* don't output symbols starting .L is -X option */
        !            72:                if (Xswitch && (p[0] == '.') && (p[1] == 'L'))
        !            73:                        return (1);
        !            74: 
        !            75:                /* don't output local symbols */
        !            76:                if (NULL != strchr(p, ';'))
        !            77:                        return (1);
        !            78:        }
        !            79: 
        !            80:        /* don't output dot symbol */
        !            81:        if (&dot == (psym *)sp)
        !            82:                return (1);
        !            83: 
        !            84:        return (0);
        !            85: }
        !            86: 
        !            87: /*
        !            88:  * Give numbers to all identifier symbols.
        !            89:  * Mark undefined symbols as exref if -g.
        !            90:  * Delete symbols defined by macro, equs and equ.
        !            91:  * Called at the end of pass 0 and 1.
        !            92:  */
        !            93: unsigned short
        !            94: symGlob(number)
        !            95: {
        !            96:        register sym *sp, **psp;
        !            97:        register unsigned short i;
        !            98: 
        !            99:        for(i = 0; i < SHASH; i++) {
        !           100:                for(psp = symhash + i; NULL != (sp = *psp); ) {
        !           101:                        switch(sp->type) {
        !           102:                        case MACTYPE: /* delete macro */
        !           103:                        case MACSTR:  /* delete define */
        !           104:                                *psp = sp->next;        /* rechain list */
        !           105:                                freeMac((macro *)sp);
        !           106:                                continue;
        !           107: 
        !           108:                        case NUMBER: /* delete equ */
        !           109:                                if ((2 == pass) && (sp->flag & S_EXDEF))
        !           110:                                        sp->num = number++;
        !           111:                                sp->type = IDENTIFIER;
        !           112:                                sp->flag = S_UNDEF;
        !           113:                                break;
        !           114: 
        !           115:                        case IDENTIFIER:
        !           116:                                if((sp->flag & S_UNDEF) && gswitch)
        !           117:                                        sp->flag = (S_EXREF | S_USED);
        !           118: 
        !           119:                                if((2 == pass) && !notSym(sp))
        !           120:                                        sp->num = number++;
        !           121:                        }
        !           122:                        psp = &(sp->next);      /* follow list */
        !           123:                }
        !           124:        }
        !           125:        lastSym = "";
        !           126:        return(number);
        !           127: }
        !           128: 
        !           129: /*
        !           130:  * Dump symbol data
        !           131:  */
        !           132: void
        !           133: symDump(output, limit)
        !           134: int (*output)();
        !           135: long limit;
        !           136: {
        !           137:        register sym *sp;
        !           138:        register i;
        !           139: 
        !           140:        for(i = 0; i < SHASH; i++)
        !           141:                for(sp = symhash[i]; NULL != sp; sp = sp->next) {
        !           142:                        if(sp->num > limit) {
        !           143:                                switch(sp->type) {
        !           144:                                case NUMBER:
        !           145:                                case IDENTIFIER:
        !           146:                                        (*output)(sp);
        !           147:                                }
        !           148:                        }
        !           149:                }
        !           150: }
        !           151: 
        !           152: /*
        !           153:  * This is called when debug records are created. It repoints
        !           154:  * the symbol number to one of the debug records. symDump then
        !           155:  * uses this information to avoid dumping the symbol twice.
        !           156:  * This means debug data can seriously screw up an output file
        !           157:  * if it is wrong.
        !           158:  */
        !           159: symReNumber(id, number)
        !           160: char *id;
        !           161: int number;
        !           162: {
        !           163:        short i;
        !           164:        register sym *sp;
        !           165: 
        !           166:        for(sp = symhash[i = hash(id) % SHASH];
        !           167:            sp != NULL;
        !           168:            sp = sp->next) {
        !           169:                if(!strcmp(id, SYMNAME(sp))) {
        !           170:                        sp->num = number;
        !           171:                        break;
        !           172:                }
        !           173:        }
        !           174: }
        !           175: 
        !           176: /*
        !           177:  * Undefined symbol message.
        !           178:  */
        !           179: static void
        !           180: unDefMsg(id)
        !           181: char *id;
        !           182: {
        !           183:        char *pt;
        !           184: 
        !           185:        if(NULL != (pt = strchr(id, ';'))) {
        !           186:                *pt = '\0';
        !           187:                yyerror("Undefined symbol '?%s'", id);
        !           188:                /* NODOC */
        !           189:                *pt = ';';
        !           190:        }
        !           191:        else
        !           192:                yyerror("Undefined symbol '%s'", id);
        !           193:                /* A symbol was used without defining it or using
        !           194:                 * a \fB-g\fR option.
        !           195:                 * You must define local symbols. */
        !           196: }
        !           197: 
        !           198: /*
        !           199:  * Redefined symbol message.
        !           200:  */
        !           201: static void
        !           202: redef(id)
        !           203: char *id;
        !           204: {
        !           205:        yyerror("Redefinition of '%s'", id);
        !           206:        /* An assembler internal symbol is being redefined. */
        !           207: }
        !           208: 
        !           209: /*
        !           210:  * Duplicate symbol message.
        !           211:  */
        !           212: static void
        !           213: dupsym(id)
        !           214: register char *id;
        !           215: {
        !           216:        register char *pt;
        !           217: 
        !           218:        if(NULL != (pt = strchr(id, ';'))) {
        !           219:                *pt = '\0';
        !           220:                yyerror("Duplicate symbol '?%s'", id);
        !           221:                /* NODOC */
        !           222:                *pt = ';';
        !           223:        }
        !           224:        else
        !           225:                yyerror("Duplicate symbol '%s'", id);
        !           226:        /* \fIsymbol\fR is defined on two different lines. */
        !           227: }
        !           228: 
        !           229: /*
        !           230:  * Lookup the name `id' in a hashtable.
        !           231:  * If it is not found build it.
        !           232:  */
        !           233: sym *
        !           234: symLookUp(id, flag, loc, sg)
        !           235: long loc;
        !           236: char *id;
        !           237: {
        !           238:        register sym *sp;
        !           239:        char *locSym;
        !           240:        short i;
        !           241: 
        !           242:        if('?' == id[0] && id[1]) {     /* local symbol */
        !           243:                locSym = galloc((unsigned)(strlen(id) + strlen(lastSym) + 1));
        !           244:                sprintf(locSym, "%s;%s", id + 1, lastSym);
        !           245:                id = locSym;
        !           246:        }
        !           247:        else
        !           248:                locSym = NULL;
        !           249: 
        !           250:        for(sp = symhash[i = hash(id) % SHASH];
        !           251:            sp != NULL;
        !           252:            sp = sp->next) {
        !           253:                if((sp->type > MACSCAN) && !strcmp(id, SYMNAME(sp))) {
        !           254:                        if(2 == pass) {
        !           255:                                switch(flag) {
        !           256:                                case S_UNDEF: /* we are looking for it */
        !           257:                                        if((S_UNDEF & sp->flag) &&
        !           258:                                           (DEFINED != lastToken) &&
        !           259:                                           (S_GLOBL != kind))
        !           260:                                                unDefMsg(id);
        !           261:                                        if (sp->flag & S_ASYM)
        !           262:                                                sp->flag |= S_USED;
        !           263:                                        return(sp);
        !           264: 
        !           265:                                case S_LOCAL: /* being defined here */
        !           266:                                        if(!(sp->flag & S_ASYM))
        !           267:                                                redef(id);
        !           268: 
        !           269:                                        else if(sp->flag & S_EXREF) {
        !           270:                                                sp->flag &= ~S_EXREF;
        !           271:                                                sp->flag |= S_EXDEF|S_LOCAL;
        !           272:                                        }
        !           273:                                        else if(statement != sp->statement)
        !           274:                                                dupsym(id);
        !           275:                                        else if((sp->loc != loc) ||
        !           276:                                                (sp->sg != sg))
        !           277:                                                yyerror("Phase error '%s'",
        !           278:                                                        id);
        !           279:                /* A symbol is defined one way in one phase of the assembly
        !           280:                 * and another way in the next phase. */
        !           281:                                        break;
        !           282: 
        !           283:                                case S_XSYM:  /*  a number */
        !           284:                                        if(!(sp->flag & S_ASYM)) {
        !           285:                                                redef(id);
        !           286:                                                return(sp);
        !           287:                                        }
        !           288:                                        if (sp->flag & S_LOCAL)
        !           289:                                                dupsym(id);
        !           290:                                        if (sp->flag & S_EXREF) {
        !           291:                                                sp->flag &= ~S_EXREF;
        !           292:                                                sp->flag |= S_EXDEF;
        !           293:                                        }
        !           294:                                        sp->flag &= ~(S_UNDEF|S_LOCAL);
        !           295:                                        sp->flag |= S_XSYM;
        !           296:                                        sp->type = NUMBER;
        !           297:                                        sp->loc  = loc;
        !           298:                                        sp->sg   = -1;  /* absolute */
        !           299:                                        return(sp);
        !           300:                                }
        !           301:                                break;
        !           302:                        }
        !           303:                        else {  /* pass 0 and 1 */
        !           304:                                switch(flag) {
        !           305:                                case S_UNDEF:   /* looking for it */
        !           306:                                        if (sp->flag & S_ASYM)
        !           307:                                                sp->flag |= S_USED;
        !           308:                                        return(sp);
        !           309: 
        !           310:                                case S_LOCAL:   /* being defined here */
        !           311:                                        if(!(sp->flag & S_ASYM))
        !           312:                                                return(sp);
        !           313: 
        !           314:                                        sp->statement = statement;
        !           315: 
        !           316:                                        if(sp->flag & S_EXREF) {
        !           317:                                                sp->flag &= ~S_EXREF;
        !           318:                                                sp->flag |= S_EXDEF|S_LOCAL;
        !           319:                                        }
        !           320:                                        else {
        !           321:                                                sp->flag &= ~S_UNDEF;
        !           322:                                                sp->flag |= flag;
        !           323:                                        }
        !           324:                                        break;
        !           325: 
        !           326:                                case S_XSYM:  /* a number */
        !           327:                                        if(!(sp->flag & S_ASYM))
        !           328:                                                return(sp);
        !           329:                                        if (sp->flag & S_EXREF) {
        !           330:                                                sp->flag &= ~S_EXREF;
        !           331:                                                sp->flag |= S_EXDEF;
        !           332:                                        }
        !           333:                                        sp->flag &= ~(S_UNDEF|S_LOCAL);
        !           334:                                        sp->flag |= S_XSYM;
        !           335:                                        sp->type = NUMBER;
        !           336:                                        sp->loc  = loc;
        !           337:                                        sp->sg   = -1;  /* absolute */
        !           338:                                        return(sp);
        !           339:                                }
        !           340:                                break;
        !           341:                        }
        !           342:                }
        !           343:        }
        !           344: 
        !           345:        if(NULL == sp)  {
        !           346:                if (DEFINED == lastToken) {
        !           347:                        static psym sy = {
        !           348:                                NULL, IDENTIFIER, 0, 0, 0, S_UNDEF,
        !           349:                                NULL, 0, 0, NULL
        !           350:                        };
        !           351: 
        !           352:                        return (&sy);
        !           353:                }
        !           354:                sp = (sym *) scpy(id, offset(sym, name));
        !           355:                sp->next = symhash[i];
        !           356:                sp->ref = symhash[i] = sp;
        !           357:                sp->flag = flag;
        !           358:        }
        !           359:        sp->type = IDENTIFIER;
        !           360:        switch(flag) {
        !           361:        case S_UNDEF:
        !           362:                if (S_GLOBL != kind)
        !           363:                        sp->flag |= S_USED;
        !           364:                break;
        !           365:        case S_XSYM:
        !           366:                sp->type = NUMBER;
        !           367:                sp->loc = loc;
        !           368:                sp->sg   = -1;  /* absolute */
        !           369:                break;
        !           370:        case S_LOCAL:
        !           371:                sp->loc = loc;
        !           372:                sp->sg = sg;
        !           373:                sp->statement = statement;
        !           374:                if(NULL == locSym)
        !           375:                        lastSym = sp->name;
        !           376:        }
        !           377:        return(sp);
        !           378: }
        !           379: 
        !           380: /*
        !           381:  * Lookup a name in opcodes.
        !           382:  * return it's index or -1.
        !           383:  */
        !           384: short
        !           385: opLookUp(id)
        !           386: char *id;
        !           387: {
        !           388:        register nhash *op;
        !           389:        short i, l;
        !           390: 
        !           391:        for (l = strlen(id), i = hash(id) % OPCOUNT;;) {
        !           392:                if ((l == (op = hashCodes + i)->nlen) &&
        !           393:                   !memcmp(id, (charLump + op->nameIx), l)) {
        !           394:                        choices = op->count;
        !           395:                        return(op->prefIx);
        !           396:                }
        !           397:                if (-1 == (i = op->next))
        !           398:                        return (-1);
        !           399:        }
        !           400: }
        !           401: 
        !           402: /*
        !           403:  * Remove an entry from the opcode table.
        !           404:  */
        !           405: void
        !           406: opDelete(id)
        !           407: char *id;
        !           408: {
        !           409:        register nhash *op;
        !           410:        short i, l;
        !           411: 
        !           412:        l = strlen(id);
        !           413:        for(i = hash(id) % OPCOUNT; -1 != i; i = op->next) {
        !           414:                if((l == (op = hashCodes + i)->nlen) &&
        !           415:                   !memcmp(id, (charLump + op->nameIx), l)) {
        !           416:                        op->nlen = 0;
        !           417:                        return;
        !           418:                }
        !           419:        }
        !           420:        return;
        !           421: }
        !           422: 
        !           423: /*
        !           424:  * Look up macros and equs symbols. Shares table with symbols.
        !           425:  */
        !           426: macro *
        !           427: macLookUp(id, type)
        !           428: char *id;
        !           429: {
        !           430:        register macro *mp;
        !           431: 
        !           432:        for(mp = (macro *)symhash[hash(id) % SHASH];
        !           433:            mp != NULL;
        !           434:            mp = mp->next)
        !           435:                if((mp->type == type) && !strcmp(id, mp->name))
        !           436:                        return(mp);
        !           437:        return(NULL);
        !           438: }
        !           439: 
        !           440: /*
        !           441:  * Delete a macro or equs.
        !           442:  */
        !           443: macDelete(s, t)
        !           444: char *s;
        !           445: short t;
        !           446: {
        !           447:        register macro *mp, **pmp;
        !           448:        short ht;
        !           449: 
        !           450:        for(pmp = (macro **)(symhash + (ht = hash(s) % SHASH));
        !           451:            NULL != (mp = *pmp);
        !           452:            pmp = &(mp->next)) {
        !           453:                if((mp->type == t) && !strcmp(s, mp->name)) {
        !           454:                        *pmp = mp->next;        /* unChain */
        !           455:                        freeMac(mp);
        !           456:                        break;
        !           457:                }
        !           458:        }
        !           459:        return(ht);
        !           460: }
        !           461: 
        !           462: /*
        !           463:  * Define macro or equs symbol.
        !           464:  * Shares symbol table with other symbols.
        !           465:  */
        !           466: void
        !           467: defMac(s, p, t)
        !           468: char *s;
        !           469: parm *p;
        !           470: short t;
        !           471: {
        !           472:        register macro *tmp;
        !           473:        short ht;
        !           474: 
        !           475:        ht = macDelete(s, t);   /* remove old form */
        !           476:        tmp = (macro *)scpy(s, offset(macro, name));
        !           477: 
        !           478:        tmp->names = p; /* parm names */
        !           479:        umList(p);
        !           480: 
        !           481:        tmp->next = (macro *)symhash[ht];
        !           482:        symhash[ht] = (sym *)tmp;
        !           483:        if(MACTYPE == (tmp->type = t)) {
        !           484:                newLevel(INMACDEF);
        !           485:                inMacDef = tmp;
        !           486:        }
        !           487: }

unix.superglobalmegacorp.com

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