Annotation of 3BSD/cmd/as/assyms.c, revision 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.