Annotation of 43BSDTahoe/lib/old_compiler/as/as.tahoe/assyms.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     Copyright (c) 1982 Regents of the University of California
                      3:  */
                      4: #ifndef lint
                      5: static char sccsid[] = "@(#)assyms.c 4.14 8/11/83";
                      6: #endif not lint
                      7: 
                      8: #include <stdio.h>
                      9: #include <ctype.h>
                     10: #include "as.h"
                     11: #include "asscan.h"
                     12: #include "assyms.h"
                     13: 
                     14: /*
                     15:  *     Managers for chunks of symbols allocated from calloc()
                     16:  *     We maintain a linked list of such chunks.
                     17:  *
                     18:  */
                     19: struct allocbox        *allochead;     /*head of chunk list*/
                     20: struct allocbox        *alloctail;     /*tail*/
                     21: struct allocbox        *newbox;        /*for creating a new chunk*/
                     22: struct symtab          *nextsym;       /*next symbol free*/
                     23: int                    symsleft;       /*slots left in current chunk*/
                     24: 
                     25: struct symtab          **symptrs;
                     26: struct symtab          **symdelim[NLOC + NLOC +1];
                     27: struct symtab          **symptrub;
                     28: /*
                     29:  *     Managers for the dynamically extendable hash table
                     30:  */
                     31: struct hashdallop      *htab;
                     32: 
                     33: Iptr   itab[NINST];    /*maps opcodes to instructions*/
                     34: /*
                     35:  *     Counts what went into the symbol table, so that the
                     36:  *     size of the symbol table can be computed.
                     37:  */
                     38: int    nsyms;          /* total number in the symbol table */
                     39: int    njxxx;          /* number of jxxx entrys */
                     40: int    nforgotten;     /* number of symbols erroneously entered */
                     41: int    nlabels;        /* number of label entries */
                     42: 
                     43: /*
                     44:  *     Managers of the symbol literal storage.
                     45:  */
                     46: struct strpool         *strplhead = 0;
                     47: 
                     48: symtabinit()
                     49: {
                     50:        allochead = 0;
                     51:        alloctail = 0;
                     52:        nextsym = 0;
                     53:        symsleft = 0;
                     54:        strpoolalloc();         /* get the first strpool storage area */
                     55:        htab = 0;
                     56:        htaballoc();            /* get the first part of the hash table */
                     57: }
                     58: 
                     59: /*
                     60:  *     Install all known instructions in the symbol table
                     61:  */
                     62: syminstall()
                     63: {
                     64:        register        Iptr    ip;
                     65:        register        struct  symtab  **hp;
                     66:        register        char    *p1, *p2;
                     67:        register        int     i;
                     68: 
                     69:        for (i = 0; i < NINST; i++)
                     70:                itab[i] = (Iptr)0xAAAAAAAA;
                     71: 
                     72:        for (ip = (Iptr)instab; FETCHNAME(ip)[0]; ip++) {
                     73:                p1 = FETCHNAME(ip);
                     74:                p2 = yytext;
                     75:                while (*p2++ = *p1++);
                     76:                hp = lookup(0);         /* 0 => don't install this*/
                     77:                if (*hp==NULL) {
                     78:                        *hp = (struct symtab *)ip;
                     79:                        if (   (ip->s_tag!=INSTn)
                     80:                            && (ip->s_tag!=INST0)
                     81:                            && (ip->s_tag!=0))
                     82:                                continue; /* was pseudo-op */
                     83:                        itab[ip->i_opcode & 0xFF] = ip;
                     84:                }
                     85:        }
                     86: }      /*end of syminstall*/
                     87: 
                     88: #define ISLABEL(sp) \
                     89:        (   (!savelabels) \
                     90:         && (sp->s_tag == LABELID) \
                     91:         && (STRPLACE(sp) & STR_CORE) \
                     92:         && (FETCHNAME(sp)[0] == 'L'))
                     93: /*
                     94:  *     Assign final values to symbols,
                     95:  *     and overwrite the index field with its relative position in
                     96:  *     the symbol table we give to the loader.
                     97:  */
                     98: extern struct exec hdr;
                     99: 
                    100: freezesymtab()
                    101: {
                    102:        register        struct  symtab  *sp;
                    103:                                long    bs;
                    104:        register        int     relpos = 0;
                    105:        register        struct  symtab          *ubsp;
                    106:        register        struct  allocbox        *allocwalk;
                    107: 
                    108:        DECLITERATE(allocwalk, sp, ubsp)
                    109:        {
                    110:                if (sp->s_tag >= IGNOREBOUND)
                    111:                        continue;               /*totally ignore jxxx entries */
                    112:                /*
                    113:                 *      Ignore stabs, but give them a symbol table index
                    114:                 */
                    115:                if (sp->s_type & STABFLAG)
                    116:                        goto assignindex;
                    117:                if ((sp->s_type&XTYPE)==XUNDEF)
                    118:                        sp->s_type = XXTRN+XUNDEF;
                    119:                else if ((sp->s_type&XTYPE)==XDATA)
                    120:                        sp->s_value += usedot[sp->s_index].e_xvalue;
                    121:                else if ((sp->s_type&XTYPE)==XTEXT)
                    122:                        sp->s_value += usedot[sp->s_index].e_xvalue;
                    123:                else if ((sp->s_type&XTYPE)==XBSS) {
                    124:                        bs = sp->s_value;
                    125:                        sp->s_value = hdr.a_bss + datbase;
                    126:                        hdr.a_bss += bs;
                    127:                }
                    128:           assignindex:
                    129:                if (!ISLABEL(sp))
                    130:                        sp->s_index = relpos++;
                    131:        }
                    132: }
                    133: 
                    134: /*
                    135:  *     For all of the stabs that had their final value undefined during pass 1
                    136:  *     and during pass 2 assign a final value.
                    137:  *     We have already given stab entrys a initial approximation
                    138:  *     when we constsructed the sorted symbol table.
                    139:  *     Iteration order doesn't matter.
                    140:  */
                    141: 
                    142: stabfix()
                    143: {
                    144:        register struct symtab *sp, **cosp;
                    145:        register struct symtab *p;
                    146:        
                    147:        SYMITERATE(cosp, sp){
                    148:                if(sp->s_ptype && (sp->s_type & STABFLAG)) {    
                    149:                        p = sp->s_dest; 
                    150: /* 
                    151:  * STABFLOATING indicates that the offset has been saved in s_desc, s_other
                    152:  */
                    153:                        if(sp->s_tag == STABFLOATING) {
                    154:                          sp->s_value = ( ( ((unsigned char) sp->s_other) << 16)                                        | ( (unsigned short) sp->s_desc )  );
                    155:                          sp->s_value = sp->s_value + p->s_value;
                    156:                        }
                    157:                        else sp->s_value = p->s_value;
                    158:                        sp->s_index = p->s_index;
                    159:                        sp->s_type = p->s_type;
                    160: 
                    161:               
                    162:                }
                    163:        }
                    164: }
                    165: 
                    166: char *Calloc(number, size)
                    167:        int     number, size;
                    168: {
                    169:        register        char *newstuff;
                    170:        char    *sbrk();
                    171:        newstuff = sbrk(number*size);
                    172:        if ((int)newstuff == -1){
                    173:                yyerror("Ran out of Memory");
                    174:                delexit();
                    175:        }
                    176:        return(newstuff);
                    177: }
                    178: 
                    179: char *ClearCalloc(number, size)
                    180:        int     number, size;
                    181: {
                    182:        register        char    *newstuff;              /* r11 */
                    183:        register        int     length = number * size; /* r10 */
                    184: #ifdef lint
                    185:        length = length;
                    186: #endif length
                    187:        newstuff = Calloc(number, size);
                    188:        strncpy (newstuff, "\0", length);
                    189:        return(newstuff);
                    190: }
                    191: 
                    192: struct symtab *symalloc()
                    193: {
                    194:        if (symsleft == 0){
                    195:                newbox = (struct allocbox *)ClearCalloc(1,ALLOCQTY);
                    196:                symsleft = SYMDALLOP;
                    197:                nextsym = &newbox->symslots[0];
                    198:                if (alloctail == 0){
                    199:                        allochead = alloctail = newbox;
                    200:                } else {
                    201:                        alloctail->nextalloc = newbox;
                    202:                        alloctail = newbox;
                    203:                }
                    204:        }
                    205:        --symsleft;
                    206:        ++nsyms;
                    207:        return(nextsym++);
                    208: }
                    209: 
                    210: strpoolalloc()
                    211: {
                    212:        register        struct  strpool *new;
                    213: 
                    214:        new = (struct strpool *)Calloc(1, sizeof (struct strpool));
                    215:        new->str_nalloc = 0;
                    216:        new->str_next = strplhead;
                    217:        strplhead = new;
                    218: }
                    219: 
                    220: symcmp(Pptr, Qptr)
                    221:        struct symtab **Pptr, **Qptr;
                    222: {
                    223:        register struct symtab *p = *Pptr;
                    224:        register struct symtab *q = *Qptr;
                    225:        if (p->s_index < q->s_index)
                    226:                return(-1);
                    227:        if (p->s_index > q->s_index)
                    228:                return(1);
                    229:        if (p->s_value < q->s_value)
                    230:                return(-1);
                    231:        if (p->s_value > q->s_value)
                    232:                return(1);
                    233:        /*
                    234:         *      Force jxxx entries to virtually preceed labels defined
                    235:         *      to follow the jxxxx instruction, so that bumping the
                    236:         *      jxxx instruction correctly fixes up the following labels
                    237:         */
                    238:        if (p->s_tag >= IGNOREBOUND)    /*p points to a jxxx*/
                    239:                return(-1);             
                    240:        if (q->s_tag >= IGNOREBOUND)
                    241:                return(1);
                    242:        /*
                    243:         *      both are now just plain labels; the relative order doesn't
                    244:         *      matter.  Both can't be jxxxes, as they would have different
                    245:         *      values.
                    246:         */
                    247:        return(0);                      
                    248: }      /*end of symcmp*/
                    249: 
                    250: /*
                    251:  *     We construct the auxiliary table of pointers, symptrs and
                    252:  *     symdelim
                    253:  *     We also assign preliminary values to stab entries that did not yet
                    254:  *     have an absolute value (because they initially referred to
                    255:  *     forward references). We don't worry about .stabds, as they
                    256:  *     already have an estimated final value
                    257:  */
                    258: 
                    259: sortsymtab()
                    260: {
                    261:        register        struct  symtab  *sp;
                    262:        register        struct  symtab  **cowalk;
                    263:        register        struct  allocbox        *allocwalk;
                    264:                        struct  symtab  *ubsp;
                    265:                                int     segno;
                    266:                                int     slotno;
                    267:                                int     symsin; /*number put into symptrs*/
                    268: 
                    269:        symptrs =  (struct symtab **)Calloc(nsyms + 2, sizeof *symptrs);
                    270:        /*
                    271:         *      Allocate one word at the beginning of the symptr array
                    272:         *      so that backwards scans through the symptr array will
                    273:         *      work correctly while scanning through the zeroth segment
                    274:         */
                    275:        *symptrs++ = 0;
                    276:        cowalk = symptrs;
                    277:        symsin = 0;
                    278:        DECLITERATE(allocwalk, sp, ubsp) {
                    279:                if (sp->s_ptype && (sp->s_type &STABFLAG)){
                    280:                        sp->s_value = sp->s_dest->s_value;
                    281:                        sp->s_index = sp->s_dest->s_index;
                    282:                }
                    283:                if (symsin >= nsyms)
                    284:                        yyerror("INTERNAL ERROR: overfilled symbol table indirection table");
                    285:                *cowalk++ = sp;
                    286:                symsin++;
                    287:        }
                    288:        if (symsin != nsyms)
                    289:                yyerror("INTERNAL ERROR: installed %d syms, should have installed %d",
                    290:                        symsin, nsyms);
                    291:        symptrub = &symptrs[nsyms ];
                    292:        qsort(symptrs, nsyms, sizeof *symptrs, symcmp);
                    293:        symdelim[0] = symptrs;
                    294:        for (cowalk = symptrs, sp = *cowalk, segno = 0, slotno = 1;
                    295:             segno < NLOC + NLOC;
                    296:             segno++, slotno++){
                    297:                for (; sp && sp->s_index == segno; sp = *++cowalk);
                    298:                symdelim[slotno] = cowalk;      /*forms the ub delimeter*/
                    299:        }
                    300: }      /*end of sortsymtab*/
                    301: 
                    302: #ifdef DEBUG
                    303: dumpsymtab()
                    304: {
                    305:        register        int     segno;
                    306:        register        struct symtab *sp, **cosp, *ub;
                    307:        char            *tagstring();
                    308: 
                    309:        printf("Symbol Table dump:\n");
                    310:        for (segno = 0; segno < NLOC + NLOC; segno++){
                    311:                printf("Segment number: %d\n", segno);
                    312:                SEGITERATE(segno, 0, 0, cosp, sp, ub, ++){
                    313:                        printf("\tSeg: %d \"%s\" value: %d index: %d tag %s\n",
                    314:                                segno, sp->s_name ? FETCHNAME(sp) : "(NULL)",
                    315:                                sp->s_value, sp->s_index,
                    316:                                tagstring(sp->s_tag));
                    317:                        printf("\t\ttype: %d jxbump %d jxfear: %d\n",
                    318:                                sp->s_type, sp->s_jxbump, sp->s_jxfear);
                    319:                }
                    320:                printf("\n\n");
                    321:        }
                    322: }
                    323: 
                    324: static char tagbuff[4];
                    325: 
                    326: char *tagstring(tag)
                    327:        unsigned        char    tag;
                    328: {
                    329:        switch(tag){
                    330:                case JXACTIVE:          return("active");
                    331:                case JXNOTYET:          return("notyet");
                    332:                case JXALIGN:           return("align");
                    333:                case JXQUESTIONABLE:    return("jxquestionable");
                    334:                case JXINACTIVE:        return("inactive");
                    335:                case JXTUNNEL:          return("tunnel");
                    336:                case OBSOLETE:          return("obsolete");
                    337:                case IGNOREBOUND:       return("ignorebound");
                    338:                case STABFLOATING:      return("stabfloating");
                    339:                case STABFIXED:         return("stabfixed");
                    340:                case LABELID:           return("labelid");
                    341:                case OKTOBUMP:          return("oktobump");
                    342:                case ISET:              return("iset");
                    343:                case ILSYM:             return("ilsym");
                    344:                default:                (void)sprintf(tagbuff,"%d", tag);
                    345:                                        return(tagbuff);
                    346:        }
                    347: }
                    348: #endif DEBUG
                    349: 
                    350: htaballoc()
                    351: {
                    352:        register        struct  hashdallop      *new;
                    353:        new = (struct hashdallop *)ClearCalloc(1, sizeof (struct hashdallop));
                    354:        if (htab == 0)
                    355:                htab = new;
                    356:        else {          /* add AFTER the 1st slot */
                    357:                new->h_next = htab->h_next;
                    358:                htab->h_next = new;
                    359:        }
                    360: }
                    361: 
                    362: #define        HASHCLOGGED     (NHASH / 2)
                    363: 
                    364: /*
                    365:  *     Lookup a symbol stored in extern yytext.
                    366:  *     All strings passed in via extern yytext had better have
                    367:  *     a trailing null.  Strings are placed in yytext for hashing by
                    368:  *     syminstall() and by yylex();
                    369:  *
                    370:  *     We take pains to avoid function calls; this functdion
                    371:  *     is called quite frequently, and the calls overhead
                    372:  *     in the vax contributes significantly to the overall
                    373:  *     execution speed of as.
                    374:  */
                    375: struct symtab **lookup(instflg)
                    376:        int     instflg;                /* 0: don't install */
                    377: {
                    378:        static   int            initialprobe;
                    379:        register struct symtab  **hp;
                    380:        register char           *from;
                    381:        register char           *to;
                    382:        register        int     len;
                    383:        register        int     nprobes;
                    384:        static  struct  hashdallop *hdallop;
                    385:        static  struct  symtab  **emptyslot;
                    386:        static  struct  hashdallop *emptyhd;
                    387:        static  struct  symtab  **hp_ub;
                    388: 
                    389:        emptyslot = 0;
                    390:        for (nprobes = 0, from = yytext;
                    391:             *from;
                    392:             nprobes <<= 2, nprobes += *from++)
                    393:                continue;
                    394:        nprobes += from[-1] << 5;
                    395:        nprobes %= NHASH;
                    396:        if (nprobes < 0)
                    397:                nprobes += NHASH;
                    398: 
                    399:        initialprobe = nprobes;
                    400:        for (hdallop = htab; hdallop != 0; hdallop = hdallop->h_next){
                    401:                for (hp = &(hdallop->h_htab[initialprobe]),
                    402:                                nprobes = 1,
                    403:                                hp_ub = &(hdallop->h_htab[NHASH]);
                    404:                     (*hp) && (nprobes < NHASH);
                    405:                                hp += nprobes,
                    406:                                hp -= (hp >= hp_ub) ? NHASH:0,
                    407:                                nprobes += 2)
                    408:                {
                    409:                        from = yytext;
                    410:                        to = FETCHNAME(*hp);
                    411:                        while (*from && *to)
                    412:                                if (*from++ != *to++)
                    413:                                        goto nextprobe;
                    414:                        if (*to == *from)       /*assert both are == 0*/
                    415:                                return(hp);
                    416:                nextprobe: ;
                    417:                }
                    418:                if (*hp == 0 && emptyslot == 0 &&
                    419:                    hdallop->h_nused < HASHCLOGGED) {
                    420:                        emptyslot = hp;
                    421:                        emptyhd = hdallop;
                    422:                }
                    423:        }
                    424:        if (emptyslot == 0) {
                    425:                htaballoc();
                    426:                hdallop = htab->h_next;         /* aren't we smart! */
                    427:                hp = &hdallop->h_htab[initialprobe];
                    428:        } else {
                    429:                hdallop = emptyhd;
                    430:                hp = emptyslot;
                    431:        }
                    432:        if (instflg) {
                    433:                *hp = symalloc();
                    434:                hdallop->h_nused++;
                    435:                for (from = yytext, len = 0; *from++; len++)
                    436:                        continue;
                    437:                (*hp)->s_name = (char *)savestr(yytext, len + 1, STR_BOTH);
                    438:        }
                    439:        return(hp);
                    440: }      /*end of lookup*/
                    441: /*
                    442:  *     save a string str with len in the places indicated by place
                    443:  */
                    444: struct strdesc *savestr(str, len, place)
                    445:        char    *str;
                    446:        int     len;
                    447:        int     place;
                    448: {
                    449:        reg     struct  strdesc *res;
                    450:        reg     int     tlen;
                    451:        /*
                    452:         *      Compute the total length of the record to live in core
                    453:         */
                    454:        tlen = sizeof(struct strdesc) - sizeof(res->sd_string);
                    455:        if (place & STR_CORE)
                    456:                tlen += (len + 3) & ~3;
                    457:        /*
                    458:         *      See if there is enough space for the record,
                    459:         *      and allocate the record.
                    460:         */
                    461:        if (tlen >= (STRPOOLDALLOP - strplhead->str_nalloc))
                    462:                strpoolalloc();
                    463:        res = (struct strdesc *)(strplhead->str_names + 
                    464:                strplhead->str_nalloc);
                    465:        /*
                    466:         *      Save the string information that is always present
                    467:         */
                    468:        res->sd_stroff = strfilepos;
                    469:        res->sd_strlen = len;
                    470:        res->sd_place = place;
                    471:        /*
                    472:         *      Now, save the string itself.  If str is null, then
                    473:         *      the characters have already been dumped to the file
                    474:         */
                    475:        if ((place & STR_CORE) && str)
                    476:                movestr(res[0].sd_string, str, len);
                    477:        if (place & STR_FILE){
                    478:                if (str){
                    479:                        fwrite(str, 1, len, strfile);
                    480:                }
                    481:                strfilepos += len;
                    482:        }
                    483:        /*
                    484:         *      Adjust the in core string pool size
                    485:         */
                    486:        strplhead->str_nalloc += tlen;
                    487:        return(res);
                    488: }
                    489: /*
                    490:  *     The relocation information is saved internally in an array of
                    491:  *     lists of relocation buffers.  The relocation buffers are
                    492:  *     exactly the same size as a token buffer; if we use VM for the
                    493:  *     temporary file we reclaim this storage, otherwise we create
                    494:  *     them by mallocing.
                    495:  */
                    496: #define        RELBUFLG        TOKBUFLG
                    497: #define        NRELOC          ((TOKBUFLG - \
                    498:                          (sizeof (int) + sizeof (struct relbufdesc *)) \
                    499:                        ) / (sizeof (struct relocation_info)))
                    500: 
                    501: struct relbufdesc{
                    502:        int     rel_count;
                    503:        struct  relbufdesc      *rel_next;
                    504:        struct  relocation_info rel_reloc[NRELOC];
                    505: };
                    506: extern struct  relbufdesc      *tok_free;
                    507: #define        rel_free tok_free
                    508: static struct  relbufdesc      *rel_temp;
                    509: struct relocation_info r_can_1PC;
                    510: struct relocation_info r_can_0PC;
                    511: 
                    512: initoutrel()
                    513: {
                    514:        r_can_0PC.r_address = 0;
                    515:        r_can_0PC.r_symbolnum = 0;
                    516:        r_can_0PC.r_pcrel = 0;
                    517:        r_can_0PC.r_length = 0;
                    518:        r_can_0PC.r_extern = 0;
                    519: 
                    520:        r_can_1PC = r_can_0PC;
                    521:        r_can_1PC.r_pcrel = 1;
                    522: }
                    523: 
                    524: outrel(xp, reloc_how)
                    525:        register        struct  exp     *xp;
                    526:        int             reloc_how;      /* TYPB..TYPD + (possibly)RELOC_PCREL */
                    527: {
                    528:        struct          relocation_info reloc;
                    529:        register        int     x_type_mask;    
                    530:                        int     pcrel;
                    531: 
                    532:        x_type_mask = xp->e_xtype & ~XFORW;
                    533:        pcrel = reloc_how & RELOC_PCREL;
                    534:        reloc_how &= ~RELOC_PCREL;
                    535:        
                    536:        if (bitoff&07)
                    537:                yyerror("Padding error");
                    538:        if (x_type_mask == XUNDEF)
                    539:                yyerror("Undefined reference");
                    540: 
                    541:        if ( (x_type_mask != XABS) || pcrel ) {
                    542:                if (ty_NORELOC[reloc_how])
                    543:                        yyerror("Illegal Relocation of floating or large int number.");
                    544:                reloc = pcrel ? r_can_1PC : r_can_0PC;
                    545:                reloc.r_address = dotp->e_xvalue -
                    546:                    ( (dotp < &usedot[NLOC] || readonlydata) ? 0 : datbase );
                    547:                reloc.r_length = ty_nlg[reloc_how];
                    548:                switch(x_type_mask){
                    549:                        case XXTRN | XUNDEF:
                    550:                                reloc.r_symbolnum = xp->e_xname->s_index;
                    551:                                reloc.r_extern = 1;
                    552:                                break;
                    553:                        default:
                    554:                                if (readonlydata && (x_type_mask&~XXTRN) == XDATA)
                    555:                                        x_type_mask = XTEXT | (x_type_mask&XXTRN);
                    556:                                reloc.r_symbolnum = x_type_mask;
                    557:                                break;
                    558:                }
                    559:                if ( (relfil == 0) || (relfil->rel_count >= NRELOC) ){
                    560:                        if (rel_free){
                    561:                                rel_temp = rel_free;
                    562:                                rel_free = rel_temp->rel_next;
                    563:                        } else {
                    564:                                rel_temp = (struct relbufdesc *)
                    565:                                        Calloc(1,sizeof (struct relbufdesc));
                    566:                        }
                    567:                        rel_temp->rel_count = 0;
                    568:                        rel_temp->rel_next = relfil;
                    569:                        relfil = rusefile[dotp - &usedot[0]] = rel_temp;
                    570:                }
                    571:                relfil->rel_reloc[relfil->rel_count++] = reloc;
                    572:        }
                    573:        /*
                    574:         *      write the unrelocated value to the text file
                    575:         */
                    576:        dotp->e_xvalue += ty_nbyte[reloc_how];
                    577:        if (pcrel)
                    578:                xp->e_xvalue -= dotp->e_xvalue;
                    579:        switch(reloc_how){
                    580:        case TYPQ:
                    581:                bwrite(&(xp->e_number.num_num.numIq_int.Iq_ulong[1]),
                    582:                        sizeof (long), txtfil);
                    583:                bwrite(&(xp->e_number.num_num.numIq_int.Iq_ulong[0]),
                    584:                        sizeof (long), txtfil);
                    585:                break;
                    586:        case TYPD:
                    587:                bwrite(&(xp->e_number.num_num.numFd_float.Fd_ulong[0]),
                    588:                        sizeof (long), txtfil);
                    589:                bwrite(&(xp->e_number.num_num.numFd_float.Fd_ulong[1]),
                    590:                        sizeof (long), txtfil);
                    591:                break;
                    592:        case TYPF:
                    593:                bwrite(&(xp->e_number.num_num.numFf_float.Ff_ulong[0]),
                    594:                        sizeof (long), txtfil);
                    595:                break;
                    596: 
                    597:        case TYPB:
                    598:                bwrite(((char *)&(xp->e_xvalue))+3, ty_nbyte[reloc_how], txtfil);
                    599:                break;
                    600:        case TYPW:
                    601:                bwrite(((char *)&(xp->e_xvalue))+2, ty_nbyte[reloc_how], txtfil);
                    602:                break;
                    603:        case TYPL:
                    604:                bwrite ((char *)&(xp->e_xvalue), ty_nbyte[reloc_how], txtfil);
                    605:                break;
                    606:        }
                    607:        if (liston && (passno == 2))
                    608:                switch (reloc_how)
                    609:                {
                    610:                  case TYPQ:
                    611:                          long_out(xp->e_number.num_num.numIq_int.Iq_ulong[1]);
                    612:                          long_out(xp->e_number.num_num.numIq_int.Iq_ulong[0]);
                    613:                  case TYPD:
                    614:                          long_out(xp->e_number.num_num.numIq_int.Iq_ulong[0]);
                    615:                          long_out(xp->e_number.num_num.numIq_int.Iq_ulong[1]);
                    616:                          break;
                    617:                  case TYPF:
                    618:                          long_out(xp->e_number.num_num.numFf_float.Ff_ulong[0]);
                    619:                          break;
                    620: 
                    621:                  case TYPB:
                    622:                          byte_out(xp->e_xvalue);
                    623:                          break;
                    624:                  case TYPW:
                    625:                          word_out(xp->e_xvalue);
                    626:                          break;
                    627:                  case TYPL:
                    628:                          long_out(xp->e_xvalue);
                    629:                          break;
                    630:                }
                    631: }
                    632: /*
                    633:  *     Flush out all of the relocation information.
                    634:  *     Note that the individual lists of buffers are in
                    635:  *     reverse order, so we must reverse them
                    636:  */
                    637: off_t closeoutrel(relocfile)
                    638:        BFILE   *relocfile;
                    639: {
                    640:        int     locindex;
                    641:        u_long  Closeoutrel();
                    642: 
                    643:        trsize = 0;
                    644:        for (locindex = 0; locindex < NLOC; locindex++){
                    645:                trsize += Closeoutrel(rusefile[locindex], relocfile);
                    646:        }
                    647:        drsize = 0;
                    648:        for (locindex = 0; locindex < NLOC; locindex++){
                    649:                drsize += Closeoutrel(rusefile[NLOC + locindex], relocfile);
                    650:        }
                    651:        return(trsize + drsize);
                    652: }
                    653: 
                    654: u_long Closeoutrel(relfil, relocfile)
                    655:        struct  relbufdesc      *relfil;
                    656:        BFILE   *relocfile;
                    657: {
                    658:        u_long  tail;
                    659:        if (relfil == 0)
                    660:                return(0L);
                    661:        tail = Closeoutrel(relfil->rel_next, relocfile);
                    662:        bwrite((char *)&relfil->rel_reloc[0],
                    663:                relfil->rel_count * sizeof (struct relocation_info),
                    664:                relocfile);
                    665:        return(tail + relfil->rel_count * sizeof (struct relocation_info));
                    666: }
                    667: 
                    668: #define NOUTSYMS (nsyms - njxxx - nforgotten - (savelabels ? 0 : nlabels))
                    669: int sizesymtab()
                    670: {
                    671:        return (sizeof (struct nlist) * NOUTSYMS);
                    672: }
                    673: /*
                    674:  *     Write out n symbols to file f, beginning at p
                    675:  *     ignoring symbols that are obsolete, jxxx instructions, and
                    676:  *     possibly, labels
                    677:  */
                    678: int symwrite(symfile)
                    679:        BFILE *symfile;
                    680: {
                    681:                int     symsout;                /*those actually written*/
                    682:                int     symsdesired = NOUTSYMS;
                    683:        reg     struct  symtab *sp, *ub;
                    684:                char    *name;                  /* temp to save the name */
                    685:                int     totalstr;
                    686:        /*
                    687:         *      We use sp->s_index to hold the length of the
                    688:         *      name; it isn't used for anything else
                    689:         */
                    690:        register        struct  allocbox        *allocwalk;
                    691: 
                    692:        symsout = 0;
                    693:        totalstr = sizeof(totalstr);
                    694:        DECLITERATE(allocwalk, sp, ub) {
                    695:                if (sp->s_tag >= IGNOREBOUND) 
                    696:                        continue;
                    697:                if (ISLABEL(sp))
                    698:                        continue;
                    699:                symsout++;
                    700:                name = sp->s_name;              /* save pointer */
                    701:                /*
                    702:                 *      the length of the symbol table string
                    703:                 *      always includes the trailing null;
                    704:                 *      blast the pointer to its a.out value.
                    705:                 */
                    706:                if (sp->s_name && (sp->s_index = STRLEN(sp))){
                    707:                        sp->s_nmx = totalstr;
                    708:                        totalstr += sp->s_index;
                    709:                } else {
                    710:                        sp->s_nmx = 0;
                    711:                }
                    712:                if (sp->s_ptype != 0)
                    713:                        sp->s_type = sp->s_ptype;
                    714:                else
                    715:                        sp->s_type = (sp->s_type & (~XFORW));
                    716:                if (readonlydata && (sp->s_type&~N_EXT) == N_DATA)
                    717:                        sp->s_type = N_TEXT | (sp->s_type & N_EXT);
                    718:                bwrite((char *)&sp->s_nm, sizeof (struct nlist), symfile);
                    719:                sp->s_name = name;              /* restore pointer */
                    720:        }
                    721:        if (symsout != symsdesired)
                    722:                yyerror("INTERNAL ERROR: Wrote %d symbols, wanted to write %d symbols\n",
                    723:                        symsout, symsdesired);
                    724:        /*
                    725:         *      Construct the string pool from the symbols that were written,
                    726:         *      possibly fetching from the string file if the string
                    727:         *      is not core resident.
                    728:         */
                    729:        bwrite(&totalstr, sizeof(totalstr), symfile);
                    730:        symsout = 0;
                    731:        DECLITERATE(allocwalk, sp, ub) {
                    732:                if (sp->s_tag >= IGNOREBOUND) 
                    733:                        continue;
                    734:                if (ISLABEL(sp))
                    735:                        continue;
                    736:                symsout++;
                    737:                if (sp->s_name && STRLEN(sp) > 0){
                    738:                 if (STRPLACE(sp) & STR_CORE){
                    739:                        bwrite(FETCHNAME(sp), STRLEN(sp), symfile);
                    740:                 } else if (STRPLACE(sp) & STR_FILE){
                    741:                        char    rbuf[2048];
                    742:                        int     left, nread;
                    743:                        fseek(strfile, STROFF(sp), 0);
                    744:                        for (left = STRLEN(sp); left > 0; left -= nread){
                    745:                                nread = fread(rbuf, sizeof(char),
                    746:                                        min(sizeof(rbuf), left), strfile);
                    747:                                if (nread == 0)
                    748:                                        break;
                    749:                                bwrite(rbuf, nread, symfile);
                    750:                        }
                    751:                 }
                    752:                }
                    753:        }
                    754:        if (symsout != symsdesired)
                    755:                yyerror("INTERNAL ERROR: Wrote %d strings, wanted %d\n",
                    756:                        symsout, symsdesired);
                    757: }

unix.superglobalmegacorp.com

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