Annotation of researchv9/jerq/sgs/ld/tv.c, revision 1.1

1.1     ! root        1: static char ID[] = "@(#) tv.c: 1.15 5/1/83";
        !             2: 
        !             3: #include <stdio.h>
        !             4: 
        !             5: #include "system.h"
        !             6: 
        !             7: #if TS || RT
        !             8: #include <ar.h>
        !             9: #else
        !            10: #include <archive.h>
        !            11: #endif
        !            12: 
        !            13: #include "reloc.h"
        !            14: #include "sdpsrc/hd/define2.h"
        !            15: #include "structs.h"
        !            16: #include "tv.h"
        !            17: #include "ldtv.h"
        !            18: #include "ldfcn.h"
        !            19: #include "extrns.h"
        !            20: #include "list.h"
        !            21: #include "sgsmacros.h"
        !            22: #include "bool.h"
        !            23: #include "ldmacros.h"
        !            24: 
        !            25: static FILE    *tvstream = NULL;
        !            26: #if AR16WR
        !            27: static char *tvbuf;
        !            28: #endif
        !            29: static FILE    *tvread = NULL;
        !            30: static int     tvnxt;          /* next available tv slot */
        !            31: long           gettvnxt();     /* finds next usable slot */
        !            32: /*eject*/
        !            33: tvspecdef()
        !            34: {
        !            35: #if TRVEC
        !            36:        /*
        !            37:         * Complete definition of tvspec
        !            38:         *      called just after reading transfer file
        !            39:         */
        !            40: 
        !            41:        register unsigned spare;
        !            42: 
        !            43: #if !ONEPROC
        !            44:        tvspec.tvinflnm = (char *) ((int) tvspec.tvinflnm + (int) strbase);
        !            45: #endif
        !            46:        spare = (unsigned) tvspec.tvosptr;
        !            47:        tvspec.tvosptr = (OUTSECT *) myalloc(sizeof(OUTSECT));
        !            48:        tvspec.tvosptr->oshdr.s_size = ((long) spare) * TVENTSZ;
        !            49:        if ( aflag ) {
        !            50:                /*
        !            51:                 * Define the Output Section which will be used to 
        !            52:                 * contain the tv
        !            53:                 */
        !            54:                tvspec.tvosptr->osflags = FILL;
        !            55:                tvspec.tvosptr->osalign = 16;
        !            56:                copy(tvspec.tvosptr->oshdr.s_name, _TV, 8);
        !            57:                tvspec.tvosptr->oshdr.s_paddr = -1L;    /*none given */
        !            58:                if (tvspec.tvrange[0]==0) /* leave slot 0 empty */
        !            59:                        tvspec.tvosptr->oshdr.s_size += TVENTSZ;
        !            60:                }
        !            61: 
        !            62: #endif
        !            63: }
        !            64: 
        !            65: #if TRVEC
        !            66: tvreloc()
        !            67: {
        !            68: 
        !            69:        register INSECT *sptr;
        !            70:        register int    numreloc;       /* nbr of relocation entries  */
        !            71:        register SYMTAB *pglob;         /* ptr to ld symbol entry     */
        !            72:        AUXTAB          *paux;          /* ptr to auxillary entry     */
        !            73:        AUXENT          aux;            /* auxillary entry            */
        !            74:        SYMENT          lsym;           /* local symbol table entry   */
        !            75:        SCNHDR          shdr;           /* section header             */
        !            76:        RELOC           rentry;         /* local relocation entry     */
        !            77:        LDFILE          *rfd,rfdbuf, *ifd, ifdbuf;
        !            78:        INFILE          *infl, *pnfl;
        !            79:        char            *symname;
        !            80: 
        !            81:        /*
        !            82:         * the functions in DMERT's shared libraries have 0 in the tvndx
        !            83:         * field. To insure that all functions needing tv slots have P_TV
        !            84:         * in the tvndx field, scan all relocation entries for references
        !            85:         * to functions in shared libraries.
        !            86:         */
        !            87: 
        !            88:        rfd = &rfdbuf;
        !            89:        ifd = &ifdbuf;
        !            90:        IOPTR(ifd) = NULL;
        !            91:        pnfl = NULL;
        !            92:        infl = (INFILE *)infilist.head;
        !            93:        while (infl != NULL) {
        !            94: 
        !            95:                OFFSET(ifd) = OFFSET(rfd) = infl->flfiloff;
        !            96:                if ( IOPTR(ifd) == NULL) {
        !            97:                        if ((IOPTR(ifd) = fopen(infl->flname, "r")) == NULL ||
        !            98:                           (IOPTR(rfd) = fopen(infl->flname, "r")) == NULL )
        !            99:                                lderror(2,0,NULL, "Can't open %s", infl->flname);
        !           100:                        if (infl->flfiloff == 0L)
        !           101:                                TYPE(ifd) = TYPE(rfd) = 0;
        !           102:                        else
        !           103:                                TYPE(ifd) = TYPE(rfd) = USH_ARTYPE;
        !           104:                        }
        !           105:                if (TYPE(ifd) == ARTYPE) {
        !           106:                        if (FSEEK(ifd, 0L, BEGINNING) != OKFSEEK)
        !           107:                                lderror(2,0,NULL, "internal error: fail to seek to the member of %s",
        !           108:                                infl->flname);
        !           109:                        }
        !           110:                if (FREAD(&(HEADER(ifd)),FILHSZ,1,ifd) != 1 )
        !           111:                        lderror(2,0,NULL, "fail to read file header of %s", infl->flname);
        !           112:                if (HEADER(ifd).f_flags & F_RELFLG) {
        !           113:                        pnfl = infl;
        !           114:                        infl = infl->flnext;
        !           115:                        continue;
        !           116:                        }
        !           117: 
        !           118:                HEADER(rfd) = HEADER(ifd);
        !           119: 
        !           120:                for( sptr = infl->flishead; sptr != NULL; sptr = sptr->isnext ) {
        !           121:                        if( (numreloc = sptr->ishdr.s_nreloc) > 0 ) {
        !           122:                                if (FSEEK(rfd,(long) (FILHSZ+HEADER(rfd).f_opthdr+
        !           123:                                        (sptr->isecnum-1) * SCNHSZ),BEGINNING) != OKFSEEK ||
        !           124:                                FREAD(&shdr,SCNHSZ,1,rfd) != 1 ||
        !           125:                                FSEEK(rfd,shdr.s_relptr,BEGINNING) != OKFSEEK)  {
        !           126:                                        lderror(1,0,NULL, "Seek to relocation entries for section %.8s in file %s failed",
        !           127:                                                sptr->ishdr.s_name, infl->flname);
        !           128:                                        numreloc = 0;
        !           129:                                        }
        !           130:                                }
        !           131:                        while( numreloc-- ) {
        !           132:                                if (fread(&rentry, RELSZ, 1, IOPTR(rfd)) != 1)
        !           133:                                        lderror(2,0,NULL,"fail to read reloc entries of file %s",
        !           134:                                        infl->flname);
        !           135:                                if( ! (ISTVRELOC(rentry.r_type)) )
        !           136:                                        continue;
        !           137:                                if (FSEEK(ifd,HEADER(ifd).f_symptr+
        !           138:                                        rentry.r_symndx * SYMESZ,BEGINNING) != OKFSEEK ||
        !           139:                                FREAD(&lsym,SYMESZ,1,ifd) != 1)
        !           140:                                        lderror(2,0,NULL,"fail to read symtb entry %ld of file %s",
        !           141:                                        rentry.r_symndx,infl->flname);
        !           142:                                if ( lsym.n_sclass != C_EXT )
        !           143:                                        continue;       /* ignore statics */
        !           144: 
        !           145:                                symname = SYMNAME( lsym );
        !           146:                                pglob = findsym( symname );
        !           147: 
        !           148:                                if ( pglob->sment.n_scnum > 0) {
        !           149:                                        if( pglob->sment.n_numaux > 0 ) {
        !           150:                                                paux = getaux(pglob->smauxid);
        !           151:                                                if  (paux->axent.x_sym.x_tvndx == 0) { 
        !           152:                                                        paux->axent.x_sym.x_tvndx = P_TV;
        !           153:                                                        tvspec.tvosptr->oshdr.s_size += TVENTSZ;
        !           154:                                                        PUTAUX(paux, 1);
        !           155:                                                        }
        !           156:                                                else
        !           157:                                                        PUTAUX(paux, 0);
        !           158:                                                PUTSYM( pglob, 0 );
        !           159:                                        } else {
        !           160:                                                zero(&aux, AUXESZ);
        !           161:                                                aux.x_sym.x_tvndx = P_TV;
        !           162:                                                tvspec.tvosptr->oshdr.s_size += TVENTSZ;
        !           163:                                                putaux( makeaux(pglob, &aux, 0), 1);
        !           164:                                                PUTSYM( pglob, 1 );
        !           165:                                        }
        !           166: 
        !           167:                                } else
        !           168:                                        PUTSYM( pglob, 0 );
        !           169:                        }
        !           170:                }
        !           171: 
        !           172:                pnfl = infl;
        !           173:                infl = infl->flnext;
        !           174: 
        !           175:                /* see if next input is from the same archive */
        !           176:                if ((pnfl->flfiloff > 0L) && (infl != NULL))
        !           177:                        if (strcmp(pnfl->flname, infl->flname) == 0 &&
        !           178:                                        (pnfl->flfiloff < infl->flfiloff))
        !           179:                        continue;
        !           180: 
        !           181:                fclose(IOPTR(ifd));
        !           182:                fclose(IOPTR(rfd));
        !           183:                IOPTR(ifd) = NULL;
        !           184:                }
        !           185: 
        !           186: }
        !           187: #endif
        !           188: 
        !           189: 
        !           190: 
        !           191: tvupdat()
        !           192: {
        !           193: #if TRVEC
        !           194: /*
        !           195:  * If _TV section is not user-defined but needs to
        !           196:  * be, add it to the list of output sections
        !           197:  *
        !           198:  *  Check if _TV section needs to be bonded. If so, add it to
        !           199:  *  the bondlist
        !           200:  */
        !           201: 
        !           202:        OUTSECT *osptr;
        !           203: 
        !           204:        if ( (osptr = fndoutsec(_TV)) != NULL ) {
        !           205:                ++usrdeftv;
        !           206:                /* redo work done in tvspecdef() */
        !           207:                free( tvspec.tvosptr );
        !           208:                tvspec.tvosptr = osptr;
        !           209:                tvspec.tvosptr->osflags = FILL;
        !           210:                tvspec.tvosptr->osalign  = 16;
        !           211:                tvspec.tvosptr->oshdr.s_paddr = -1L;
        !           212:        } else {
        !           213:                /*
        !           214:                 * User defined no .tv output section but .tv
        !           215:                 * input sections may be present
        !           216:                 */
        !           217:                if ( ! aflag )
        !           218:                        return;
        !           219:                if ( usrdeftv ) /* there are .tv input sections */
        !           220:                        if ( tvspec.tvrange[0] == 0 )
        !           221:                                tvspec.tvosptr->oshdr.s_size -= TVENTSZ;
        !           222:                ++numoutsc;
        !           223:                listadd(l_OS, &outsclst, tvspec.tvosptr);
        !           224: 
        !           225:                if( tvspec.tvbndadr != -1L ) {
        !           226:                        register ACTITEM *aptr;
        !           227: 
        !           228:                        aptr = (ACTITEM *) myalloc(sizeof(ACTITEM));
        !           229:                        aptr->bond.aitype = AIBOND;
        !           230:                        aptr->bond.aiinflnm = tvspec.tvinflnm;
        !           231:                        aptr->bond.aiinlnno = tvspec.tvinlnno;
        !           232:                        aptr->bond.aioutsec = tvspec.tvosptr;
        !           233:                        aptr->bond.aiadrbnd = tvspec.tvbndadr;
        !           234:                        listadd(l_AI, &bondlist, aptr);
        !           235:                        }
        !           236:                }
        !           237: #endif
        !           238: }
        !           239: /*eject*/
        !           240: tvupdt2()
        !           241: {
        !           242: #if TRVEC
        !           243:        OUTSECT *osptr;
        !           244:        long    *lptr;
        !           245: 
        !           246:        if ( usrdeftv ) {
        !           247:                osptr = fndoutsec(_TV);
        !           248:                /*
        !           249:                 * Assume RANGE(0,N)
        !           250:                 */
        !           251:                tvspec.tvlength = osptr->oshdr.s_size / TVENTSZ;
        !           252:                if ( tvspec.tvrange[1] == 0 ) /* no RANGE directive */
        !           253:                        tvspec.tvrange[1] = tvspec.tvlength - 1;
        !           254:        } else {
        !           255:                /*
        !           256:                 * Make sure that TV directive is adequate
        !           257:                 * and fill in missing spaces
        !           258:                 */
        !           259: 
        !           260:                lptr = &tvspec.tvosptr->oshdr.s_size;
        !           261:                if ((tvspec.tvrange[1]!=0)
        !           262:                  &&((long)((tvspec.tvrange[1]-tvspec.tvrange[0]+(tvspec.tvrange[0]? 1 : 2))*TVENTSZ)<*lptr))
        !           263:                        lderror(2,0,tvspec.tvinflnm, "tv range allows %d entries; %d needed",
        !           264:                                        tvspec.tvrange[1]-tvspec.tvrange[0]+1,
        !           265:                                        (int) (*lptr/TVENTSZ));
        !           266:                if( (((long) tvspec.tvlength) * TVENTSZ) >= *lptr )
        !           267:                        *lptr = ((long) tvspec.tvlength) * TVENTSZ;
        !           268:                else    if( tvspec.tvlength == 0 )
        !           269:                                tvspec.tvlength = *lptr / TVENTSZ;
        !           270:                        else
        !           271:                                lderror(1,0,NULL, "tv needs %ld entries; only %d allowed",
        !           272:                                        *lptr/TVENTSZ, tvspec.tvlength);
        !           273:                if (tvspec.tvrange[1] == 0)
        !           274:                        tvspec.tvrange[1] = tvspec.tvlength - 1;
        !           275:                }
        !           276: #endif
        !           277: }
        !           278: /*eject*/
        !           279: tvinit()
        !           280: {
        !           281: #if TRVEC
        !           282: 
        !           283: /*
        !           284:  * Initialize for writing the transfer vector
        !           285:  */
        !           286: 
        !           287:        register SYMTAB *pglob;
        !           288:        register AUXTAB *paux;
        !           289:        register int    indx;
        !           290:        SCNHDR  *psect;
        !           291:        TVENTRY outslot;
        !           292:        AUXENT  aux;
        !           293:        long    offset;         /* where to write slot  */
        !           294:        int     changed;
        !           295: 
        !           296: 
        !           297:        if( (tvstream = fopen(outfilnm, "r+")) == NULL )
        !           298:                lderror(2,0,NULL, "can't open %s to write the tv",
        !           299:                        outfilnm);
        !           300: #if AR16WR
        !           301:        tvbuf = myalloc( BUFSIZ );
        !           302:        setbuf( tvstream, tvbuf );
        !           303: #endif
        !           304: 
        !           305:        fseek(tvstream, tvspec.tvosptr->oshdr.s_scnptr, 0);
        !           306:        for ( indx = tvspec.tvrange[0]; indx <= tvspec.tvrange[1]; ++indx)
        !           307:                fwrite(&tvspec.tvfill, TVENTSZ, 1, tvstream);
        !           308: 
        !           309: /*
        !           310:  *     For each tv slot assignment directive, write out that slot
        !           311:  *     if it is legal and update the ld symbol table appropriately.
        !           312:  *
        !           313:  *     TV slot assignment directives are of the form "func=n" where
        !           314:  *     func is a function name and n is a transfer vector index. Another
        !           315:  *     directive specifies a RANGE for the current load, meaning that
        !           316:  *     all functions defined in this load are to be assigned slots within
        !           317:  *     the given range. Slot assignment directives for functions outside
        !           318:  *     the given range are for use in resolving references to functions
        !           319:  *     defined in another subsystem. Ld depends on the veracity and
        !           320:  *     competence of the user to insure that this is, after all, the
        !           321:  *     slot index assigned to this function in another subsystem load.
        !           322:  *
        !           323:  *     Certain conditions result in errors.
        !           324:  *     1) If the user specifies a LENGTH for the total transfer vector,
        !           325:  *             a) if more slots are required than the given LENGTH allows,
        !           326:  *     or      b) if an ASSIGN directive is issued which lies beyond the
        !           327:  *                specified LENGTH
        !           328:  *        then ERROR
        !           329:  *     2) If the user ASSIGNs a slot S to a function which is undefined
        !           330:  *        in the current load, then
        !           331:  *             if  R1 <= S <= R2
        !           332:  *                     then ERROR
        !           333:  *             {where R1 is n in the directive RANGE(n,m) or 0;
        !           334:  *                    R2 is m in the directive RANGE(n,m) or LENGTH; }
        !           335:  *     3) If the user ASSIGNs a slot to a function which is defined
        !           336:  *        in the current load, then
        !           337:  *             if NOT R1 <= S <= R2
        !           338:  *                     then ERROR
        !           339:  *
        !           340:  *     Otherwise the assigned function slot is either used to update
        !           341:  *     the ld symbol table and/or written to the a.out file or, if the
        !           342:  *     assigned function is unreferenced in the current load, ignored.
        !           343:  */
        !           344: 
        !           345: #if ONEPROC
        !           346:        while (tvslot1)  {
        !           347: #else
        !           348:        tvslot1 = (TVASSIGN *) myalloc(sizeof(TVASSIGN));
        !           349: 
        !           350:        while( tvslotcnt-- ) {
        !           351:                fread( tvslot1, sizeof(TVASSIGN), 1, trnfdes);
        !           352: #endif
        !           353: 
        !           354:                /*
        !           355:                 * If the symbol has never been referenced, ignore 
        !           356:                 * the ASSIGN command
        !           357:                 */
        !           358:                if( (pglob = findsym(tvslot1->funname)) == NULL ) {
        !           359: #if ONEPROC
        !           360:                        tvslot1 = tvslot1->nxtslot;
        !           361: #endif
        !           362:                        continue;
        !           363:                        }
        !           364: 
        !           365:                changed = 0;
        !           366:                if( pglob->sment.n_scnum == 0 ) {
        !           367:                        /*
        !           368:                         * The symbol is referenced but not defined
        !           369:                         */
        !           370:                        if( (tvslot1->slot >= tvspec.tvrange[0]) &&
        !           371:                            (tvslot1->slot <= tvspec.tvrange[1]) ) {
        !           372:                                PUTSYM(pglob, 0);
        !           373:                                lderror(2,0,tvspec.tvinflnm,
        !           374:                                        "Undefined symbol assigned a tv slot within tv range");
        !           375:                                }
        !           376:                        else {
        !           377:                                if( pglob->sment.n_numaux == 0 ) {
        !           378:                                        zero(&aux, AUXESZ);
        !           379:                                        paux = makeaux(pglob, &aux, 0);
        !           380:                                        changed = 1;
        !           381:                                } else {
        !           382:                                        paux = getaux(pglob->smauxid);
        !           383:                                        }
        !           384:                                paux->axent.x_sym.x_tvndx = P_TV;
        !           385:                                PUTAUX(paux, 1);
        !           386:                                }
        !           387:                        }
        !           388:                else {
        !           389:                        /*
        !           390:                         * The symbol is defined
        !           391:                         */
        !           392:                        if( (tvslot1->slot < tvspec.tvrange[0]) ||
        !           393:                            (tvslot1->slot > tvspec.tvrange[1]) ) {
        !           394:                                PUTSYM(pglob, 0);
        !           395:                                lderror(2,0,tvspec.tvinflnm,
        !           396:                                        "Defined symbol assigned a tv slot outside tv range");
        !           397:                                }
        !           398:                        }
        !           399: 
        !           400:                /*
        !           401:                 * Update ld symbol table aux entry
        !           402:                 */
        !           403: 
        !           404:                if (pglob->sment.n_numaux <= 0)  {
        !           405:                        if (pglob->sment.n_type == 0) {
        !           406:                                zero( &aux, AUXESZ );
        !           407:                                paux = makeaux(pglob, &aux, 0);
        !           408:                                changed = 1;
        !           409:                                paux->axent.x_sym.x_tvndx = N_TV;
        !           410:                        } else
        !           411:                                lderror(2,0,tvspec.tvinflnm,
        !           412:                                        "attempt to assign tv slot to illegal symbol");
        !           413:                } else
        !           414:                        paux = getaux(pglob->smauxid);
        !           415:                /*
        !           416:                 * If a function has been defined but never referenced
        !           417:                 * through a tv, then the tvndx is still N_TV, not P_TV
        !           418:                 * thus we need to test for both as the user may be
        !           419:                 * defining the function for use in another subsystem
        !           420:                 * and this code would otherwise generate an error message
        !           421:                 */
        !           422:                if( paux->axent.x_sym.x_tvndx != P_TV && paux->axent.x_sym.x_tvndx != N_TV ) {
        !           423:                        PUTAUX(paux,0);
        !           424:                        PUTSYM(pglob, changed);
        !           425:                        lderror(2,0,tvspec.tvinflnm,
        !           426:                                "Two tv slot assignments for function %.8s: %d and %d",
        !           427:                                SYMNAME( pglob->sment ),
        !           428:                                paux->axent.x_sym.x_tvndx,
        !           429:                                tvslot1->slot);
        !           430:                } else {
        !           431:                        paux->axent.x_sym.x_tvndx = tvslot1->slot;
        !           432:                        PUTAUX(paux, 1);
        !           433:                        }
        !           434: 
        !           435:                /*
        !           436:                 * Determine if it is necessary to actually write the
        !           437:                 * tv slot to the output file: does the slot fall
        !           438:                 * within the specified tv range
        !           439:                 */
        !           440: 
        !           441:                if( (tvslot1->slot < tvspec.tvrange[0])  ||
        !           442:                    (tvslot1->slot > tvspec.tvrange[1]) ) {
        !           443:                        PUTSYM(pglob, changed);
        !           444: #if ONEPROC
        !           445:                        tvslot1 = tvslot1->nxtslot;
        !           446: #endif
        !           447:                        continue;
        !           448:                        }
        !           449: 
        !           450:                offset = (long) (tvspec.tvosptr->oshdr.s_scnptr + (TVENTSZ *
        !           451:                          (tvslot1->slot - tvspec.tvrange[0])));
        !           452:                fseek(tvstream, offset-ftell(tvstream), 1);
        !           453: 
        !           454:                setslot(pglob, psect, &outslot);
        !           455: 
        !           456:                PUTSYM(pglob, changed);
        !           457:                fwrite(&outslot, TVENTSZ, 1, tvstream);
        !           458: #if ONEPROC
        !           459:                tvslot1 = tvslot1->nxtslot;
        !           460: #endif
        !           461:                }
        !           462: 
        !           463:        fflush(tvstream);
        !           464:        
        !           465:        /*
        !           466:         * Don't use slot 0 as it is illegal in C to have any
        !           467:         * type of valid pointer with a zero value
        !           468:         */
        !           469: 
        !           470:        tvnxt = (tvspec.tvrange[0] != 0) ? tvspec.tvrange[0] : 1;
        !           471: 
        !           472:        /*
        !           473:         * Position tv file pointers:
        !           474:         *      tvstream : start of the tv (range)
        !           475:         *      tvread   : start of first legal tv slot
        !           476:         */
        !           477:        if( (tvread=fopen(outfilnm,"r")) == NULL )
        !           478:                lderror(2,0,NULL,"Cannot open %s to read tv",outfilnm);
        !           479:        fseek(tvstream, tvspec.tvosptr->oshdr.s_scnptr, 0);
        !           480:        fseek(tvread, ((long)(tvspec.tvosptr->oshdr.s_scnptr + 
        !           481:                (tvspec.tvrange[0] ? 0 : TVENTSZ))), 0);
        !           482: 
        !           483:        return;
        !           484: 
        !           485: #endif
        !           486: }
        !           487: /*eject*/
        !           488: tvslot(pglob, psym, infile, cs)
        !           489: SYMTAB         *pglob;         /* symbol is in ld symbol table entry */
        !           490: struct syment  *psym;          /* symtab entry is from input file */
        !           491: FILE           *infile;        /* input file stream */
        !           492: unsigned short cs;             /* segment value; used only for psym */
        !           493: {
        !           494: 
        !           495: /*
        !           496:  * Check whether the given symbol needs a slot
        !           497:  * in the tv.  If it does and one has not be assigned,
        !           498:  * assign the symbol a slot and write that entry to the
        !           499:  * tv in the output file
        !           500:  *
        !           501:  * The symbol is passed in either a gsym or syment symbol table
        !           502:  * entry data structure.  For a gsym, look in the aux entry; for a
        !           503:  * syment, read the next syment from the input file.
        !           504:  * In the latter case, reseek the input file pointer to the original
        !           505:  * position
        !           506:  *
        !           507:  * The return value is:
        !           508:  *
        !           509:  *             -1      symbol doesn't need tv slot
        !           510:  *              0      symbol needs tv slot, but this is
        !           511:  *                     not an absolute load
        !           512:  *             >0      tv slot needed and assigned
        !           513:  */
        !           514: 
        !           515:        int             ret;
        !           516:        long            offset;         /* where to write next */
        !           517:        AUXTAB          *paux;
        !           518:        TVENTRY         tvent;
        !           519:        AUXENT          aux;
        !           520: 
        !           521:        if( ! tvflag )
        !           522:                return ( -1 );
        !           523: 
        !           524: #if TRVEC
        !           525:        if( pglob != NULL )
        !           526:                psym = &pglob->sment;
        !           527: 
        !           528: /*
        !           529:  * We are assured that all symbols needing tv slots have already
        !           530:  * been detected in loadobjf() and their tvndx set to P_TV.
        !           531:  * Except for static functions which are detected in psymtab
        !           532:  * but their tvndx left at N_TV
        !           533:  */
        !           534: 
        !           535:        if( psym->n_numaux == 0 )
        !           536:                return ( -1 );
        !           537: 
        !           538:        if( pglob != NULL ) {
        !           539:                /*
        !           540:                 * This routine was given an ld symbol table entry
        !           541:                 */
        !           542:                paux = getaux(pglob->smauxid);
        !           543:                if (paux->axent.x_sym.x_tvndx == 0 ) {
        !           544:                        PUTAUX(paux, 0);
        !           545:                        return ( -1 );
        !           546:                        }
        !           547:                if( paux->axent.x_sym.x_tvndx == P_TV ) {
        !           548:                        /*
        !           549:                         * This symbol is referenced through a tv:
        !           550:                         *
        !           551:                         *      tvndx == P_TV
        !           552:                         */
        !           553:                        if( ! aflag ) {
        !           554:                                PUTAUX(paux, 0);
        !           555:                                return ( 0 );
        !           556:                                }
        !           557:                        if( pglob->smscnptr != NULL ) {
        !           558: 
        !           559:                                slotassign(&tvent, pglob, &cs);
        !           560: 
        !           561:                                }
        !           562:                        else {
        !           563:                                /*
        !           564:                                 * tv ref to undefined symbol
        !           565:                                 */
        !           566:                                PUTAUX(paux, 0);
        !           567:                                return( -1 );
        !           568:                                }
        !           569:                        if ( (offset = gettvnxt()) == 0L)
        !           570:                                lderror(2,0,NULL,"Internal error: out of tv slots");
        !           571:                        fseek(tvstream, offset-ftell(tvstream), 1);
        !           572:                        paux->axent.x_sym.x_tvndx = tvnxt;
        !           573:                        PUTAUX(paux, 1);
        !           574:                        }
        !           575:                else {
        !           576:                        if( paux->axent.x_sym.x_tvndx == N_TV )
        !           577:                                ret = 0;
        !           578:                        else
        !           579:                        /*
        !           580:                         * The symbol already has a tv assigned:
        !           581:                         *
        !           582:                         *      tvndx > 0
        !           583:                         */
        !           584:                                ret = paux->axent.x_sym.x_tvndx;
        !           585:                        PUTAUX(paux, 0);
        !           586:                        return ( ret );
        !           587:                        }
        !           588:                }
        !           589:        else {
        !           590:                /*
        !           591:                 * This routine was given an input symbol table entry
        !           592:                 */
        !           593:                fread(&aux, AUXESZ, 1, infile);
        !           594:                fseek(infile, (long) -AUXESZ, 1);
        !           595:                if( aux.x_sym.x_tvndx != N_TV )
        !           596:                        return ( -1 );
        !           597:                if( ! aflag )
        !           598:                        return ( 0 );
        !           599:                if ( (offset = gettvnxt()) == 0L)
        !           600:                        lderror(2,0,NULL,"Internal error: out of tv slots");
        !           601:                fseek(tvstream, offset-ftell(tvstream), 1);
        !           602: 
        !           603:                settventry(&tvent, psym, &cs);
        !           604:                }
        !           605: 
        !           606:        fwrite(&tvent, TVENTSZ, 1, tvstream);
        !           607: 
        !           608:        return ( tvnxt++ );
        !           609: 
        !           610: #endif
        !           611: }
        !           612: /*eject*/
        !           613: long
        !           614: gettvnxt()
        !           615: {
        !           616: #if TRVEC
        !           617: 
        !           618: /*
        !           619:  * This routine is called only when it is certain that we need to write
        !           620:  * out a tv entry. tvinit() has written assigned slots and filled all
        !           621:  * empty slots with 0. The first time this routine is called tvnxt equals
        !           622:  * tvspec.tvrange[0], tvread is open for reading, the read/write
        !           623:  * pointer is at the beginning of the transfer vector.
        !           624:  *
        !           625:  * It begins reading transfer vector entries until it finds
        !           626:  * one which is unused. It then seeks TVENTSZ backwards and returns
        !           627:  * the file offset of the available slot. It increments tvnxt whenever
        !           628:  * it finds an unavailable slot. When next called, it will be in a position
        !           629:  * to proceed reading slots, being positioned correctly and knowing
        !           630:  * the value of tvnxt.
        !           631:  */
        !           632: 
        !           633:        long    inslot;
        !           634: 
        !           635:        for( ; tvnxt <= tvspec.tvrange[1]; ++tvnxt ) {
        !           636:                fread(&inslot, TVENTSZ, 1, tvread);
        !           637:                if( inslot == -1L )
        !           638:                        return( (long)(ftell(tvread)-TVENTSZ) );
        !           639:                }
        !           640: 
        !           641:        return(0);
        !           642: #endif
        !           643: }
        !           644: /*eject*/
        !           645: tvfinish()
        !           646: {
        !           647: #if TRVEC
        !           648:        long    offset;
        !           649:        SYMTAB  *psym;
        !           650: 
        !           651:        if( tvspec.tvfnfill[0] != '\0' ) {
        !           652:                if( (psym = findsym(tvspec.tvfnfill)) == NULL )
        !           653:                        lderror(1, tvspec.tvinlnno, tvspec.tvinflnm,
        !           654:                                "tv fill symbol %s does not exist", tvspec.tvfnfill);
        !           655:                else {
        !           656: 
        !           657:                        filltvassign(psym);
        !           658: 
        !           659:                        PUTSYM(psym, 0);
        !           660: 
        !           661:                        /*
        !           662:                         * update x_tvfill in .tv aux entry
        !           663:                         */
        !           664:                        if ( (psym=findsym(_TV)) == NULL)
        !           665:                                lderror(0,0,NULL,"No .tv in symbol table");
        !           666:                        else {
        !           667:                                AUXTAB  *paux;
        !           668:                                union {
        !           669:                                        TVENTRY ent;
        !           670:                                        long    l;
        !           671:                                } fill;
        !           672: 
        !           673:                                fill.ent = tvspec.tvfill;
        !           674:                                paux = getaux(psym->smauxid);
        !           675:                                paux->axent.x_tv.x_tvfill = fill.l;
        !           676:                                PUTAUX(paux, 1);
        !           677:                                PUTSYM(psym, 0);
        !           678:                                }
        !           679: 
        !           680:                        if ( tvspec.tvrange[0] == 0 ) { /* fill slot 0 */
        !           681:                                fseek(tvstream, tvspec.tvosptr->oshdr.s_scnptr, 0);
        !           682:                                fwrite(&tvspec.tvfill, TVENTSZ, 1, tvstream);
        !           683:                                }
        !           684: 
        !           685:                        for( offset = gettvnxt(); tvnxt <= tvspec.tvrange[1]; ) {
        !           686:                                fseek(tvstream, offset-ftell(tvstream), 1);
        !           687:                                fwrite(&tvspec.tvfill, TVENTSZ, 1, tvstream);
        !           688:                                ++tvnxt;
        !           689:                                offset = gettvnxt();
        !           690:                                } /* for */
        !           691:                        } /* else */
        !           692:                } /* if tvfnfill[0] */
        !           693: 
        !           694:        fclose(tvstream);
        !           695: #if AR16WR
        !           696:        free( tvbuf );
        !           697: #endif
        !           698:        fclose(tvread);
        !           699: 
        !           700: #endif
        !           701: }

unix.superglobalmegacorp.com

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