Annotation of coherent/b/bin/as/sym.c, revision 1.1.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.