Annotation of researchv9/jerq/sgs/ld/ld2.c, revision 1.1.1.1

1.1       root        1: static char ID[] = "@(#) ld2.c: 1.16 12/1/83";
                      2: #include "system.h"
                      3: 
                      4: #include <stdio.h>
                      5: #include "reloc.h"
                      6: #include "linenum.h"
                      7: #include "structs.h"
                      8: #include "y.tab.h"
                      9: 
                     10: #if TRVEC
                     11: #include "tv.h"
                     12: #include "ldtv.h"
                     13: #endif
                     14: 
                     15: #include "extrns.h"
                     16: #include "list.h"
                     17: #include "params.h"
                     18: #include "sgsmacros.h"
                     19: #include "patch.h"
                     20: 
                     21: 
                     22: #define BASIC_TYPES (STYP_TEXT | STYP_DATA | STYP_BSS)
                     23: #define        K8      0x2000L
                     24: static ITEMID dotacid;
                     25: static OUTSECT *dotosptr;
                     26: /*eject*/
                     27: pboslist()
                     28: {
                     29: 
                     30: /*
                     31:  * Process the BLDOUTSC List
                     32:  */
                     33: 
                     34:        register OUTSECT *osptr;
                     35:        register INSECT *insptr;
                     36:        register INFILE *inflptr;
                     37: #if !ONEPROC
                     38:        ACTITEM a;
                     39: #endif
                     40:        OUTSECT *dfn_scn_grp();
                     41:        long    check_sect();
                     42: 
                     43: 
                     44: /*
                     45:  * Process the list of output sections.  Output sections can be 
                     46:  * defined in two places:
                     47:  *
                     48:  *     1. PASS 1: user-supplied; bldcnt will be > 0, and the bldoutsc 
                     49:  *                     list head will be NULL
                     50:  *     2. PASS 2: default-generation; bldcnt will be 0, and the
                     51:  *                     bldoutsc list will describe the output
                     52:  *                     sections
                     53:  *
                     54:  *     These two uses are mutually exclusive
                     55:  */
                     56: 
                     57: #if DEBUG
                     58:        if( dflag > 2 )
                     59:                fprintf( stderr, "\nBLDOSCN data structures:" );
                     60: #endif
                     61: #if !ONEPROC
                     62:        while( bldcnt-- ) {
                     63: 
                     64:                fread( &a, 1, sizeof(ACTITEM), trnfdes );
                     65:                a.dfnscn.aiinflnm = (char *) ((int) a.dfnscn.aiinflnm + (int) strbase);
                     66: 
                     67:                osptr = dfn_scn_grp(&a, 0);
                     68:                copy(osptr->oshdr.s_name, a.dfnscn.ainame, 8);
                     69: #if TRVEC
                     70:                /*
                     71:                 * User can define attributes of TV in two ways:
                     72:                 * (1) using TV { } directive
                     73:                 * (2) using SECTIONS { .tv : {} } directive
                     74:                 * so force them to agree
                     75:                 */
                     76:                if ( equal(a.dfnscn.ainame, _TV, 8) ) { /* defining .tv */
                     77:                        if ( tvspec.tvbndadr == -1L )
                     78:                                tvspec.tvbndadr = a.dfnscn.aibndadr;
                     79:                        else
                     80:                                a.dfnscn.aibndadr = tvspec.tvbndadr;
                     81:                        }
                     82: #endif
                     83:                if( a.dfnscn.aitype == AIDFNSCN )
                     84:                        numoutsc++;
                     85: 
                     86:                osptr->oshdr.s_paddr = -1L;
                     87:                listadd(l_OS, &outsclst, osptr);
                     88:                }
                     89: #endif
                     90: 
                     91:        /*
                     92:         * We now know everything there is to know about the
                     93:         * transfer vector:
                     94:         *      At the end of ploadfil(), we knew how big it
                     95:         *      had to be.
                     96:         *      Here we know whether it was defined by ld or
                     97:         *      whether it is defined by .tv input sections
                     98:         *      together with a .tv SECTION directive
                     99:         * Go check everything and complete tvspec definition.
                    100:         */
                    101: 
                    102: #if TRVEC
                    103:        if ( tvflag )
                    104:                tvupdat();      /* update definition of tv */
                    105: #endif
                    106: 
                    107:        if( bldoutsc.head ) {
                    108:                register ACTITEM *aptr, *a2ptr;
                    109: 
                    110:                aptr = (ACTITEM *) bldoutsc.head;
                    111:                while( aptr ) {
                    112: 
                    113:                        osptr = dfn_scn_grp(aptr, 1);
                    114:        
                    115:                        copy(osptr->oshdr.s_name, aptr->dfnscn.ainame, 8);
                    116:                        if( aptr->dfnscn.aitype == AIDFNSCN )
                    117:                                numoutsc++;
                    118:        
                    119:                        osptr->oshdr.s_paddr = -1L;
                    120:                        listadd(l_OS, &outsclst, osptr);
                    121: 
                    122:                        a2ptr = aptr;
                    123:                        aptr = aptr->dfnscn.ainext;
                    124:                        free( (char *) a2ptr);
                    125:                        }
                    126:                }
                    127: 
                    128: /*
                    129:  * Make sure all input sections are allocated
                    130:  * into some output section.
                    131:  */
                    132: 
                    133:        for( inflptr = (INFILE *) infilist.head; inflptr; inflptr = inflptr->flnext ) {
                    134:                for( insptr = inflptr->flishead; insptr; insptr=insptr->isnext ) {
                    135:                        if (insptr->isoutsec <= 0) {
                    136:                                if ((osptr = fndoutsec(insptr->ishdr.s_name)) != NULL)
                    137:                                        inscadd(insptr,osptr);
                    138:                                else {
                    139:                                        osptr = (OUTSECT *) myalloc(sizeof(OUTSECT));
                    140:                                        numoutsc++;
                    141:                                        copy(osptr->oshdr.s_name, insptr->ishdr.s_name, 8);
                    142:                                        osptr->osfill = globfill;
                    143:                                        osptr->oshdr.s_paddr = -1l;
                    144:                                        listadd(l_OS,&outsclst,osptr);
                    145:                                        inscadd(insptr,osptr);
                    146:                                        }
                    147:                                }
                    148:                        }
                    149:                }
                    150: 
                    151:        /*
                    152:         * for each output section, check the flags, and for a group,
                    153:         * check the size.
                    154:         */
                    155: 
                    156:        for( osptr = (OUTSECT *) outsclst.head; osptr; osptr = osptr->osnext ) 
                    157:                {
                    158: #if PAGING
                    159:                        ACTITEM *aptr;
                    160:                        ADDRESS textbegin, textsize;
                    161:                        textbegin = hflag + FILHSZ + SCNHSZ * numoutsc + memorg;
                    162: #endif
                    163:                if (osptr->oshdr.s_flags & STYP_GROUP) {
                    164:                        OUTSECT *op;
                    165:                        for( op = ((OUTSECT *) osptr->osinclhd); op; op = op->osnext ) {
                    166: #if PAGING
                    167:                                if (bond_t_d && !Nflag && equal(op->oshdr.s_name,_DATA,8)) {
                    168:                                        osptr->osalign = 0L;
                    169:                                        aptr = (ACTITEM *) myalloc(sizeof(ACTITEM));
                    170:                                        aptr->bond.aitype = AIBOND;
                    171:                                        aptr->bond.aiinflnm = "*default.bond.file*";
                    172:                                        aptr->bond.aiinlnno = 3;
                    173:                                        aptr->bond.aioutsec = osptr;
                    174:                                        aptr->bond.aiadrbnd = ((textsize + textbegin) / BOUNDARY + 1) 
                    175:                                                * BOUNDARY + (textsize + textbegin) % K8;
                    176:                                        listadd(l_AI,&bondlist,aptr);
                    177:                                        }
                    178: #endif
                    179:                                osptr->oshdr.s_size += check_sect( op );
                    180:                                }
                    181:                        if (osptr->oshdr.s_size > MAXSCNSIZE)
                    182:                                lderror(1,0,NULL, "GROUP containing section %.8s is too big",
                    183:                                    osptr->osinclhd->ishdr.s_name);
                    184:                } else {
                    185: #if PAGING
                    186:                        if (bond_t_d && !Nflag && equal(osptr->oshdr.s_name,_TEXT,8)) {
                    187:                                textsize = osptr->oshdr.s_size;
                    188:                                aptr = (ACTITEM *) myalloc(sizeof(ACTITEM));
                    189:                                aptr->bond.aitype = AIBOND;
                    190:                                aptr->bond.aiinflnm = "*default.bond.file*";
                    191:                                aptr->bond.aiinlnno = 2;
                    192:                                aptr->bond.aioutsec = osptr;
                    193:                                aptr->bond.aiadrbnd = textbegin;
                    194:                                listadd(l_AI,&bondlist,aptr);
                    195:                                }
                    196: #endif
                    197:                        check_sect( osptr );
                    198:                        }
                    199:                }
                    200: 
                    201:        /*
                    202:         * If .tv is user-defined, we now know the true size of
                    203:         * the section ( the sum of the sizes of the input
                    204:         * sections) which we didn't know before. Now call the
                    205:         * the final update routine to insure .tv symtab entry
                    206:         * is correct
                    207:         */
                    208: 
                    209: #if TRVEC
                    210:        if ( tvflag )
                    211:                tvupdt2();      /* final update of tvrange and tvlength */
                    212: #endif
                    213: 
                    214: #if DEBUG
                    215:        if (dflag)
                    216:                dmp_outsects();
                    217: #endif
                    218: }
                    219: /*eject*/
                    220: OUTSECT *
                    221: dfn_scn_grp(aptr, dflt)
                    222: 
                    223: ACTITEM *aptr;         /* DFNSCN or DFNGRP entry    */
                    224: int dflt;              /* user-supplied or ld-default entry */
                    225: {
                    226: 
                    227: /*
                    228:  * Process one AIDFNSCN or AIDFNGRP data structure from
                    229:  * the list of output sections
                    230:  */
                    231: 
                    232:        OUTSECT *osptr, *op;
                    233:        INFILE *inflptr;
                    234:        INSECT *insptr;
                    235:        ENODE *ep;
                    236:        long val;
                    237:        int fill, fillflag;
                    238:        ACTITEM *a2ptr;
                    239: #if !ONEPROC
                    240:        ACTITEM b;
                    241: #endif
                    242: 
                    243: #if DEBUG
                    244:        if( dflag > 2 )
                    245:                fprintf( stderr, "\n\t%04x %s (%s) %d (%s) %04x (%s)\n\t\t%08lx %d %08lx %08lx %d %d (%04x,%04x)",
                    246:                        aptr->dfnscn.ainext,
                    247:                        (aptr->dfnscn.aitype == AIDFNSCN) ? "AIDFNSCN" : "AIDFNGRP",
                    248:                        aptr->dfnscn.aiinflnm,
                    249:                        aptr->dfnscn.aiinlnno, aptr->dfnscn.ainame, aptr->dfnscn.aifill,
                    250:                        aptr->dfnscn.aiowname, aptr->dfnscn.aibndadr, aptr->dfnscn.aiattown,
                    251:                        aptr->dfnscn.aialign, aptr->dfnscn.aiblock, (unsigned) aptr->dfnscn.aifillfg,
                    252:                        (unsigned) aptr->dfnscn.aisctype, aptr->dfnscn.sectspec.head, aptr->dfnscn.sectspec.tail );
                    253: #endif
                    254: 
                    255:        osptr = (OUTSECT *) myalloc(sizeof(OUTSECT));
                    256:        if (aptr->dfnscn.aibndadr != -1L) {             /* section bonded */
                    257:                a2ptr = (ACTITEM *) myalloc(sizeof(ACTITEM));
                    258:                a2ptr->bond.aitype = AIBOND;
                    259:                a2ptr->bond.aiinflnm = aptr->dfnscn.aiinflnm;
                    260:                a2ptr->bond.aiinlnno = aptr->dfnscn.aiinlnno;
                    261:                a2ptr->bond.aioutsec = osptr;
                    262:                a2ptr->bond.aiadrbnd = aptr->dfnscn.aibndadr;
                    263:                listadd(l_AI,&bondlist,a2ptr);
                    264:                }
                    265:        else if (aptr->dfnscn.aiowname[0] != '\0') {  /*owner specified */
                    266:                a2ptr = (ACTITEM *) myalloc(sizeof(ACTITEM));
                    267:                a2ptr->dfownr.aitype = AIDFOWNR;
                    268:                a2ptr->dfownr.aiinflnm = aptr->dfnscn.aiinflnm;
                    269:                a2ptr->dfownr.aiinlnno = aptr->dfnscn.aiinlnno;
                    270:                a2ptr->dfownr.aioutsec = osptr;
                    271:                copy(a2ptr->dfownr.ainamown, aptr->dfnscn.aiowname, 8);
                    272:                listadd(l_AI,&ownlist,a2ptr);
                    273:                }
                    274:        else if (aptr->dfnscn.aiattown != 0) {  /* attr of owner */
                    275:                a2ptr = (ACTITEM *) myalloc(sizeof(ACTITEM));
                    276:                a2ptr->ownatr.aitype = AIOWNATR;
                    277:                a2ptr->ownatr.aiinflnm = aptr->dfnscn.aiinflnm;
                    278:                a2ptr->ownatr.aiinlnno = aptr->dfnscn.aiinlnno;
                    279:                a2ptr->ownatr.aioutsec = osptr;
                    280:                a2ptr->ownatr.aiownatt = aptr->dfnscn.aiattown;
                    281:                listadd(l_AI,&atownlst,a2ptr);
                    282:                }
                    283: 
                    284:        if (aptr->dfnscn.aitype == AIDFNGRP)
                    285:                osptr->oshdr.s_flags = STYP_GROUP;
                    286:        else
                    287:                osptr->oshdr.s_flags = aptr->dfnscn.aisctype;
                    288:        osptr->osalign = aptr->dfnscn.aialign;
                    289:        osptr->osblock = aptr->dfnscn.aiblock;
                    290:        osptr->osfill = aptr->dfnscn.aifill;
                    291:        osptr->osflags |= aptr->dfnscn.aifillfg;
                    292: 
                    293: /*
                    294:  * A DFNSCN need have no subordinate entries, since the following is
                    295:  * legal:
                    296:  *             .text : {}
                    297:  */
                    298: 
                    299:        if( aptr->dfnscn.sectspec.head == NULL )
                    300:                return( osptr );
                    301: 
                    302: /*
                    303:  * A DFNGRP is a sequence of one or more DFNSCN entries
                    304:  */
                    305: 
                    306:        if( aptr->dfnscn.aitype == AIDFNGRP ) {
                    307:                a2ptr = (ACTITEM *) aptr->dfnscn.sectspec.head;
                    308:                do {
                    309:                        if( ! dflt ) {
                    310: #if !ONEPROC
                    311:                                fread( &b, 1, sizeof(ACTITEM), trnfdes );
                    312:                                b.dfnscn.aiinflnm = (char *) ((int) b.dfnscn.aiinflnm + (int) strbase);
                    313:                                a2ptr = &b;
                    314: #endif
                    315:                                }
                    316: 
                    317:                        op = dfn_scn_grp(a2ptr, dflt);
                    318: 
                    319:                        op->oshdr.s_paddr = -1L;
                    320:                        listadd(l_GRP, osptr, op);
                    321:                        numoutsc++;
                    322:                        copy(op->oshdr.s_name, a2ptr->dfnscn.ainame, 8);
                    323: 
                    324:                        if( (a2ptr = a2ptr->dfnscn.ainext) == NULL )
                    325:                                return( osptr );
                    326:                        }
                    327:                while( 1 );
                    328:                }
                    329: 
                    330: /*
                    331:  * Process a DFNSCN with one or more subordinate entries, of type
                    332:  * AIADFILE, AIADDSCN, or AIEVEXPR
                    333:  */
                    334: 
                    335:        a2ptr = (ACTITEM *) aptr->dfnscn.sectspec.head;
                    336:        do {
                    337:                if( ! dflt ) {
                    338: #if !ONEPROC
                    339:                        fread( &b, 1, sizeof(ACTITEM), trnfdes );
                    340:                        b.adfile.aiinflnm = (char *) ((int) b.adfile.aiinflnm + (int) strbase);
                    341:                        a2ptr = &b;
                    342: #endif
                    343:                        }
                    344: 
                    345:                switch( a2ptr->adfile.aitype ) {
                    346: 
                    347:                case AIADFILE:
                    348: 
                    349:                        if( ! dflt )
                    350:                                a2ptr->adfile.aifilnam = (char *) ((int) a2ptr->adfile.aifilnam + (int) strbase);
                    351: 
                    352: #if DEBUG
                    353:                        if( dflag > 2 )
                    354:                                fprintf( stderr, "\n\t%04x AIADFILE (%s) %d (%s) %d %d %d",
                    355:                                        a2ptr->adfile.ainext, a2ptr->adfile.aiinflnm,
                    356:                                        a2ptr->adfile.aiinlnno, a2ptr->adfile.aifilnam, a2ptr->adfile.ainadscs,
                    357:                                        a2ptr->adfile.aifill2, (unsigned) a2ptr->adfile.aifilflg );
                    358: #endif
                    359: 
                    360:                        if( (inflptr = fndinfil(a2ptr->adfile.aifilnam)) == NULL )
                    361:                                break;
                    362:                        if( a2ptr->adfile.ainadscs == 0 ) {
                    363:                                insptr = inflptr->flishead;
                    364:                                while( insptr ) {
                    365:                                        if( insptr->isoutsec == NULL ) {
                    366:                                                inscadd(insptr, osptr);
                    367:                                                insptr->isfill = a2ptr->adfile.aifill2;
                    368:                                                insptr->isfillfg = a2ptr->adfile.aifilflg;
                    369:                                                }
                    370:                                        insptr = insptr->isnext;
                    371:                                        /*
                    372:                                         * In case inflptr is library,
                    373:                                         *  get next one
                    374:                                         */
                    375:                                        if( (insptr == NULL)  &&  (inflptr->flfiloff > 0L) )
                    376:                                                while( (inflptr = inflptr->flnext) )
                    377:                                                        if (strcmp(a2ptr->adfile.aifilnam,inflptr->flname) == 0) {
                    378:                                                                insptr = inflptr->flishead;
                    379:                                                                break;
                    380:                                                                }
                    381:                                        }
                    382:                                }
                    383:                        else {
                    384:                                fill = a2ptr->adfile.aifill2;
                    385:                                fillflag = a2ptr->adfile.aifilflg;
                    386:                                }
                    387:                        break;
                    388: 
                    389:                case AIADDSCN:
                    390: 
                    391:                        if( ! dflt )
                    392:                                a2ptr->addscn.aiscfile = (char *) ((int) a2ptr->addscn.aiscfile + (int) strbase);
                    393: 
                    394: #if DEBUG
                    395:                        if( dflag > 2 )
                    396:                                fprintf( stderr, "\n\t%04x AIADDSCN (%s) %d (%s) %04x (%s)",
                    397:                                        a2ptr->addscn.ainext, a2ptr->addscn.aiinflnm,
                    398:                                        a2ptr->addscn.aiinlnno, a2ptr->addscn.ainame, a2ptr->addscn.aifill,
                    399:                                        a2ptr->addscn.aiscfile );
                    400: #endif
                    401: 
                    402:                        if( (inflptr = fndinfil(a2ptr->addscn.aiscfile)) == NULL )
                    403:                                break;
                    404:                        insptr = inflptr->flishead;
                    405:                        while(insptr) {
                    406:                                if (equal(a2ptr->addscn.ainame,insptr->ishdr.s_name,8))  {
                    407:                                        if (insptr->isoutsec) {
                    408:                                                lderror(1, a2ptr->addscn.aiinlnno, a2ptr->addscn.aiinflnm,
                    409:                                                   "adding %s(%.8s) to multiple output sections",
                    410:                                                   inflptr->flname,
                    411:                                                   insptr->ishdr.s_name);
                    412:                                                goto contin1;
                    413:                                                }
                    414:                                        inscadd(insptr,osptr);
                    415:                                        insptr->isfill = fill;
                    416:                                        insptr->isfillfg = fillflag;
                    417:                                        insptr = NULL;
                    418:                                        if (inflptr->flfiloff > 0L)
                    419:                                        /*
                    420:                                         * In case inflptr is library,
                    421:                                         *  get next one
                    422:                                         */
                    423:                                                while( (inflptr = inflptr->flnext) )
                    424:                                                        if (strcmp(a2ptr->addscn.aiscfile,inflptr->flname) == 0) {
                    425:                                                                insptr = inflptr->flishead;
                    426:                                                                break;
                    427:                                                                }
                    428:                                        if ( insptr != NULL )
                    429:                                                continue;
                    430:                                        else
                    431:                                                goto contin1;
                    432:                                        }
                    433:                                insptr = insptr->isnext;
                    434:                                }
                    435:                        lderror(1, a2ptr->addscn.aiinlnno, a2ptr->addscn.aiinflnm,
                    436:                                "%s(%.8s) not found",
                    437:                                a2ptr->addscn.aiscfile,a2ptr->addscn.ainame);
                    438:                        break;
                    439: 
                    440:                case AIEVEXPR:
                    441: 
                    442: #if DEBUG
                    443:                        if( dflag > 2 )
                    444:                                fprintf( stderr, "\n\t%04x AIEVEXPR (%s) %d %04x\n\t\tROOT:",
                    445:                                        a2ptr->evexpr.ainext, a2ptr->evexpr.aiinflnm,
                    446:                                        a2ptr->evexpr.aiinlnno, a2ptr->evexpr.aiexptr );
                    447: #endif
                    448: 
                    449: #if ONEPROC
                    450:                        aptr = a2ptr;
                    451: #else
                    452:                        aptr = ldexp( &b );
                    453: #endif
                    454: 
                    455:                        a2ptr = a2ptr->adfile.ainext;
                    456:                        ep = aptr->evexpr.aiexptr;
                    457:                        cur_dot = osptr->oshdr.s_size;
                    458: 
                    459:                        if (ep->gnode.exleft->gnode.exop != DOT) {
                    460:                                /*
                    461:                                 * LHS of assnment is regular symbol
                    462:                                 */
                    463:                                dotacid = 0;
                    464:                                dotosptr = osptr;
                    465:                                chgdot(ep->gnode.exright);
                    466:                                listadd(l_AI, &explist, aptr);
                    467:                                }
                    468:                        else {
                    469:                                /*
                    470:                                 * LHS is DOT symbol
                    471:                                 */
                    472:                                curexp = aptr;
                    473:                                val = eval(ep->gnode.exright);
                    474:                                if (val < cur_dot)
                    475:                                        lderror(1, aptr->evexpr.aiinlnno, aptr->evexpr.aiinflnm,
                    476:                                                "attempt to decrement DOT");
                    477:                                else
                    478:                                        osptr->oshdr.s_size = val;
                    479: 
                    480:                                clrexp( aptr );
                    481:                                }
                    482:                        goto contin2;
                    483:                }
                    484: 
                    485:        contin1:
                    486:                a2ptr = a2ptr->adfile.ainext;
                    487:        contin2:
                    488:                if (a2ptr == NULL)
                    489:                        return( osptr );
                    490: 
                    491:                }
                    492:        while( 1 );
                    493: }
                    494: /*eject*/
                    495: inscadd(pin,pout)
                    496: INSECT *pin;
                    497: OUTSECT *pout;
                    498: {
                    499: 
                    500: /*
                    501:  * Add an input section to an output section.
                    502:  *
                    503:  * The text, relocation, and lineno info of the input section
                    504:  * are allocated at the end of the output section.
                    505:  */
                    506: 
                    507:        long btype;
                    508: 
                    509:        pin->isoutsec = pout;
                    510:        pin->isdispl = pout->oshdr.s_size;
                    511:        pin->islndisp = ((long) pout->oshdr.s_nlnno * (long) LINESZ);
                    512:        pout->oshdr.s_size += pin->ishdr.s_size;
                    513:        pout->oshdr.s_nlnno += pin->ishdr.s_nlnno;
                    514: 
                    515:        if (rflag) {
                    516:                pin->isrldisp = ((long) pout->oshdr.s_nreloc * (long) RELSZ);
                    517:                pout->oshdr.s_nreloc += pin->ishdr.s_nreloc;
                    518:                }
                    519: 
                    520:        btype = pin->ishdr.s_flags & BASIC_TYPES;
                    521:        if (btype)
                    522:                pout->oshdr.s_flags |= btype;
                    523:        else if ( equal( _TEXT, pin->ishdr.s_name, 8 ))
                    524:                pout->oshdr.s_flags |= STYP_TEXT;
                    525:        else if ( equal( _DATA, pin->ishdr.s_name, 8 ))
                    526:                pout->oshdr.s_flags |= STYP_DATA;
                    527:        else if ( equal( _BSS, pin->ishdr.s_name, 8 ))
                    528:                pout->oshdr.s_flags |= STYP_BSS;
                    529: 
                    530:        pout->osflags |= (pin->ishdr.s_flags & STYP_DSECT) ? OSDSECT : OSREG;
                    531:        if (pin->ishdr.s_flags & STYP_INFO)
                    532:                pout->osflags |= OSINFO;
                    533:        if (pin->ishdr.s_flags & STYP_COPY)
                    534:                pout->osflags |= OSCOPY;
                    535: 
                    536:        listadd(l_INC,pout,pin);
                    537: }
                    538: /*eject*/
                    539: INFILE *
                    540: fndinfil(fnam)
                    541: char *fnam;
                    542: {
                    543: 
                    544: /*
                    545:  * Locate the input file structure by a given name, and
                    546:  * return a pointer to the structure.
                    547:  *
                    548:  *  Note: fnam must be a null terminated string.
                    549:  */
                    550: 
                    551:        register INFILE *p;
                    552: 
                    553:        p = (INFILE *) infilist.head;
                    554:        while (p) {
                    555:                if (strcmp(fnam,p->flname) == 0) 
                    556:                        return(p);
                    557:                p = p->flnext;
                    558:                }
                    559: 
                    560:        return(NULL);
                    561: }
                    562: /*eject*/
                    563: chgdot(p)
                    564: ENODE *p;
                    565: {
                    566:        register SYMTAB *sym;
                    567:        ITEMID add_dot();
                    568: 
                    569: /*
                    570:  * This function is called when an assignment is encountered
                    571:  * within an output section specification, and the LHS of the
                    572:  * assnment is to a symbol other than DOT.  Any occurances of
                    573:  * DOT within the RHS expression must be replaced by a reference
                    574:  * to a dummy symbol table entry, which will have the correct
                    575:  * value after the output section is relocated.
                    576:  */
                    577: 
                    578:        switch(p->gnode.exop) {
                    579:        case DOT:
                    580:                if( dotacid == 0 )
                    581:                        dotacid = add_dot(cur_dot, dotosptr);
                    582:                p->nnode.exsymptr = dotacid;
                    583:                break;
                    584:        case NAME:
                    585:        case INT:
                    586:                break;
                    587:        default:
                    588:                if (p->gnode.exleft) 
                    589:                        chgdot(p->gnode.exleft);
                    590:                if (p->gnode.exright)
                    591:                        chgdot(p->gnode.exright);
                    592:        }
                    593: }
                    594: /*eject*/
                    595: add_pad()
                    596: {
                    597: 
                    598: /*
                    599:  * If the "-B" flag was specified, add any necessary "padding sections"
                    600:  * to the outpt file
                    601:  */
                    602: 
                    603:        register ANODE *ap;             /* ptr into avlist */
                    604:        ANODE *newap;                   /* ptr to padding section node */
                    605:        register OUTSECT *osp;
                    606:        register INSECT *isp;
                    607:        int no_need_pad,                /* = 1 iff don't need padding */
                    608:            counter;                    /* used to make unique names */
                    609:        char padname[8];                /* padding section name */
                    610: 
                    611: /*
                    612:  * Look for an output section which meets one of two conditions:
                    613:  *
                    614:  *     1. The section is comprised entirely of uninitialized .bss
                    615:  *             sections
                    616:  *     2. The section is of zero length
                    617:  *
                    618:  * For every output section of these types, add an additional output
                    619:  * section immediatly after it.  This "padding section" has only two
                    620:  * non-zero/non-NULL/non-trivial characteristics:
                    621:  *     1. It is composed of Bflag bytes of zero
                    622:  *     2. It is written under control of BLOCK(Bflag)
                    623:  *
                    624:  * Note that padding sections have a virtual/physical address
                    625:  * of -1 (to generate errors from any user program or utility
                    626:  * attempting to use these values), and flags indicating that
                    627:  * it is a padding section
                    628:  */
                    629: 
                    630:        counter = 0;
                    631:        for( ap = (ANODE *) avlist.head; ap; ap = ap->adnext ) {
                    632:                if( ap->adtype != ADSECT )
                    633:                        continue;
                    634: 
                    635:                osp = ap->adscnptr;
                    636:                no_need_pad = (osp->osflags & FILL);
                    637:                for( isp = osp->osinclhd; isp; isp = isp->isincnxt )
                    638:                        if( (isp->ishdr.s_scnptr > 0)  ||  (isp->isfillfg) )
                    639:                                no_need_pad = 1;
                    640:                if( ap->adsize == 0L )
                    641:                        no_need_pad = 0;
                    642:                
                    643:                if( no_need_pad )
                    644:                        continue;
                    645:                
                    646:                osp = (OUTSECT *) myalloc(sizeof(OUTSECT));
                    647:                numoutsc++;
                    648:                sprintf( padname, "-pad%2d-", counter++ );
                    649:                copy( osp->oshdr.s_name, padname, 8 );
                    650:                osp->oshdr.s_paddr = -1L;
                    651:                osp->oshdr.s_vaddr = -1L;
                    652:                osp->oshdr.s_size = Bflag;
                    653:                osp->oshdr.s_flags = STYP_PAD;
                    654:                osp->osblock = Bflag;
                    655:                
                    656:                newap = (ANODE *) myalloc(sizeof(ANODE));
                    657:                newap->adtype = ADPAD;
                    658:                newap->adsize = Bflag;
                    659:                newap->adscnptr = osp;
                    660: 
                    661:                listins( l_ADR, &avlist, ap, newap );
                    662:                }
                    663: 
                    664: #if DEBUG
                    665:        if( dflag > 1 ) {
                    666:                fprintf( stderr, "\nadd_pad" );
                    667:                dump_mem();
                    668:                }
                    669: #endif
                    670: 
                    671: }
                    672: /*eject*/
                    673: updatsms()
                    674: {
                    675: 
                    676: /*
                    677:  * After allocation, this function sets
                    678:  *     1. The section number of all output sections
                    679:  *     2. The virtual addresses of all input sections (isnewvad)
                    680:  *     3. The file offset of output sections
                    681:  *
                    682:  * In addition, the relocated value for all global symbols is 
                    683:  * computed and stored in the symbol table, along with the new
                    684:  * section number.
                    685:  *
                    686:  * The virtual addresses of output sections are set by
                    687:  * audit_regions in allocation.
                    688:  */
                    689: 
                    690:        register SYMTAB *symp;
                    691:        register OUTSECT *osp;
                    692:        register INSECT *isp;
                    693:        int snum, init;
                    694:        long vaddr, indx;
                    695:        long filoffst, lnnoptr, nrelocs;
                    696:        ANODE *ap;
                    697:        INFILE *fp;
                    698: 
                    699: /*
                    700:  * Compute the starting file offset of the first output section
                    701:  *
                    702:  * ********** NOTE NOTE NOTE NOTE **********
                    703:  *
                    704:  *     Increase the size of the optional header by the amount of
                    705:  *     space needed to generate a patch list
                    706:  *
                    707:  * ********** NOTE NOTE NOTE NOTE **********
                    708:  */
                    709: 
                    710:        hflag += psize();
                    711:        filoffst = (long) FILHSZ + hflag + SCNHSZ * numoutsc;
                    712: 
                    713:        nrelocs = 0L;
                    714:        snum = 0;
                    715: 
                    716:        for( ap = (ANODE *) avlist.head; ap; ap = ap->adnext ) {
                    717:                if (ap->adtype == ADSECT) {
                    718:                        osp = ap->adscnptr;
                    719:                        /*
                    720:                         ***** Special processing *****
                    721:                         *
                    722:                         * The description of the _TV output section is
                    723:                         * changed, so as to make it equivalent to that
                    724:                         * section of the transfer vector actually used
                    725:                         * in this ld run
                    726:                         *
                    727:                         * Note that in the default case - no ASSIGN or
                    728:                         * RANGE commands, the entire transfer vector
                    729:                         * is used, and hence this code produces no
                    730:                         * change.
                    731:                         *
                    732:                         * When ASSIGN and RANGE commands are present,
                    733:                         * the actual section of the transfer vector
                    734:                         * used is typically a subset of the entire
                    735:                         * vector. Output only the piece used
                    736:                         */
                    737: #if TRVEC
                    738:                        if( tvflag && equal(osp->oshdr.s_name,_TV,8) ) {
                    739:                                osp->oshdr.s_paddr +=
                    740:                                        (tvspec.tvrange[0] * TVENTSZ);
                    741:                                osp->oshdr.s_vaddr += 
                    742:                                        (tvspec.tvrange[0] * TVENTSZ);
                    743:                                osp->oshdr.s_size =
                    744:                                        ((tvspec.tvrange[1]-tvspec.tvrange[0]+1)*TVENTSZ);
                    745:                                }
                    746: #endif
                    747:                        init = (osp->osflags & FILL);   /* section is initialized*/
                    748:                        osp->ossecnum = ++snum;
                    749:                        vaddr = osp->oshdr.s_vaddr;
                    750:                        for( isp = osp->osinclhd; isp; isp = isp->isincnxt ) {
                    751:                                isp->isnewvad = vaddr + isp->isdispl;
                    752:                                isp->isnewpad = osp->oshdr.s_paddr + isp->isdispl;
                    753:                                if (isp->ishdr.s_scnptr > 0 || isp->isfillfg)
                    754:                                        init = 1;
                    755:                                }
                    756: 
                    757:                        if ((osp->oshdr.s_flags & STYP_NOLOAD) || (osp->oshdr.s_flags & STYP_DSECT))
                    758:                                init = 0;
                    759:                        if (init) {
                    760:                                filoffst += alignment(osp->osblock,filoffst);
                    761:                                osp->oshdr.s_scnptr = filoffst;
                    762:                                filoffst += osp->oshdr.s_size;
                    763:                                if (rflag)
                    764:                                        nrelocs += (long) osp->oshdr.s_nreloc;
                    765:                                if (filoffst % 2)
                    766:                                        ++filoffst;
                    767:                                }
                    768:                        else
                    769:                                osp->oshdr.s_scnptr = 0L;
                    770:                        }
                    771:                else if( ap->adtype == ADPAD ) {
                    772:                        osp = ap->adscnptr;
                    773:                        osp->ossecnum = ++snum;
                    774:                        filoffst += alignment(osp->osblock,filoffst);
                    775:                        osp->oshdr.s_scnptr = filoffst;
                    776:                        filoffst += osp->oshdr.s_size;
                    777:                        if( filoffst % 2 )
                    778:                                ++filoffst;
                    779:                        }
                    780:                }
                    781: 
                    782: /*
                    783:  * Do the same for the "dummy" sections (DSECTS)
                    784:  */
                    785: 
                    786:        for( osp = (OUTSECT *) dsectlst.head; osp; osp = osp->osdsnext ) {
                    787:                osp->ossecnum = ++snum;
                    788:                for( isp = osp->osinclhd; isp; isp = isp->isincnxt ) {
                    789:                        isp->isnewvad = osp->oshdr.s_vaddr + isp->isdispl;
                    790:                        isp->isnewpad = osp->oshdr.s_paddr + isp->isdispl;
                    791:                        }
                    792:                if ( osp->oshdr.s_flags & (STYP_COPY | STYP_INFO)) {
                    793:                        filoffst += alignment(osp->osblock,filoffst);
                    794:                        osp->oshdr.s_scnptr = filoffst;
                    795:                        filoffst += osp->oshdr.s_size;
                    796:                        if ( rflag )
                    797:                                nrelocs += (long) osp->oshdr.s_nreloc;
                    798:                        if ( filoffst % 2)
                    799:                                ++filoffst;
                    800:                } else {
                    801:                        osp->oshdr.s_nreloc = 0;
                    802:                        osp->oshdr.s_nlnno  = 0;
                    803:                        }
                    804:                }
                    805: 
                    806: /*
                    807:  * Loop through sections a 2nd time to set the
                    808:  * file pointer to relocation and line numbers for each section
                    809:  */
                    810: 
                    811:        lnnoptr = filoffst + nrelocs * (long) RELSZ;
                    812:        for( ap = (ANODE *) avlist.head; ap; ap = ap->adnext ) {
                    813:                if (ap->adtype == ADSECT) {
                    814:                        osp = ap->adscnptr;
                    815:                        if (osp->oshdr.s_flags & STYP_NOLOAD) {
                    816:                                osp->oshdr.s_nreloc = 0;
                    817:                                osp->oshdr.s_nlnno  = 0;
                    818:                                continue;
                    819:                                }
                    820:                        if( rflag  &&  (osp->oshdr.s_nreloc != 0) ) {
                    821:                                osp->oshdr.s_relptr = filoffst;
                    822:                                filoffst += ((long)osp->oshdr.s_nreloc *
                    823:                                                        (long) RELSZ);
                    824:                                }
                    825: #if UNIX || XL
                    826:                        if(  (!sflag && !xflag)  &&  (osp->oshdr.s_nlnno != 0) ) {
                    827: #else
                    828:                        if(  (!sflag )  &&  (osp->oshdr.s_nlnno != 0) ) {
                    829: #endif
                    830:                                osp->oshdr.s_lnnoptr = lnnoptr;
                    831:                                lnnoptr += ((long)osp->oshdr.s_nlnno *
                    832:                                                        (long) LINESZ);
                    833:                                }
                    834:                        }
                    835:                }
                    836: 
                    837: /*
                    838:  * Do the same for the "copy" sections (COPY)
                    839:  */
                    840: 
                    841:        for( osp = (OUTSECT *) dsectlst.head; osp; osp = osp->osdsnext ) {
                    842:                if ( osp->oshdr.s_flags & (STYP_COPY | STYP_INFO)) {
                    843:                        if ( rflag && (osp->oshdr.s_nreloc != 0) ) {
                    844:                                osp->oshdr.s_relptr = filoffst;
                    845:                                filoffst += ((long) osp->oshdr.s_nreloc
                    846:                                                * (long) RELSZ);
                    847:                                }
                    848:                        if ( (! sflag) && (osp->oshdr.s_nlnno != 0) ) {
                    849:                                osp->oshdr.s_lnnoptr = lnnoptr;
                    850:                                lnnoptr += ((long) osp->oshdr.s_nlnno *
                    851:                                                        (long) LINESZ);
                    852:                                }
                    853:                        }
                    854:                }
                    855: 
                    856:        symtborg = filoffst = lnnoptr;
                    857:        fp = (INFILE *) infilist.head;
                    858:        indx = 0;
                    859:        while (fp) {
                    860:                fp->flsymndx = indx;
                    861:                indx += fp->flnlsyms;
                    862:                fp = fp->flnext;
                    863:                }
                    864: 
                    865:        symp = NULL;
                    866:        while( (symp = loopsym(symp, 1)) != NULL ) {
                    867:                if( symp->sment.n_scnum > 0 ) {
                    868:                        isp = symp->smscnptr;
                    869:                        symp->sment.n_scnum = isp->isoutsec->ossecnum;
                    870:                        symp->smnewval = symp->sment.n_value 
                    871:                                + isp->isnewpad - isp->ishdr.s_paddr;
                    872:                        symp->smnewvirt = symp->smnewval
                    873:                                - isp->isnewpad + isp->isnewvad;
                    874:                        if( symp->smlocflg ) {
                    875:                                symp->smoutndx += isp->isfilptr->flsymndx;
                    876:                                }
                    877:                        else {
                    878:                                symp->smoutndx = indx++;
                    879:                                indx += symp->sment.n_numaux;
                    880:                                }
                    881:                        }
                    882:                else {
                    883:                        if ((symp->sment.n_zeroes == 0) ||
                    884:                                        (strncmp( symp->sment.n_name, ".dot", 4 ) != 0))
                    885:                                symp->smoutndx = indx++;
                    886:                        symp->smnewval = symp->sment.n_value;
                    887:                        symp->smnewvirt = symp->sment.n_value;
                    888:                        indx += symp->sment.n_numaux;
                    889:                        }
                    890:                }
                    891: #if FLEXNAMES
                    892:        tnumsyms = indx;
                    893: #endif
                    894: }
                    895: /*eject*/
                    896: OUTSECT *
                    897: findoscn(number)
                    898: int number;            /* number of desired section */
                    899: {
                    900: 
                    901: /*
                    902:  * Look through the output section list, outsclst,
                    903:  * for a section with the specified number.  Return
                    904:  * a pointer to that element of the list.  If no
                    905:  * section exists with that number, return NULL.
                    906:  */
                    907: 
                    908:        register OUTSECT *osptr;
                    909: 
                    910:        osptr = (OUTSECT *) outsclst.head;
                    911:        while ( osptr != NULL ) {
                    912:                if ( osptr->ossecnum == number )
                    913:                        return (osptr);
                    914:                osptr = osptr->osnext;
                    915:                }
                    916: 
                    917:        return (NULL);
                    918: }
                    919: /*eject*/
                    920: split_scns()
                    921: {
                    922: 
                    923: /*
                    924:  * Run though the output section list.  If the size of any output
                    925:  * section is greater then MAXSCNSZ, split the output section into
                    926:  * two (or more) output sections
                    927:  *
                    928:  * The name of a new section is the first char of the old name,
                    929:  * followed by a number, followed by the rest of the old
                    930:  * name.  Only eight characters are kept.
                    931:  */
                    932: 
                    933:        OUTSECT *osp, *newosp, *nxtosp;
                    934:        INSECT  *isp, *nxtisp;
                    935:        char    *oldname, newname[20];          /* 8 + 4 + extra */
                    936:        int     scnnumber;
                    937:        long    newdisp, startdisp;     /* OUTSECT displacements */
                    938: 
                    939: /*
                    940:  * "osp" scans down the outsclst, and "nxtosp" will
                    941:  * always point to the next section on the original
                    942:  * list.  If we have to split osp, the new node
                    943:  * will be newosp, and nxtosp will not change.
                    944:  */
                    945: 
                    946:        for( osp = (OUTSECT *) outsclst.head; osp; osp = nxtosp ) {
                    947:                nxtosp = osp->osnext;
                    948: 
                    949: /* begin KLUDGE */
                    950:                adjsize(osp);
                    951: /* end KLUDGE */
                    952: 
                    953:                if (osp->oshdr.s_flags & STYP_DSECT)
                    954:                        continue;
                    955: 
                    956:                if( (osp->osinclhd == osp->osincltl)  ||  (osp->oshdr.s_size <= MAXSCNSZ) ) {
                    957:                        /* Either there is only one input section in the
                    958:                         * output section, or the output section is
                    959:                         * within the permissible size
                    960:                         */
                    961:                        if( (isp = osp->osinclhd) == NULL )
                    962:                                continue;
                    963:                        if( isp->ishdr.s_size > MAXSCNSIZE ) {
                    964:                                lderror(1,0,NULL, "section %.8s in file %s too big",
                    965:                                        isp->ishdr.s_name, isp->isfilptr->flname);
                    966:                                osp->osinclhd = osp->osincltl = NULL;
                    967:                                }
                    968:                        continue;
                    969:                        }
                    970: 
                    971:                /*
                    972:                 * An output section is too large, and must be split.
                    973:                 *
                    974:                 * Walk through the list of input sections, to build
                    975:                 * two (or more) output sections which are all within
                    976:                 * the permissible size range
                    977:                 */
                    978: 
                    979:                osp->oshdr.s_nreloc = 0;
                    980:                osp->oshdr.s_nlnno = 0;
                    981:                isp = osp->osinclhd;
                    982:                osp->osinclhd = osp->osincltl = NULL;
                    983:                scnnumber = 0;
                    984:                oldname = osp->oshdr.s_name;
                    985: 
                    986:                newdisp = 0L;
                    987:                if( isp != NULL )
                    988:                        startdisp = osp->oshdr.s_size = isp->isdispl;
                    989:                else
                    990:                        startdisp = osp->oshdr.s_size = 0L;
                    991: 
                    992:                /*
                    993:                 * "isp" points to the current input section which we
                    994:                 * are trying to add to the output section given by
                    995:                 * "osp"
                    996:                 */
                    997: 
                    998:                for(; isp; isp = nxtisp ) {
                    999:                        nxtisp = isp->isincnxt;
                   1000:                        if( osp->oshdr.s_size + isp->ishdr.s_size <= MAXSCNSZ ) {
                   1001:                                newdisp = isp->isdispl - startdisp;
                   1002:                                if( osp->oshdr.s_size > newdisp )
                   1003:                                        lderror(1,0, NULL,
                   1004:                                                "internal error: split_scns, size of %.8s exceeds its new displacement",
                   1005:                                                osp->oshdr.s_name);
                   1006: 
                   1007:                                osp->oshdr.s_size = newdisp;
                   1008:                                isp->isincnxt = NULL;
                   1009:                                inscadd(isp, osp);
                   1010:                                }
                   1011:                        else if ( osp->oshdr.s_size != 0 ) {
                   1012:                                nxtisp = isp;   /* back up to reprocess */
                   1013:                                newosp = (OUTSECT *) myalloc(sizeof(OUTSECT));
                   1014:                                numoutsc++;
                   1015:                                sprintf(newname, "%c%x%.6s", *oldname,
                   1016:                                        scnnumber++, oldname + 1);
                   1017:                                copy(newosp->oshdr.s_name, newname, 8);
                   1018:                                newosp->oshdr.s_paddr = -1L;
                   1019:                                newosp->osnext = osp->osnext;
                   1020:                                osp->osnext = newosp;
                   1021:                                if( (OUTSECT *) outsclst.tail == osp )
                   1022:                                        outsclst.tail = (char *) newosp;
                   1023:                                osp = newosp;
                   1024:                                newdisp = 0L;
                   1025:                                startdisp = isp->isdispl;
                   1026:                                }
                   1027:                        else if ( isp->ishdr.s_size <= MAXSCNSIZE ) {
                   1028:                                isp->isincnxt = NULL;
                   1029:                                inscadd(isp, osp);
                   1030:                                }
                   1031:                        else
                   1032:                                lderror(1,0,NULL, "section %.8s in file %s is too big",
                   1033:                                        isp->ishdr.s_name, isp->isfilptr->flname);
                   1034:                        }
                   1035: 
                   1036:                }
                   1037: 
                   1038: }
                   1039: /*eject*/
                   1040: psize()
                   1041: {
                   1042: /*
                   1043:  * Determine the size of the patch list. This is done by looking for
                   1044:  * all output sections having the name of ".patchnn", where nn is a
                   1045:  * two-digit number
                   1046:  *
                   1047:  * This routine returns, as an int value, the size of the patch list
                   1048:  */
                   1049: 
                   1050:        register int index, space;
                   1051:        char pname[10];
                   1052:        OUTSECT *fndoutsec();
                   1053: 
                   1054:        if( ! pflag )
                   1055:                return( 0 );
                   1056:        else
                   1057:                space = sizeof(long);
                   1058: 
                   1059: /*
                   1060:  * Patch sections, if they exist, must be named consecutively, starting
                   1061:  * at ".patch00"
                   1062:  */
                   1063: 
                   1064:        for( index = 0; index < 100; index++ ) {
                   1065:                if (index < 10)
                   1066:                        sprintf(pname, ".patch0%d", index);
                   1067:                else
                   1068:                        sprintf( pname, ".patch%d", index );
                   1069:                if( fndoutsec(pname) == NULL )
                   1070:                        break;
                   1071:                space += PESIZE;
                   1072:                }
                   1073: 
                   1074:        return( space );
                   1075: }
                   1076: /*eject*/
                   1077: OUTSECT *
                   1078: fndoutsec(nam)
                   1079: char *nam;
                   1080: {
                   1081:        register OUTSECT *p, *q;
                   1082: 
                   1083:        for( p = (OUTSECT *) outsclst.head; p; p=p->osnext ) {
                   1084:                if (p->oshdr.s_flags & STYP_GROUP)
                   1085:                        for( q = (OUTSECT *) p->osinclhd; q; q=q->osnext ) {
                   1086:                                if (equal(nam,q->oshdr.s_name,8))
                   1087:                                        return(q);
                   1088:                        }
                   1089:                else
                   1090:                        if (equal(nam,p->oshdr.s_name,8))
                   1091:                                return(p);
                   1092:        }
                   1093:        return(NULL);
                   1094: }
                   1095: 
                   1096: 
                   1097: 
                   1098: 
                   1099: #if ILDOPT
                   1100: add_extra()
                   1101: {
                   1102: 
                   1103: /* If the "-ild" flag was specified, add sections to the output file to
                   1104:  * cover any remaining configured memory.
                   1105:  */
                   1106: 
                   1107:        register ANODE *ap, *newap;     /* ptr into avlist */
                   1108:        OUTSECT *osp1, *osp2;           /* ptrs to the new output section headers */
                   1109:        int counter;                    /* used to make unique names */
                   1110:        char sectname[9];               /* new section name */
                   1111: 
                   1112: /* For each remaining area of available memory, create a fake output section
                   1113:  * that fits in that area. The purpose of this is to cover all of configured
                   1114:  * memory so that the incremental ld will be able to determine the memory
                   1115:  * configuration. Increase numoutsc to leave room for the .history section
                   1116:  * header.
                   1117:  */
                   1118: 
                   1119:        numoutsc++;
                   1120:        counter = 0;
                   1121:        for (ap = (ANODE *) avlist.head; ap; ap = ap->adnext) {
                   1122:                if (counter > 99)
                   1123:                        break;
                   1124:                if (ap->adtype != ADAVAIL)
                   1125:                        continue;
                   1126:                if ( ap != (ANODE *) avlist.head && ap->adprev->adtype != ADAVAIL &&
                   1127:                      ap->adprev->adscnptr != NULL &&
                   1128:                      (ap->adprev->adscnptr->oshdr.s_flags & STYP_NOLOAD)  &&
                   1129:                     ap != (ANODE *) avlist.tail && ap->adnext->adtype != ADAVAIL &&
                   1130:                      ap->adnext->adscnptr != NULL &&
                   1131:                      (ap->adnext->adscnptr->oshdr.s_flags & STYP_NOLOAD)    )
                   1132:                        continue;
                   1133: 
                   1134:                ap->adtype = ADSECT;
                   1135:                newap = (ANODE *) myalloc( sizeof(ANODE) + 2 * sizeof(OUTSECT));
                   1136:                osp1 = (OUTSECT *) (newap + 1);
                   1137:                osp2 = osp1 + 1;
                   1138:                numoutsc += 2;
                   1139:                if (counter < 10)
                   1140:                        sprintf(sectname, ".i_l_d0%d", counter++);
                   1141:                else
                   1142:                        sprintf( sectname, ".i_l_d%d", counter++);
                   1143:                copy( osp1->oshdr.s_name, sectname, 8 );
                   1144:                osp1->oshdr.s_flags = STYP_DSECT;
                   1145:                ap->adscnptr = osp1;
                   1146: 
                   1147:                if (counter < 10)
                   1148:                        sprintf( sectname, ".i_l_d0%d", counter++);
                   1149:                else
                   1150:                        sprintf( sectname, ".i_l_d%d", counter++ );
                   1151:                copy( osp2->oshdr.s_name, sectname, 8 );
                   1152:                osp2->oshdr.s_paddr = ap->adpaddr;
                   1153:                osp2->oshdr.s_vaddr = ap->adpaddr;
                   1154:                osp2->oshdr.s_size = ap->adsize;
                   1155:                osp2->oshdr.s_flags = STYP_DSECT;
                   1156:                osp2->osflags = 0;
                   1157: 
                   1158:                newap->adtype = ADSECT;
                   1159:                newap->adpaddr = ap->adpaddr;
                   1160:                newap->adsize = ap->adsize;
                   1161:                newap->adscnptr = osp2;
                   1162:                newap->admemp = ap->admemp;
                   1163:                newap->adregp = ap->adregp;
                   1164:                listins( l_ADR, &avlist, ap, newap );
                   1165:        }
                   1166: }
                   1167: #endif
                   1168: 
                   1169: 
                   1170: 
                   1171: 
                   1172: long
                   1173: check_sect( osptr )
                   1174: OUTSECT *osptr;
                   1175: {
                   1176: 
                   1177: /* 
                   1178:  * check the flags in the output section. if all the input sections are dummy
                   1179:  * sections, the output section should be a dummy section.
                   1180:  * If no input section was a regular section and one was a copy section
                   1181:  * the output will be a copy section.  If any input section was an info
                   1182:  * section,  the output section will have the info flag on. (Most flags
                   1183:  * are not mutually exclusive.)
                   1184:  * if a bss section is combined with data or text, the bss section is
                   1185:  * initialized, and becomes data.
                   1186:  * return the size of the section if the output section is not a dummy
                   1187:  * (the size is used in allocating space for a group).
                   1188:  */
                   1189: 
                   1190:        if ((osptr->osflags & OSDSECT) && !(osptr->osflags & OSREG)) {
                   1191:                osptr->oshdr.s_flags |= STYP_DSECT;
                   1192:                /* remember COPY section also has OSDSECT on */
                   1193:                if (osptr->osflags & OSCOPY)
                   1194:                        osptr->oshdr.s_flags |= STYP_COPY;
                   1195:                }
                   1196:        if (osptr->osflags & OSINFO)
                   1197:                osptr->oshdr.s_flags |= STYP_INFO;
                   1198: 
                   1199:        if ((osptr->oshdr.s_flags & STYP_BSS) &&
                   1200:                        ((osptr->oshdr.s_flags & (STYP_TEXT | STYP_DATA)) ||
                   1201:                        (osptr->osflags & FILL))) {
                   1202:                osptr->oshdr.s_flags ^= STYP_BSS;
                   1203:                osptr->oshdr.s_flags |= STYP_DATA;
                   1204:                }
                   1205: 
                   1206:        if ( !(osptr->oshdr.s_flags & BASIC_TYPES))
                   1207:                if (equal( _TEXT, osptr->oshdr.s_name, 8 ))
                   1208:                        osptr->oshdr.s_flags |= STYP_TEXT;
                   1209:                else if (equal( _DATA, osptr->oshdr.s_name, 8 ))
                   1210:                        osptr->oshdr.s_flags |= STYP_DATA;
                   1211:                else if (equal( _BSS, osptr->oshdr.s_name, 8 ))
                   1212:                        osptr->oshdr.s_flags |= STYP_BSS;
                   1213: 
                   1214:        return ((osptr->oshdr.s_flags & STYP_DSECT) ? 0L : osptr->oshdr.s_size);
                   1215: }

unix.superglobalmegacorp.com

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