Annotation of researchv9/jerq/sgs/ld/ld2.c, revision 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.