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

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

unix.superglobalmegacorp.com

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