Annotation of 3BSD/cmd/as/assyms.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: #include <stdio.h>
                      3: #include "as.h"
                      4: #include "assyms.h"
                      5: 
                      6: struct allocbox        *allochead;
                      7: struct allocbox        *alloctail;
                      8: struct symtab          *nextsym;
                      9: struct allocbox        *newbox;
                     10: char                   *namebuffer;
                     11: int                    symsleft;
                     12: 
                     13: symtabinit()
                     14: {
                     15:        allochead = 0;
                     16:        alloctail = 0;
                     17:        nextsym = 0;
                     18:        symsleft = 0;
                     19: }
                     20: 
                     21: /*
                     22:  *     Install all known instructions in the symbol table
                     23:  */
                     24: syminstall()
                     25: {
                     26:        register        struct  instab  *ip;
                     27:        register        struct  symtab  **hp;
                     28:        register        char    *p1, *p2;
                     29: 
                     30:        for (ip=instab; ip->name[0]!=0; ip++) {
                     31:                p1 = ip->name;
                     32:                p2 = yytext;
                     33:                while (*p2++ = *p1++);
                     34:                hp = lookup(0);         /* 0 => don't install this*/
                     35:                if (*hp==NULL) {
                     36:                        *hp = (struct symtab *)ip;
                     37:                        if (   (ip->tag!=INSTn)
                     38:                            && (ip->tag!=INST0)
                     39:                            && (ip->tag!=0))
                     40:                                continue; /* was pseudo-op */
                     41:                        itab[ip->opcode & 0xFF] = ip;
                     42:                }
                     43:        }
                     44: }      /*end of syminstall*/
                     45: 
                     46: 
                     47: /*
                     48:  *     Assign final values to symbols,
                     49:  *     and overwrite the index field with its relative position in
                     50:  *     the symbol table we give to the loader.
                     51:  */
                     52: extern struct hdr hdr;
                     53: 
                     54: freezesymtab()
                     55: {
                     56:        register        struct  symtab  *sp;
                     57:                                long    bs;
                     58:        register        int     relpos = 0;
                     59: #ifdef SORTEDOUTPUT
                     60:        register        struct  symtab  **cosp;
                     61: #else
                     62:        register        struct  symtab          *ubsp;
                     63:        register        struct  allocbox        *allocwalk;
                     64: #endif
                     65: 
                     66: #ifdef SORTEDOUTPUT
                     67:        SYMITERATE(cosp, sp)
                     68: #else
                     69:        DECLITERATE(allocwalk, sp, ubsp)
                     70: #endif
                     71:        {
                     72:                if (sp->tag >= IGNOREBOUND)
                     73:                        continue;               /*totally ignore jxxx entries */
                     74:                /*
                     75:                 *      Ignore stabs, but give them a symbol table index
                     76:                 */
                     77:                if (sp->type & STABFLAG)
                     78:                        goto assignindex;
                     79:                if ((sp->type&XTYPE)==XUNDEF)
                     80:                        sp->type = XXTRN+XUNDEF;
                     81:                else if ((sp->type&XTYPE)==XDATA)
                     82:                        sp->value += usedot[sp->index].xvalue;
                     83:                else if ((sp->type&XTYPE)==XTEXT)
                     84:                        sp->value += usedot[sp->index].xvalue;
                     85:                else if ((sp->type&XTYPE)==XBSS) {
                     86:                        bs = sp->value;
                     87:                        sp->value = hdr.bsize + datbase;
                     88:                        hdr.bsize += bs;
                     89:                }
                     90:           assignindex:
                     91:                if (    (sp->name[0] != 'L')
                     92:                     || (sp->tag != LABELID)
                     93:                     || savelabels
                     94:                     )                  /*then, we will write it later on*/
                     95:                                sp->index = relpos++;
                     96:        }
                     97: }
                     98: 
                     99: 
                    100: 
                    101: /*
                    102:  *     For all of the stabs that had their final value undefined during pass 1
                    103:  *     and during pass 2 assign a final value.
                    104:  *     We have already given stab entrys a initial approximation
                    105:  *     when we constsructed the sorted symbol table.
                    106:  *     Iteration order doesn't matter.
                    107:  */
                    108: stabfix() {
                    109:        register struct symtab *sp, **cosp;
                    110:        register struct symtab *p;
                    111:        
                    112:        SYMITERATE(cosp, sp){
                    113:                if(sp->ptype && (sp->type & STABFLAG)) {        
                    114:                        p = sp->dest;   
                    115:                        sp->value = p->value;   
                    116:                        sp->index = p->index;
                    117:                        sp->type = p->type;
                    118: #ifdef DSTAB
                    119:                        printf("STABFIX: %s (old %s) to %d offsets %d %d\n",
                    120:                                sp->name, p->name, sp->value, sp, p);
                    121: #endif
                    122:                }
                    123:        }
                    124: }
                    125: 
                    126: char *Calloc(number, size)
                    127:        int     number, size;
                    128: {
                    129:        register        char *newstuff;
                    130:        newstuff = (char *)sbrk(number*size);
                    131:        if ((int)newstuff == -1){
                    132:                yyerror("Ran out of Memory");
                    133:                delexit();
                    134:        }
                    135:        return(newstuff);
                    136: }
                    137: 
                    138: struct symtab * symalloc()
                    139: {
                    140:        if (symsleft == 0){
                    141:                register        int     *p;
                    142: 
                    143:                newbox = (struct allocbox *)Calloc(1,ALLOCQTY);
                    144:                symsleft = SYMDALLOP;
                    145:                nextsym = &newbox->symslots[0];
                    146:                namebuffer = &newbox->symnames[0];
                    147:                p = (int *)(&newbox->symnames[SYMDALLOP * NCPS]);
                    148:                while ( p > (int *)newbox){
                    149:                        *--p = 0;
                    150:                }
                    151:                if (alloctail == 0){
                    152:                        allochead = alloctail = newbox;
                    153:                } else {
                    154:                        alloctail->nextalloc = newbox;
                    155:                        alloctail = newbox;
                    156:                }
                    157:        }
                    158:        --symsleft;
                    159:        ++nsyms;
                    160:        nextsym->name = namebuffer;
                    161:        namebuffer += NCPS;
                    162:        return(nextsym++);
                    163: }
                    164: 
                    165: symcmp(pptr, qptr)
                    166:        struct symtab **pptr, **qptr;
                    167: {
                    168:        register struct symtab *p = *pptr;
                    169:        register struct symtab *q = *qptr;
                    170:        if (p->index < q->index)
                    171:                return(-1);
                    172:        if (p->index > q->index)
                    173:                return(1);
                    174:        if (p->value < q->value)
                    175:                return(-1);
                    176:        if (p->value > q->value)
                    177:                return(1);
                    178:        /*
                    179:         *      Force jxxx entries to virtually preceed labels defined
                    180:         *      to follow the jxxxx instruction, so that bumping the
                    181:         *      jxxx instruction correctly fixes up the following labels
                    182:         */
                    183:        if (p->tag >= IGNOREBOUND)      /*p points to a jxxx*/
                    184:                return(-1);             
                    185:        if (q->tag >= IGNOREBOUND)
                    186:                return(1);
                    187:        /*
                    188:         *      both are now just plain labels; the relative order doesn't
                    189:         *      matter.  Both can't be jxxxes, as they would have different
                    190:         *      values.
                    191:         */
                    192:        return(0);                      
                    193: }      /*end of symcmp*/
                    194: 
                    195: /*
                    196:  *     We construct the auxiliary table of pointers, symptrs and
                    197:  *     symdelim
                    198:  *     We also assign preliminary values to stab entries that did not yet
                    199:  *     have an absolute value (because they initially referred to
                    200:  *     forward references). We don't worry about .stabds, as they
                    201:  *     already have an estimated final value
                    202:  */
                    203: 
                    204: sortsymtab()
                    205: {
                    206:        register        struct  symtab  *sp;
                    207:        register        struct  symtab  **cowalk;
                    208:        register        struct  allocbox        *allocwalk;
                    209:                        struct  symtab  *ubsp;
                    210:                                int     segno;
                    211:                                int     slotno;
                    212:                                int     symsin; /*number put into symptrs*/
                    213: 
                    214:        symptrs =  (struct symtab **)Calloc(nsyms + 2, sizeof *symptrs);
                    215:        /*
                    216:         *      Allocate one word at the beginning of the symptr array
                    217:         *      so that backwards scans through the symptr array will
                    218:         *      work correctly while scanning through the zeroth segment
                    219:         */
                    220:        *symptrs++ = 0;
                    221:        cowalk = symptrs;
                    222:        symsin = 0;
                    223:        DECLITERATE(allocwalk, sp, ubsp) {
                    224:                if (sp->ptype && (sp->type &STABFLAG)){
                    225:                        sp->value = sp->dest->value;
                    226:                        sp->index = sp->dest->index;
                    227:                }
                    228:                if (symsin >= nsyms)
                    229:                        yyerror("INTERNAL ERROR: overfilled symbol table indirection table");
                    230:                *cowalk++ = sp;
                    231:                symsin++;
                    232:        }
                    233:        if (symsin != nsyms)
                    234:                yyerror("INTERNAL ERROR: installed %d syms, should have installed %d",
                    235:                        symsin, nsyms);
                    236:        symptrub = &symptrs[nsyms ];
                    237:        qsort(symptrs, nsyms, sizeof *symptrs, symcmp);
                    238:        symdelim[0] = symptrs;
                    239:        for (cowalk = symptrs, sp = *cowalk, segno = 0, slotno = 1;
                    240:             segno < NLOC + NLOC;
                    241:             segno++, slotno++){
                    242:                for (; sp && sp->index == segno; sp = *++cowalk);
                    243:                symdelim[slotno] = cowalk;      /*forms the ub delimeter*/
                    244:        }
                    245: }      /*end of sortsymtab*/
                    246: 
                    247: #ifdef DEBUG
                    248: dumpsymtab()
                    249: {
                    250:        register        int     segno;
                    251:        register        struct symtab *sp, **cosp, *ub;
                    252:        char            *tagstring();
                    253: 
                    254:        printf("Symbol Table dump:\n");
                    255:        for (segno = 0; segno < NLOC + NLOC; segno++){
                    256:                printf("Segment number: %d\n", segno);
                    257:                SEGITERATE(segno, 0, 0, cosp, sp, ub, ++){
                    258:                        printf("\tSeg: %d \"%8.8s\" value: %d index: %d tag %s\n",
                    259:                                segno, sp->name, sp->value, sp->index, tagstring(sp->tag));
                    260:                        printf("\t\ttype: %d jxbump %d jxfear: %d\n",
                    261:                                sp->type, sp->jxbump, sp->jxfear);
                    262:                }
                    263:                printf("\n\n");
                    264:        }
                    265: }
                    266: 
                    267: static char tagbuff[4];
                    268: 
                    269: char *tagstring(tag)
                    270:        unsigned        char    tag;
                    271: {
                    272:        switch(tag){
                    273:                case JXACTIVE:          return("active");
                    274:                case JXNOTYET:          return("notyet");
                    275:                case JXALIGN:           return("align");
                    276:                case JXQUESTIONABLE:    return("jxquestionable");
                    277:                case JXINACTIVE:        return("inactive");
                    278:                case JXTUNNEL:          return("tunnel");
                    279:                case OBSOLETE:          return("obsolete");
                    280:                case IGNOREBOUND:       return("ignorebound");
                    281:                case STABFLOATING:      return("stabfloating");
                    282:                case STABFIXED:         return("stabfixed");
                    283:                case LABELID:           return("labelid");
                    284:                case OKTOBUMP:          return("oktobump");
                    285:                case ISET:              return("iset");
                    286:                case ILSYM:             return("ilsym");
                    287:                default:                sprintf(tagbuff,"%d", tag);
                    288:                                        return(tagbuff);
                    289:        }
                    290: }
                    291: #endif
                    292: 
                    293: #define        HASHCLOGGED     (NHASH * 3 ) / 4
                    294: 
                    295: struct symtab **lookup(instflg)
                    296:        int     instflg;                /* 0: don't install */
                    297: {
                    298:        register int            ihash;
                    299:        register struct symtab  **hp;
                    300:        register char           *p1, *p2;
                    301:        register        int     i;
                    302: 
                    303: #ifdef METRIC
                    304:        nhashed++;
                    305: #endif
                    306: 
                    307:        /*
                    308:         *      All strings passed in in yytext had better have
                    309:         *      a trailing null.  Strings are placed in yytext for
                    310:         *      hashing by syminstall() and yylex()
                    311:         */
                    312:        for (ihash = 0, p1 = yytext ; *p1; ihash <<= 2, ihash += *p1++);
                    313:        ihash += p1[-1] << 5;
                    314:        ihash %= NHASH;
                    315:        if (ihash < 0) ihash += NHASH;
                    316:        hp = &hshtab[ihash];
                    317:        ihash = 1;              /*now, it counts the number of times we rehash*/
                    318:        while (*hp) {
                    319:                p1 = yytext;
                    320:                p2 = (*hp)->name;
                    321:                for (i = 0; (i<NCPS) && *p1; i++)
                    322:                        if (*p1++ != *p2++)
                    323:                                goto no;
                    324:                if (i >= NCPS)          /*both symbols are maximal length*/
                    325:                        return(hp);
                    326:                if (*p2 == 0)   /*assert *p1 == 0*/
                    327:                        return(hp);
                    328:            no:
                    329: #ifdef METRIC
                    330:                nhcollisions++;
                    331: #endif
                    332:                hp += ihash;
                    333:                ihash += 2;
                    334:                if (hp >= &hshtab[NHASH])
                    335:                        hp -= NHASH;
                    336:        }
                    337:        if(++hshused >= HASHCLOGGED) {
                    338:                yyerror("Symbol table overflow");
                    339:                delexit();
                    340:        }
                    341:        if (instflg) {
                    342: #ifdef METRIC
                    343:                nentered++;
                    344: #endif
                    345:                *hp = symalloc();
                    346:                p1 = yytext;
                    347:                p2 = (*hp)->name;
                    348:                while (*p2++ = *p1++);
                    349:        }
                    350:        return(hp);
                    351: }      /*end of symlook*/
                    352: 
                    353: #ifdef vax
                    354: #define writel(p,n,f) fwrite((long)p, sizeof (long), n, f)
                    355: #else
                    356: writel(p,n,f)
                    357:        long *p;
                    358:        FILE *f;
                    359: {
                    360:        while (n--) {
                    361:                fwrite(&(*p).loword,2,1,f);
                    362:                fwrite(&(*p).hiword,2,1,f);
                    363:                p++;
                    364:        }
                    365: }
                    366: #endif
                    367: 
                    368: int reflen[] = {0,0,1,1,2,2,4,4,8,8};
                    369: 
                    370: /*
                    371:  *     Save the relocation information
                    372:  */
                    373: outrel(pval,reftype,reltype,xsym)
                    374:        long            *pval;
                    375:        register int    reftype,reltype;
                    376:        struct symtab   *xsym;
                    377: {
                    378: 
                    379: /*
                    380:  *     reftype: PCREL or not, plus length LEN1, LEN2, LEN4, LEN8
                    381:  *     reltype: csect ("segment") number (XTEXT, XDATA, ...) associated with 'val'
                    382:  *     xsym: symbol table pointer
                    383:  */
                    384:        long ts;
                    385:        char tc;
                    386:        long tl;
                    387:        short t;
                    388:        if (passno!=2) {
                    389:                dotp->xvalue += reflen[reftype];
                    390:                return;
                    391:        }
                    392:        if (bitoff&07)
                    393:                yyerror("Padding error");
                    394:        reltype &= ~XFORW;
                    395:        if (reltype == XUNDEF)
                    396:                yyerror("Undefined reference");
                    397:        if (reltype != XABS || reftype & PCREL) {
                    398:                /* write the address portion of a relocation datum */
                    399:                if (dotp >= &usedot[NLOC]) {
                    400:                        hdr.drsize += sizeof(dotp->xvalue) + 3 + sizeof tc;
                    401:                        tl = dotp->xvalue-datbase;
                    402:                        writel(&tl,1,relfil);
                    403:                } else {
                    404:                        hdr.trsize += sizeof(dotp->xvalue) + 3 + sizeof tc;
                    405:                        writel(&dotp->xvalue,1,relfil);
                    406:                }
                    407:                /* write the properties portion of a relocation datum */
                    408:                if (reltype == XXTRN+XUNDEF) {
                    409:                        ts = (xsym->index);
                    410:                        tc = (XXTRN<<3) | (reftype-LEN1);
                    411:                } else if ((reltype&XTYPE) == XUNDEFO) {
                    412:                        ts = (xsym->index);
                    413:                        tc = ((XXTRN+2)<<3) | (reftype-LEN1);
                    414:                } else  {
                    415:                        ts = (reltype);
                    416:                        tc = (reftype-LEN1);
                    417:                }
                    418:                fwrite((char *)&ts, 3, 1, relfil);
                    419:                fwrite(&tc, sizeof(tc), 1, relfil);
                    420:        }
                    421:        /* write the raw ("unrelocated") value to the text file */
                    422:        t = reflen[reftype];
                    423:        dotp->xvalue += t;
                    424:        if (reftype & PCREL)
                    425:                *pval -= dotp->xvalue;
                    426: #ifdef vax
                    427:        fwrite(pval,1,t,txtfil);
                    428: #else
                    429:        if (t>2) {
                    430:                fwrite(&((*pval).loword),1,2,txtfil);
                    431:                fwrite(&((*pval).hiword),1,t-2,txtfil);
                    432:        } else fwrite(&((*pval).loword),1,t,txtfil);
                    433: #endif
                    434: }
                    435: 
                    436: 
                    437: /*
                    438:  *     Write out n symbols to file f, beginning at p
                    439:  *     ignoring symbols that are obsolete, jxxx instructions, and
                    440:  *     possibly, labels
                    441:  */
                    442: 
                    443: int sizesymtab()
                    444: {
                    445:        struct symtab *sp;
                    446: 
                    447: #define NOUTSYMS (nsyms - njxxx - nforgotten - (savelabels ? 0 : nlabels))
                    448: 
                    449:        return (
                    450:                (  NCPS
                    451:                 + sizeof (sp->ptype)
                    452:                 + sizeof (sp->other)
                    453:                 + sizeof (sp->desc)
                    454:                 + sizeof (sp->value)
                    455:                ) 
                    456:                *       NOUTSYMS
                    457:        );
                    458: }
                    459: 
                    460: symwrite(f)
                    461:        FILE *f;
                    462: {
                    463:        int     symsout;                        /*those actually written*/
                    464:        int     symsdesired = NOUTSYMS;
                    465:        register        struct  symtab *sp, *ub;
                    466: #ifdef SORTEDOUTPUT
                    467:        int     segno;
                    468:        register        struct  symtab          **copointer;
                    469: #else
                    470:        register        struct  allocbox        *allocwalk;
                    471: #endif
                    472: 
                    473: #ifdef SORTEDOUTPUT
                    474:        for (segno = 0, symsout = 0; segno < NLOC + NLOC; segno++)
                    475:                SEGITERATE(segno, 0, 0, copointer, sp, ub, ++)
                    476: #else
                    477:        symsout = 0;
                    478:        DECLITERATE(allocwalk, sp, ub)
                    479: #endif
                    480:        {
                    481:                if (sp->tag >= IGNOREBOUND) 
                    482:                        continue;
                    483:                if ((sp->name[0] == 'L') && (sp->tag == LABELID) && !savelabels)
                    484:                        continue;
                    485:                symsout++;
                    486:                fwrite(sp->name, NCPS, 1, f);
                    487:                sp->type &= ~XFORW;
                    488:                fwrite((sp->ptype) ? (char *)(&(sp->ptype)) : (char *)(&(sp->type)),
                    489:                        sizeof(char), 1, f);
                    490:        /*
                    491:         *      WATCH OUT.  THIS DEPENDS THAT THE ALLOCATION OF
                    492:         *      the four fields ptype, other, desc and value are
                    493:         *      contiguous.  This may have to be changed!
                    494:         *      This is safe (as of 2-Nov-79).
                    495:         */
                    496:                fwrite(&(sp->other),
                    497:                        sizeof (sp->other)
                    498:                       + sizeof (sp->desc)
                    499:                       + sizeof (sp->value), 1, f
                    500:                );
                    501: #ifdef fooie
                    502: #ifdef vax
                    503:                fwrite(&(sp->name[0]), sizeof(symtab[0].name), 1, f);
                    504:                fwrite(sp->ptype ? &(sp->ptype) : &(sp->type),
                    505:                        sizeof(symtab[0].type), 1, f);
                    506:                fwrite(&(sp->other), sizeof(symtab[0].other), 1, f);
                    507:                fwrite(&(sp->desc), sizeof(symtab[0].desc), 1, f);
                    508:                fwrite(&(sp->value), sizeof(symtab[0].value), 1, f);
                    509: #else
                    510:                writel(&(p->value), 1, f);
                    511: #endif
                    512: #endif
                    513:        }
                    514:        if (symsout != symsdesired)
                    515:                yyerror("INTERNAL ERROR: Wrote %d symbols, wanted to write %d symbols\n",
                    516:                        symsout, symsdesired);
                    517: }
                    518: 
                    519: Flushfield(n)
                    520:        register int n;
                    521: {
                    522:        while (n>0) {
                    523:                outb(bitfield);
                    524:                bitfield >>= 8;
                    525:                n -= 8;
                    526:        }
                    527:        bitoff=0;
                    528:        bitfield=0;
                    529: }

unix.superglobalmegacorp.com

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