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