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

1.1     ! root        1: static char ID[] = "@(#) output.c: 1.30 12/10/83";
        !             2: #include <stdio.h>
        !             3: 
        !             4: #if PORTAR
        !             5: #include <ar.h>
        !             6: #endif
        !             7: 
        !             8: #include "system.h"
        !             9: #include "reloc.h"
        !            10: #include "linenum.h"
        !            11: #include "structs.h"
        !            12: #include "extrns.h"
        !            13: #include "ldfcn.h"
        !            14: 
        !            15: #if TRVEC
        !            16: #include "tv.h"
        !            17: #include "ldtv.h"
        !            18: #endif
        !            19: 
        !            20: #include "aouthdr.h"
        !            21: #include "slotvec.h"
        !            22: #include "sgs.h"
        !            23: #include "patch.h"
        !            24: #include "sgsmacros.h"
        !            25: #include "instr.h"
        !            26: #include "params.h"
        !            27: #include "ldmacros.h"
        !            28: 
        !            29: 
        !            30: #if AR32W && !UNIX
        !            31: #define MAXSCNBS 20
        !            32: #else
        !            33: #define MAXSCNBS 4
        !            34: #endif
        !            35: 
        !            36: /*
        !            37: #if NATIVE || UNIX
        !            38: #define MODE 0777
        !            39: #else
        !            40: #define MODE 0666
        !            41: #endif
        !            42: */
        !            43: #define        MODE    0666    /* rob - we always want no execute for 5620s */
        !            44: 
        !            45: static long    lastfile = -1L; /* symtab index of previous .file entry */
        !            46: static long    nextfile = -1L; /* symtab index of next .file entry */
        !            47: static char    undefmsg;       /* has the undefined message been printed? */
        !            48: 
        !            49: #if FLEXNAMES
        !            50: static long    string_buf_length = 0;
        !            51: static char    *last_string_ptr = NULL;
        !            52: #endif
        !            53: 
        !            54: extern unsigned svhighslt;
        !            55: extern unsigned short macflags;        /* defined in ld1.c */
        !            56: extern unsigned short swapb2();
        !            57: 
        !            58: /*eject*/
        !            59: output()
        !            60: {
        !            61: 
        !            62: /*
        !            63:  * Produce the output object file
        !            64:  */
        !            65: 
        !            66: 
        !            67:        FILE *fdes, *sdes, *rdes;
        !            68: #if FLEXNAMES
        !            69:        FILE *strdes;
        !            70:        long strtborg;
        !            71: #endif
        !            72:        int fd;
        !            73:        FILHDR outflhdr;
        !            74:        unsigned *buf;
        !            75:        ANODE *ap;
        !            76:        OUTSECT *osp;
        !            77:        INSECT *isp;
        !            78:        register SYMTAB *symp;
        !            79:        short fill;
        !            80:        long indx;
        !            81:        extern long time();
        !            82: #if AR16WR
        !            83:        char rdesbuf[BUFSIZ], fdesbuf[BUFSIZ], sdesbuf[BUFSIZ];
        !            84: #endif
        !            85: 
        !            86: /*
        !            87:  * Only generate output if there were no fatal errors,
        !            88:  * and the output file can be opened
        !            89:  *
        !            90:  * NOTE: there is no return from these two lderror calls
        !            91:  */
        !            92: 
        !            93:        if( (errlev > 1) || (errlev && (!rflag || !aflag)) )
        !            94:                lderror(2,0,NULL, "Error(s). No output written to %s",
        !            95:                        outfilnm);
        !            96: 
        !            97:        buf = (unsigned *) myalloc(BUFSIZ);
        !            98: 
        !            99:        if( cflag != 4 ) {
        !           100:                if( (fd = creat(outfilnm, MODE)) < 0 )
        !           101:                        lderror(2,0,NULL, "Can't create output file %s", outfilnm);
        !           102:                close(fd);
        !           103:                fdes = fopen(outfilnm, "w");
        !           104: #if AR16WR
        !           105:                setbuf( fdes, fdesbuf );
        !           106: #endif
        !           107:                zerofile(fdes, buf, BUFSIZ);
        !           108:                }
        !           109:        else {
        !           110:                 copy(outfilnm, "/dev/null", 10);
        !           111:                 fdes = fopen(outfilnm, "w");
        !           112:                 }
        !           113: 
        !           114: /*
        !           115:  * Prepare to generate relocation information
        !           116:  */
        !           117: 
        !           118:        if( rflag ) {
        !           119:                rdes = fopen(outfilnm, "w");
        !           120: #if AR16WR
        !           121:                setbuf( rdes, rdesbuf );
        !           122: #endif
        !           123:        } else
        !           124:                rdes = NULL;
        !           125: 
        !           126: /*
        !           127:  * Prepare to generate a symbol table
        !           128:  */
        !           129: 
        !           130:        if( ! sflag ) {
        !           131:                /*
        !           132:                 * Seek to beginning of symbol table
        !           133:                 */
        !           134:                sdes = fopen(outfilnm, "w");
        !           135: #if AR16WR
        !           136:                setbuf( sdes, sdesbuf );
        !           137: #endif
        !           138:                fseek(sdes, symtborg, 0);
        !           139: 
        !           140: #if FLEXNAMES
        !           141:                /* prepare to generate a string table */
        !           142: 
        !           143:                strdes = fopen(outfilnm, "w");
        !           144:                strtborg = symtborg + SYMESZ * tnumsyms + 4;
        !           145:                fseek(strdes,strtborg,0);
        !           146: #endif
        !           147:                }
        !           148:        else {
        !           149:                sdes = NULL;
        !           150: #if FLEXNAMES
        !           151:                strdes = NULL;
        !           152: #endif
        !           153:                }
        !           154: 
        !           155:        zero((char *) &outflhdr, FILHSZ);
        !           156:        fseek(fdes, (long) (FILHSZ + hflag), 0);
        !           157: 
        !           158: /*
        !           159:  * Output the section headers
        !           160:  *
        !           161:  * This is done in two steps:
        !           162:  *     1. All allocated sections
        !           163:  *     2. All unallocated sections (e.g., DSECTS)
        !           164:  */
        !           165: 
        !           166:        for( ap = (ANODE *) avlist.head; ap; ap = ap->adnext ) {
        !           167: 
        !           168:                if( ap->adtype == ADSECT ) {
        !           169: #if UNIX || XL
        !           170:                        if( sflag || xflag ) 
        !           171: #else
        !           172:                        if( sflag )
        !           173: #endif
        !           174:                                ap->adscnptr->oshdr.s_nlnno = 0;
        !           175:                        /*
        !           176:                         * Reduce "physical" size of .patch section (as far
        !           177:                         * as ldp is concerned) but leave "true" size
        !           178:                         * available for patch list construction in wrtplst()
        !           179:                         */
        !           180:                        if( (pflag > 0)  &&  equal(ap->adscnptr->oshdr.s_name,".patch",6) ) {
        !           181:                                indx = ap->adscnptr->oshdr.s_size;
        !           182:                                ap->adscnptr->oshdr.s_size = (long) pflag;
        !           183:                                fwrite(ap->adscnptr, SCNHSZ, 1, fdes);
        !           184:                                ap->adscnptr->oshdr.s_size = indx;
        !           185:                                }
        !           186:                        else
        !           187:                                fwrite(ap->adscnptr, SCNHSZ, 1, fdes);
        !           188:                        /* Issue a warning if a section starts on an odd byte
        !           189:                           boundary! This is NEVER adviseable, although it is
        !           190:                           possible that for certain unforseen special
        !           191:                           applications, it may be necessary, so it is put
        !           192:                           in as a warning vice a fatal error; this is
        !           193:                           applicable in varying degrees of severity for
        !           194:                           all SGSs */
        !           195:                        if(ap->adscnptr->oshdr.s_paddr & 0x01L)
        !           196:                                lderror(0,0,NULL,"Section %.8s starts on an odd byte boundary!",ap->adscnptr->oshdr.s_name);
        !           197: 
        !           198:                        }
        !           199: 
        !           200:                if( ap->adtype == ADPAD )
        !           201:                        fwrite(ap->adscnptr, SCNHSZ, 1, fdes);
        !           202: 
        !           203:                }
        !           204: 
        !           205:        for( osp = (OUTSECT *) dsectlst.head; osp; osp = osp->osdsnext ) {
        !           206:                /*
        !           207:                 * Special processing for COPY and INFO sections:
        !           208:                 *  1) remove DSECT (signifying no alloc) flag
        !           209:                 *  2) leave section size intact
        !           210:                 */
        !           211: 
        !           212:                if ( osp->oshdr.s_flags & (STYP_COPY | STYP_INFO)) {
        !           213:                        osp->oshdr.s_flags ^= STYP_DSECT;
        !           214:                        }
        !           215:                else
        !           216:                        osp->oshdr.s_size = 0L; /* DSECTS get 0 size */
        !           217:                fwrite(osp, SCNHSZ, 1, fdes);
        !           218:                }
        !           219: 
        !           220: #if ILDOPT
        !           221:        if (ildflag) {
        !           222:                SCNHDR shdr;
        !           223:                copy( shdr.s_name, ".history", 8 );
        !           224:                shdr.s_flags = STYP_DSECT;
        !           225:                shdr.s_paddr = 0l;
        !           226:                shdr.s_vaddr = 0l;
        !           227:                shdr.s_size = 0l;
        !           228:                shdr.s_scnptr = 0l;
        !           229:                shdr.s_relptr = 0l;
        !           230:                shdr.s_lnnoptr = 0l;
        !           231:                shdr.s_nreloc = 0;
        !           232:                shdr.s_nlnno = 0;
        !           233:                fwrite( &shdr, SCNHSZ, 1, fdes );
        !           234:        }
        !           235: #endif
        !           236: 
        !           237: #if TRVEC 
        !           238: /*
        !           239:  * Now do whatever is necessary to initialize tv.
        !           240:  */
        !           241: 
        !           242:        if (tvflag && aflag)
        !           243:                tvinit();
        !           244: 
        !           245: #endif
        !           246: 
        !           247: /*
        !           248:  * Close transfer file
        !           249:  */
        !           250: 
        !           251: #if !ONEPROC
        !           252:        if (ferror(trnfdes))
        !           253:                lderror(2,0,NULL,"I/O error on transfer file");
        !           254:        fclose( trnfdes );
        !           255: #if AR16WR
        !           256:        free( trnfbuf );
        !           257: #endif
        !           258: #endif
        !           259: 
        !           260: /* 
        !           261:  * Allocate buffer for slot vectors used by plocsyms 
        !           262:  */
        !           263: 
        !           264:        svinit(maxrelocsms);
        !           265: 
        !           266: /*
        !           267:  * Process each input file, in order
        !           268:  *
        !           269:  * The act of processing a file can result in the detection of fatal
        !           270:  * errors. These are indicated by setting "errlev" to 2
        !           271:  *
        !           272:  * Currently known fatal errors:
        !           273:  *     1. Undefined symbols when "-r" flag is not set
        !           274:  */
        !           275: 
        !           276: #if FLEXNAMES
        !           277:        wrtinfl(fdes, sdes, strdes, rdes, buf);
        !           278: #else
        !           279:        wrtinfl(fdes, sdes, rdes, buf);
        !           280: #endif
        !           281: 
        !           282:        if ( errlev > 1 )       /* unresolved refs in absolute load */
        !           283:                lderror(2,0,NULL, "Symbol referencing errors. No output written to %s",
        !           284:                                outfilnm);
        !           285: 
        !           286:        if ( aflag && errlev )
        !           287:                lderror(2,0,NULL, "Output file %s not executable", outfilnm);
        !           288: 
        !           289:        fflush(fdes);
        !           290: 
        !           291: #if TRVEC
        !           292: /*
        !           293:  * Complete tv processing
        !           294:  */
        !           295: 
        !           296:        if (tvflag && aflag)
        !           297:                tvfinish();
        !           298: 
        !           299: #endif
        !           300: 
        !           301: /* 
        !           302:  * Fill any necessary holes between sections, in .bss
        !           303:  */
        !           304: 
        !           305:        for( osp = (OUTSECT *) outsclst.head; osp; osp = osp->osnext ) {
        !           306: 
        !           307:                if( osp->oshdr.s_scnptr != 0L ) {
        !           308:                        long disp;
        !           309:                        long offset;
        !           310: 
        !           311: #if TRVEC
        !           312:                        /*
        !           313:                         *  Don't fill the _TV section.
        !           314:                         *  It is built by the link editor.
        !           315:                         */
        !           316:                        if( equal(osp->oshdr.s_name, _TV, 8) )
        !           317:                                continue;
        !           318: #endif
        !           319: 
        !           320:                        indx = 0;
        !           321:                        fill = (osp->osflags & FILL) ? osp->osfill : globfill;
        !           322: #if AR16WR || AR32WR
        !           323: #if SWABFMT
        !           324:                        /*
        !           325:                         * Interchange bytes of the fill constant 
        !           326:                         */
        !           327:                        fill = ((fill >> 8) & 0xff) + ((fill & 0xff) << 8);
        !           328: #endif
        !           329: #endif
        !           330:                        isp = osp->osinclhd;
        !           331:                        while( indx < osp->oshdr.s_size ) {
        !           332:                                if( isp == NULL )
        !           333:                                        disp = osp->oshdr.s_size;
        !           334:                                else
        !           335:                                        disp = isp->isdispl;
        !           336:                                if( disp > indx ) {     /* fill needed */
        !           337:                                        offset = osp->oshdr.s_scnptr + indx;
        !           338:                                        fseek(fdes, offset, 0);
        !           339:                                        for( ; indx < disp-1; indx += sizeof(short) )
        !           340:                                                fwrite(&fill, sizeof(short), 1, fdes);
        !           341:                                        if( indx < disp ) {
        !           342:                                                fwrite(&fill, sizeof(char), 1, fdes);
        !           343:                                                indx++;
        !           344:                                                }
        !           345:                                        }
        !           346:                                if( isp != NULL ) {
        !           347:                                        indx += isp->ishdr.s_size;
        !           348:                                        isp = isp->isincnxt;
        !           349:                                        }
        !           350:                                }
        !           351:                        }
        !           352:                }
        !           353: 
        !           354: /* 
        !           355:  * Write global symbols at end of symbol table 
        !           356:  */
        !           357: 
        !           358:        undefmsg = 0;
        !           359:        symp = NULL;
        !           360:        while( (symp = loopsym(symp, 1)) != NULL ) {
        !           361:                symp->sment.n_value = symp->smnewval;
        !           362:                if( (symp->smlocflg == 0)  &&  ! sflag ) {
        !           363:                        AUXTAB *auxp;
        !           364:                        char    *save_ptr;
        !           365:                        /*
        !           366:                         * set last .file entry to point to first
        !           367:                         * global symbol entry
        !           368:                         */
        !           369:                        if ( lastfile != -1L ) {
        !           370:                                setfile( sdes, noutsyms);
        !           371:                                lastfile = -1L;
        !           372:                                }
        !           373: 
        !           374:                        if( Hflag  &&  (symp->sment.n_sclass == C_EXT) )
        !           375:                                symp->sment.n_sclass = C_STAT;
        !           376: #if FLEXNAMES
        !           377:                        if (symp->sment.n_zeroes == 0L) {
        !           378:                                save_ptr = symp->sment.n_nptr;
        !           379:                                strwrite(strdes,&symp->sment, symp->smnamelength);
        !           380:                        }
        !           381: #endif
        !           382:                        if ( fwrite(symp, SYMESZ, 1, sdes) != 1 )
        !           383:                                lderror(2,0,NULL,
        !           384:                                  "Cannot complete output file %s. Write error.", outfilnm);
        !           385: #if FLEXNAMES
        !           386:                        if (symp->sment.n_zeroes == 0L)
        !           387:                                symp->sment.n_nptr = save_ptr;
        !           388: #endif
        !           389: 
        !           390:                        noutsyms++;
        !           391:                        auxp = NULL;
        !           392:                        while( (auxp = loopaux(symp, auxp, 0)) != NULL ) {
        !           393:                                if (auxp->axent.x_sym.x_tvndx == P_TV)
        !           394:                                        auxp->axent.x_sym.x_tvndx = N_TV;
        !           395: #if UNIX || XL || DMERT
        !           396:                                if ((BTYPE(symp->sment.n_type) == T_STRUCT ||
        !           397:                                    BTYPE(symp->sment.n_type) == T_UNION ||
        !           398:                                    BTYPE(symp->sment.n_type) == T_ENUM ||
        !           399:                                    symp->sment.n_sclass == C_EOS) && auxp->axent.x_sym.x_tagndx > 0)  {
        !           400: #if UNIX
        !           401:                                        if (xflag)
        !           402: #endif
        !           403: #if DMERT
        !           404:                                        if (symp->smscnptr && symp->smscnptr->isfilptr->flplib)
        !           405: #endif
        !           406: #if XL
        !           407:                                        if (xflag || (symp->smscnptr && symp->smscnptr->isfilptr->flplib))
        !           408: #endif
        !           409:                                                auxp->axent.x_sym.x_tagndx = 0;
        !           410:                                        }
        !           411: #endif
        !           412:                                fwrite(auxp, AUXESZ, 1, sdes);
        !           413:                                noutsyms++;
        !           414:                                }
        !           415:                        }
        !           416:                }
        !           417: #if FLEXNAMES
        !           418: /*
        !           419:  * Once all symbols have been written, write size of string table.
        !           420:  * Symbol table file descriptor points to beginning of string table.
        !           421:  * Final value of stroffset is size of string table.
        !           422:  */
        !           423:        if ( last_string_ptr )
        !           424:                fwrite( last_string_ptr, string_buf_length, 1, strdes );
        !           425:        if ( stroffset > 4L &&
        !           426:                fwrite(&stroffset, sizeof(stroffset), 1, sdes) != 1)
        !           427:                lderror(2,0,NULL,
        !           428:                        "fail to write size of string table for file %s",
        !           429:                        outfilnm);
        !           430: #endif
        !           431: 
        !           432: /*
        !           433:  * Output the file header
        !           434:  */
        !           435: 
        !           436:        outflhdr.f_magic = magic;
        !           437:        if( sflag ) {
        !           438:                outflhdr.f_symptr = 0L;
        !           439:                outflhdr.f_nsyms = 0L;
        !           440:                outflhdr.f_flags |= (F_LNNO | F_LSYMS);
        !           441:                }
        !           442: #if UNIX || XL
        !           443:        else if ( xflag ) {
        !           444:                        outflhdr.f_symptr = symtborg;
        !           445:                        outflhdr.f_nsyms = noutsyms;
        !           446:                        outflhdr.f_flags |= (F_LNNO | F_LSYMS);
        !           447:                        }
        !           448: #endif
        !           449:        else  {
        !           450:                outflhdr.f_symptr = symtborg;
        !           451:                outflhdr.f_nsyms = noutsyms;
        !           452:                }
        !           453:        if( ! rflag )
        !           454:                outflhdr.f_flags |= F_RELFLG;
        !           455:        if ( ! errlev && aflag )
        !           456:                outflhdr.f_flags |= F_EXEC;
        !           457: #if AR16WR
        !           458:        outflhdr.f_flags |= F_AR16WR;
        !           459: #endif
        !           460: #if AR32WR
        !           461:        outflhdr.f_flags |= F_AR32WR;
        !           462: #endif
        !           463: #if AR32W
        !           464:        outflhdr.f_flags |= F_AR32W;
        !           465: #endif
        !           466: #if M32
        !           467:        /* macflags is used to remember if any input files have F_BM32B on */
        !           468:        outflhdr.f_flags |= macflags;
        !           469: #endif
        !           470:        if ( pflag )
        !           471:                outflhdr.f_flags |= F_PATCH;
        !           472:        outflhdr.f_nscns = numoutsc;
        !           473:        outflhdr.f_timdat = (long) time(0);
        !           474:        outflhdr.f_opthdr = hflag;
        !           475:        fseek(fdes, 0L, 0);             /* seek to beginning of file */
        !           476:        fwrite(&outflhdr, FILHSZ, 1, fdes);
        !           477: 
        !           478: /*
        !           479:  * If requested, supply an old a.out file header in the optional
        !           480:  * header of the output file
        !           481:  */
        !           482: 
        !           483:        if( Xflag )
        !           484:                wrtaout(fdes, &outflhdr);
        !           485: 
        !           486: /*
        !           487:  * Zero the unused portion of the optional header
        !           488:  */
        !           489: 
        !           490:        fill = hflag - (Xflag ? sizeof(AOUTHDR) : 0) - psize();
        !           491:        if( fill > 0 ) {
        !           492:                zero((char *) buf, BUFSIZ);
        !           493:                for( ; fill > 0; fill -= BUFSIZ ) 
        !           494:                        fwrite(buf, min(fill, BUFSIZ), 1, fdes);
        !           495:                }
        !           496: 
        !           497: /*
        !           498:  * If requested, construct a patch list. This list is the last thing 
        !           499:  * built in the optional header
        !           500:  */
        !           501: 
        !           502:        if( pflag )
        !           503:                wrtplst(fdes);
        !           504: 
        !           505: /*
        !           506:  * Close and clean up
        !           507:  */
        !           508: 
        !           509:        if (ferror(fdes))
        !           510:                lderror(2,0,NULL,"I/O error on output file %s", outfilnm);
        !           511:        fclose(fdes);
        !           512:        if ( ! sflag ) {
        !           513:                if (ferror(sdes))
        !           514:                        lderror(2,0,NULL,"I/O error on output file %s",
        !           515:                                outfilnm);
        !           516:                fclose(sdes);
        !           517: #if FLEXNAMES
        !           518:                if (ferror(strdes))
        !           519:                        lderror(2,0,NULL,"I/O error on output file %s",
        !           520:                                outfilnm);
        !           521:                fclose(strdes);
        !           522: #endif
        !           523:                }
        !           524:        if( rflag )  {
        !           525:                if (ferror(rdes))
        !           526:                        lderror(2,0,NULL,"I/O error on output file %s",
        !           527:                                outfilnm);
        !           528:                fclose(rdes);
        !           529:                }
        !           530: 
        !           531:        free( buf );
        !           532: /*
        !           533:  *     Release slot vector buffers or frames
        !           534:  */
        !           535: 
        !           536: #if !NOSDP
        !           537:        svfini();
        !           538: #endif
        !           539: 
        !           540:        if ( outflhdr.f_flags & F_EXEC ) {
        !           541:                int mask;
        !           542:                mask = umask(0);
        !           543:                umask(mask);
        !           544:                chmod(outfilnm, MODE & ~mask);
        !           545:                }
        !           546: }
        !           547: /*eject*/
        !           548: #if FLEXNAMES
        !           549: wrtinfl(fdes, sdes, strdes, rdes, buf)
        !           550: FILE *fdes, *sdes, *strdes, *rdes;
        !           551: #else
        !           552: wrtinfl(fdes, sdes, rdes, buf)
        !           553: FILE *fdes, *sdes, *rdes;
        !           554: #endif
        !           555: char *buf;
        !           556: {
        !           557: 
        !           558: /*
        !           559:  * This routine is called once per run to relocate the
        !           560:  * text, relocation information, and line number entries.
        !           561:  */
        !           562: 
        !           563:        SCNHDR scnbuf[MAXSCNBS];
        !           564:        LDFILE *ifd, *rfd, ifdbuf, rfdbuf;
        !           565:        short fill;
        !           566:        int lo_scnh, hi_scnh, relocfg;
        !           567:        long ndx, offset, oldoffst, paddiff;
        !           568: 
        !           569:        INFILE  *infl,          /* current input file */
        !           570:                *pnfl;          /* previous input file*/
        !           571:        register INSECT *isp;
        !           572:        OUTSECT *osp;
        !           573:        LINENO *lentry;
        !           574:        LINENO lentrybuf;
        !           575:        SLOTVEC *svp;
        !           576:        SYMTAB *gsp;
        !           577: 
        !           578: lentry = &lentrybuf;
        !           579: 
        !           580: ifd = &ifdbuf;
        !           581: rfd = &rfdbuf;
        !           582: IOPTR(ifd) = NULL;
        !           583: pnfl = NULL;
        !           584: infl = (INFILE *)infilist.head;
        !           585: 
        !           586: while ( infl != NULL ) {
        !           587: 
        !           588:        OFFSET(ifd) = OFFSET(rfd) = infl->flfiloff;
        !           589:        if ( IOPTR(ifd) == NULL ) {     /* start new input file */
        !           590: #if COMMON
        !           591:                if (strcmp(infl->flname,COMF77) == 0) {
        !           592:                        /* skip the dummy file for F77 common data */
        !           593:                        infl = infl->flnext;
        !           594:                        continue;
        !           595:                };
        !           596: #endif
        !           597:                if( (IOPTR(ifd) = fopen(infl->flname,"r")) == NULL ||
        !           598:                    (IOPTR(rfd) = fopen(infl->flname,"r")) == NULL )
        !           599:                        lderror(2,0,NULL, "Can't open %s", infl->flname);
        !           600:                if( infl->flfiloff == 0L)
        !           601:                        TYPE(ifd) = TYPE(rfd) = 0;
        !           602:                else
        !           603:                        TYPE(ifd) = TYPE(rfd) = USH_ARTYPE;
        !           604:                }
        !           605:        if( TYPE(ifd) == ARTYPE )  {
        !           606:                if (FSEEK(ifd,0L,BEGINNING) != OKFSEEK)
        !           607:                        lderror(2,0,NULL,"internal error: fail to seek to the member of %s",
        !           608:                        infl->flname);
        !           609:                }
        !           610:        if( FREAD(&(HEADER(ifd)),FILHSZ,1,ifd) != 1 )
        !           611:                lderror(2,0,NULL,"fail to read file header of %s",infl->flname);
        !           612:        HEADER(rfd) = HEADER(ifd);
        !           613:        lo_scnh = 1;
        !           614:        if ((hi_scnh = getrec2(scnbuf,ifd,1)) == 0)  {
        !           615:                lderror(2,0,NULL,"fail to read section headers of %s",
        !           616:                infl->flname);
        !           617:                }
        !           618: 
        !           619: /*
        !           620:  * Process the local symbol table. Build the slot vector entries, to
        !           621:  * permit easier relocation of symbol references
        !           622:  */
        !           623: 
        !           624: #if FLEXNAMES
        !           625:        noutsyms += plocsyms(sdes, strdes, ifd, infl);
        !           626: #else
        !           627:        noutsyms += plocsyms(sdes, ifd, infl);
        !           628: #endif
        !           629: 
        !           630: /*
        !           631:  * Process each section in this file which is to be used for link
        !           632:  * editing
        !           633:  */
        !           634: 
        !           635:        for( isp = infl->flishead; isp; isp = isp->isnext ) {
        !           636: 
        !           637:                osp = isp->isoutsec;
        !           638:                offset = osp->oshdr.s_scnptr + isp->isdispl;
        !           639: 
        !           640:                /*
        !           641:                 * Ignore zero-length input sections, and output section
        !           642:                 * which are all zeros
        !           643:                 */
        !           644:                if( (isp->ishdr.s_size == 0L) || (osp->oshdr.s_scnptr == 0L) )
        !           645:                        continue;
        !           646: 
        !           647:                /*
        !           648:                 * If the input section was not initialized, but the output
        !           649:                 * section is, "fill" the section with the appropriate value
        !           650:                 */
        !           651:                if( isp->ishdr.s_scnptr == 0L ) {
        !           652:                        if( isp->isfillfg )
        !           653:                                fill = isp->isfill;
        !           654:                        else if( osp->osflags & FILL )
        !           655:                                fill = osp->osfill;
        !           656:                        else
        !           657:                                fill = globfill;
        !           658: #if AR16WR || AR32WR
        !           659: #if SWABFMT
        !           660:                        /*
        !           661:                         * Interchange bytes of the fill constant 
        !           662:                         */
        !           663:                        fill = ((fill >> 8) & 0x00ff) + ((fill << 8) & 0xff00);
        !           664: #endif
        !           665: #endif
        !           666:                        fseek(fdes, offset, 0);
        !           667:                        for( ndx=0; ndx < isp->ishdr.s_size-1; ndx +=2 )
        !           668:                                fwrite(&fill, sizeof(short), 1, fdes);
        !           669:                        if( ndx < isp->ishdr.s_size )
        !           670:                                fwrite(&fill, sizeof(char), 1, fdes);
        !           671:                        continue;
        !           672:                        }
        !           673: 
        !           674:                /*
        !           675:                 * Process an initialized input section
        !           676:                 */
        !           677: 
        !           678:                if( isp->isecnum < lo_scnh || isp->isecnum > hi_scnh)  {
        !           679:                        lo_scnh = isp->isecnum;
        !           680:                        if ((hi_scnh = getrec2(scnbuf,ifd,lo_scnh)) == 0)
        !           681:                                lderror(2,0,NULL,"fail to read section header %d of %s",
        !           682:                                isp->isecnum,infl->flname);
        !           683:                        hi_scnh += lo_scnh;
        !           684:                        }
        !           685:                if( FSEEK(ifd,scnbuf[isp->isecnum - lo_scnh].s_scnptr,
        !           686:                    BEGINNING) != OKFSEEK)
        !           687:                        lderror(2,0,NULL, "Seek to %s section %.8s failed",
        !           688:                                infl->flname, isp->ishdr.s_name);
        !           689:                /* 
        !           690:                 * Prepare to process relocation entries, if any
        !           691:                 */
        !           692:                if( (relocfg = isp->ishdr.s_nreloc) > 0 ) {
        !           693:                        if( FSEEK(rfd,scnbuf[isp->isecnum - lo_scnh].s_relptr,
        !           694:                            BEGINNING) != OKFSEEK)  {
        !           695:                                lderror(1,0,NULL, "Seek to %s section %.8s reloc entries failed",
        !           696:                                        infl->flname, isp->ishdr.s_name);
        !           697:                                relocfg = 0;
        !           698:                                }
        !           699:                        }
        !           700:                fseek(fdes, offset, 0);
        !           701:                if( rflag  &&  relocfg ) {
        !           702:                        offset = osp->oshdr.s_relptr + isp->isrldisp;
        !           703:                        fseek(rdes, offset, 0);
        !           704:                        }
        !           705: 
        !           706:                relocate(ifd, rfd, infl, isp, osp, fdes, rdes, &paddiff, &relocfg, buf);
        !           707: 
        !           708: /*
        !           709:  * Process line numbers, if present
        !           710:  */
        !           711: 
        !           712: #if UNIX || XL
        !           713:                if( !sflag && !xflag 
        !           714: #else
        !           715:                if( !sflag 
        !           716: #endif
        !           717:                    && scnbuf[isp->isecnum - lo_scnh].s_nlnno > 0)  {
        !           718:                        long lnptr;
        !           719: 
        !           720:                        if( FSEEK(ifd,scnbuf[isp->isecnum - lo_scnh].s_lnnoptr,
        !           721:                            BEGINNING) != OKFSEEK)
        !           722:                                lderror(2,0,NULL, "Seek to %s section %.8s lnno failed",
        !           723:                                infl->flname, isp->ishdr.s_name);
        !           724:                        oldoffst = ftell(sdes);
        !           725:                        offset = osp->oshdr.s_lnnoptr + isp->islndisp;
        !           726:                        fseek(fdes, offset, 0);
        !           727:                        lnptr = offset;
        !           728:                        for( ndx = 0; ndx < isp->ishdr.s_nlnno; ndx++ ) {
        !           729:                                AUXENT ax;
        !           730:                                AUXENT *axp;
        !           731: 
        !           732:                                if (FREAD(lentry,LINESZ,1,ifd) != 1)
        !           733:                                        lderror(2,0,NULL,"fail to read lnno of section %.8s of file %s",
        !           734:                                        isp->ishdr.s_name,infl->flname);
        !           735:                                if( lentry->l_lnno == 0 ) {
        !           736:                                        if( (svp = svread(lentry->l_addr.l_symndx)) == NULL ) {
        !           737:                                                lderror(1,0,NULL, "line nbr entry (%ld %d) found for non-relocatable symbol: section %.8s, file %s",
        !           738:                                                        lentry->l_addr.l_symndx,lentry->l_lnno, isp->ishdr.s_name, infl->flname);
        !           739:                                                continue;
        !           740:                                                }
        !           741:                                        lentry->l_addr.l_symndx = svp->svnewndx;
        !           742:                                        offset = symtborg + (1+lentry->l_addr.l_symndx)*SYMESZ
        !           743:                                                + ((char *) &ax.x_sym.x_fcnary.x_fcn.x_lnnoptr - (char *) &ax);
        !           744:                                        fseek(sdes, offset, 0);
        !           745:                                        fwrite(&lnptr, sizeof(long), 1, sdes);
        !           746:                                        }
        !           747:                                else
        !           748:                                        lentry->l_addr.l_paddr += paddiff;
        !           749:                                fwrite(lentry, LINESZ, 1, fdes);
        !           750:                                lnptr += LINESZ;
        !           751:                                } /* for */
        !           752:                        fseek(sdes, oldoffst, 0);
        !           753:                        } /* if */
        !           754:                } /* for isp */
        !           755: 
        !           756:        pnfl = infl;
        !           757:        infl = infl->flnext;
        !           758: 
        !           759:        /* see if next input file is from same archive */
        !           760:        if ( (pnfl->flfiloff > 0L) && (infl != NULL) )
        !           761:                if ( strcmp(pnfl->flname, infl->flname) == 0 &&
        !           762:                     pnfl->flfiloff < infl->flfiloff             )
        !           763:                        continue;
        !           764: 
        !           765:        fclose(IOPTR(ifd));
        !           766:        fclose(IOPTR(rfd));
        !           767:        IOPTR(ifd) = NULL;
        !           768:        }
        !           769: }
        !           770: 
        !           771: long
        !           772: #if FLEXNAMES
        !           773: plocsyms(sdes, strdes, infd, infl)
        !           774: FILE *strdes;  /* current place in output string table */
        !           775: #else
        !           776: plocsyms(sdes, infd, infl)
        !           777: #endif
        !           778: FILE *sdes;    /* current place in output symbol table */
        !           779: INFILE *infl;  /* input file control block */
        !           780: LDFILE *infd;  /* input file I/O descriptor */
        !           781: {
        !           782: 
        !           783: /*
        !           784:  * This routine is called once per input file to process its local
        !           785:  * symbol table
        !           786:  *
        !           787:  * Each symbol is relocated and written to the output file
        !           788:  *
        !           789:  * In addition, a "slot vector" entry is built so that wrtinfl
        !           790:  * can easily get at relocation info for all symbols in the file.
        !           791:  *
        !           792:  * The "slot" contains the old and new symbol values, old and new symbol
        !           793:  * table index, and new section number
        !           794:  */
        !           795: 
        !           796:        register SYMTAB *gsp;
        !           797:        register SYMENT *sm;
        !           798:        register long    count;
        !           799:        register AUXTAB *auxp;
        !           800: 
        !           801:        int *newscnum, *segment;
        !           802:        long *ovaddr, *nvaddr, *opaddr, *npaddr;
        !           803:        SLOTVEC *svp;
        !           804:        int     i,
        !           805:                secnum,         /* section in which defined */
        !           806:                reloctag,       /* needs x_tagndx relocated */
        !           807:                relocend,       /* needs x_endndx relocated */
        !           808:                tvndx;          /* tv slot index or return
        !           809:                                   code from tvslot()       */
        !           810:        long sltval1, sltval2;
        !           811:        long ndx;
        !           812:        AUXENT  *ax;
        !           813: #if FLEXNAMES
        !           814:        char *strtabptr;
        !           815:        int strtabsz;
        !           816: #endif
        !           817:        SYMENT  sm_buf;
        !           818:        AUXENT  ax_buf;
        !           819:        INSECT *isp;
        !           820:        int swrite_flag, awrite_flag;
        !           821:        char tmp_numaux;
        !           822:        long            nsymstrip;
        !           823:        char            stripflag;
        !           824: #if PORTAR
        !           825:        struct ar_hdr memberhdr;
        !           826: #endif
        !           827:        char    *symname;
        !           828: 
        !           829: /*
        !           830:  * Initialize:
        !           831:  *     1. Set slot vector starting slot number to zero
        !           832:  *     2. Get the number and position of the symbols in the input file
        !           833:  *     3. Allocate space for six arrays
        !           834:  *     4. Position the input file to the symbol table
        !           835:  */
        !           836: 
        !           837:        svhighslt = 0;
        !           838: 
        !           839:        i = HEADER(infd).f_nscns + 1;
        !           840:        nsymstrip = 0L;
        !           841:        ndx = infl->flsymndx;
        !           842: 
        !           843:        newscnum = (int *) myalloc( 2*(i*sizeof(int)) + 4*(i*sizeof(long)) );
        !           844:        segment = newscnum + i;
        !           845:        ovaddr = (long *) (segment + i);
        !           846:        nvaddr = ovaddr + i;
        !           847:        opaddr = nvaddr + i;
        !           848:        npaddr = opaddr + i;
        !           849: 
        !           850: #if FLEXNAMES && PORTAR
        !           851:        /* read string table if one exists */
        !           852: 
        !           853:        if (TYPE(infd) == USH_ARTYPE){
        !           854:                if (FSEEK(infd,-(int)(sizeof(struct ar_hdr)),BEGINNING) != OKFSEEK ||
        !           855:                        FREAD(&memberhdr,sizeof(struct ar_hdr), 1, infd) != 1 ||
        !           856:                        strncmp(memberhdr.ar_fmag,ARFMAG, sizeof(memberhdr.ar_fmag)))
        !           857:                                lderror(2,0,NULL,"fail to read archive header of file %s",
        !           858:                                infl->flname);
        !           859:                if (sscanf(memberhdr.ar_size,"%ld",&ar_size) != 1)
        !           860:                        lderror(2,0,NULL,"invalid archive size for file %s", infl->flname);
        !           861:                }
        !           862:        strtabsz = 0L;
        !           863:        if (infl->flstrings)
        !           864:                strtabptr = infl->flstrings;
        !           865:        else
        !           866:                strtabptr = strtabread(infd,infl->flname, &strtabsz);
        !           867: #endif
        !           868: 
        !           869:        if( HEADER(infd).f_symptr <= 0L ||
        !           870:            FSEEK(infd,HEADER(infd).f_symptr,BEGINNING) != OKFSEEK )  {
        !           871:                free( newscnum );
        !           872:                return(0);
        !           873:                }
        !           874: 
        !           875: /*
        !           876:  * Define the contents of the six arrays
        !           877:  */
        !           878: 
        !           879:        i = 0;
        !           880:        for( isp = infl->flishead; isp; isp = isp->isnext ) {
        !           881:                OUTSECT *os;
        !           882:                newscnum[++i] = isp->isoutsec->ossecnum;
        !           883:                ovaddr[i] = isp->ishdr.s_vaddr;
        !           884:                opaddr[i] = isp->ishdr.s_paddr;
        !           885:                nvaddr[i] = isp->isnewvad;
        !           886:                npaddr[i] = isp->isnewpad;
        !           887:                os = isp->isoutsec;
        !           888:                segment[i] = (int) ((os->oshdr.s_paddr - os->oshdr.s_vaddr) >> 4);
        !           889:                }
        !           890: 
        !           891: /*
        !           892:  * Process each symbol in the symbol table
        !           893:  */
        !           894: 
        !           895:        sm = &sm_buf;
        !           896:        ax = &ax_buf;
        !           897:        for( count = 0; count < HEADER(infd).f_nsyms; count++)  {
        !           898: 
        !           899: #if TRVEC
        !           900:                tvndx = 0;
        !           901: #else
        !           902:                tvndx = -1;
        !           903: #endif
        !           904:                reloctag = 0;
        !           905:                relocend = 0;
        !           906: 
        !           907:                if (fread(sm, SYMESZ, 1, IOPTR(infd)) != 1)
        !           908:                        lderror(2,0,NULL,"fail to read symbol table of file %s",
        !           909:                        infl->flname);
        !           910: 
        !           911: #if FLEXNAMES
        !           912:                if (sm->n_zeroes == 0L)
        !           913:                {
        !           914:                        if (strtabptr == NULL)
        !           915:                                lderror( 2, 0, NULL, "no string table in file %s", infl->flname );
        !           916:                        sm->n_nptr = strtabptr + sm->n_offset;
        !           917:                }
        !           918: #endif
        !           919:                symname = PTRNAME(sm);
        !           920: 
        !           921:                switch(sm->n_sclass) {
        !           922:                case C_EXT:
        !           923:                case C_EXTDEF:
        !           924:                        gsp = findsym( symname );
        !           925:                        swrite_flag = 0;
        !           926:                        secnum = sm->n_scnum;
        !           927:                        /*
        !           928:                         * Determine what will be stored in the slot vector
        !           929:                         */
        !           930: 
        !           931:                        procext(&tvndx, secnum, &sltval1, &sltval2, ovaddr, nvaddr, gsp, sm);
        !           932: 
        !           933:                        /*
        !           934:                         * Output defined local symbols
        !           935:                         */
        !           936:                        if( gsp->smlocflg  &&  (secnum > 0) ) {
        !           937:                                svcreate(count, sltval1, sltval2, gsp->smoutndx, gsp->sment.n_scnum,
        !           938:                                        (tvndx != -1) ? SV_TV : 0);
        !           939:                                if( ! sflag ) {
        !           940:                                        char    *save_ptr;
        !           941: 
        !           942:                                        sltval1 = gsp->sment.n_value;
        !           943:                                        gsp->sment.n_value = gsp->smnewval;
        !           944:                                        if( Hflag ) {
        !           945:                                                gsp->sment.n_sclass = C_STAT;
        !           946:                                                swrite_flag = 1;
        !           947:                                                }
        !           948: #if FLEXNAMES
        !           949:                                        if (gsp->sment.n_zeroes == 0L) {
        !           950:                                                save_ptr = gsp->sment.n_nptr;
        !           951:                                                strwrite(strdes,&gsp->sment, gsp->smnamelength);
        !           952:                                        }
        !           953: #endif
        !           954:                                        fwrite(gsp, SYMESZ, 1, sdes);
        !           955: #if FLEXNAMES
        !           956:                                        if (gsp->sment.n_zeroes == 0L)
        !           957:                                                gsp->sment.n_nptr = save_ptr;
        !           958: #endif
        !           959: 
        !           960:                                        gsp->sment.n_value = sltval1;
        !           961:                                        if( gsp->sment.n_numaux > 0 ) {
        !           962:                                                auxp = getaux(gsp->smauxid);
        !           963:                                                awrite_flag = 0;
        !           964:                                                if( auxp->axent.x_sym.x_tagndx > 0 ) {
        !           965: #if UNIX || DMERT || XL
        !           966: #if UNIX
        !           967:                                                        if (xflag)
        !           968: #endif
        !           969: #if DMERT
        !           970:                                                        if (infl->flplib)
        !           971: #endif
        !           972: #if XL
        !           973:                                                        if (infl->flplib || xflag)
        !           974: #endif
        !           975:                                                                auxp->axent.x_sym.x_tagndx = 0;
        !           976:                                                        else
        !           977: #endif
        !           978:                                                                auxp->axent.x_sym.x_tagndx += infl->flsymndx - nsymstrip;
        !           979:                                                        awrite_flag = 1;
        !           980:                                                        }
        !           981:                                                if( auxp->axent.x_sym.x_fcnary.x_fcn.x_endndx > 0 ) {
        !           982: #if UNIX || XL
        !           983:                                                        if (xflag)
        !           984:                                                                auxp->axent.x_sym.x_fcnary.x_fcn.x_endndx = ndx + 2;
        !           985:                                                        else
        !           986: #endif
        !           987:                                                                auxp->axent.x_sym.x_fcnary.x_fcn.x_endndx += infl->flsymndx - nsymstrip;
        !           988:                                                        awrite_flag = 1;
        !           989:                                                        }
        !           990:                                                if( auxp->axent.x_sym.x_tvndx == P_TV)
        !           991:                                                        auxp->axent.x_sym.x_tvndx = N_TV;
        !           992: #if DMERT || XL
        !           993:                                                if (infl->flplib) {
        !           994:                                                        auxp->axent.x_sym.x_fcnary.x_fcn.x_lnnoptr = 0L;
        !           995:                                                        awrite_flag = 1;
        !           996:                                                        }
        !           997: #endif
        !           998: 
        !           999:                                                fwrite(auxp, AUXESZ, 1, sdes);
        !          1000:                                                PUTAUX(auxp, awrite_flag);
        !          1001:                                                }
        !          1002:                                        }
        !          1003:                                if( sm->n_numaux > 0 )  {
        !          1004:                                        if (fseek(IOPTR(infd), (long) (sm->n_numaux * AUXESZ), 1) != OKFSEEK)
        !          1005:                                                lderror(2,0,NULL,"fail to skip the aux entry of %s",
        !          1006:                                                infl->flname);
        !          1007:                                        }
        !          1008:                                ndx += 1 + sm->n_numaux;
        !          1009:                                count += sm->n_numaux;
        !          1010:                                }
        !          1011:                        else {
        !          1012:                                /*
        !          1013:                                 * Symbol is not defined (in this run)
        !          1014:                                 */
        !          1015:                                if ( (gsp->sment.n_scnum == 0) && aflag &&
        !          1016:                                        (tvndx == -1)) {
        !          1017:                                        /*
        !          1018:                                         * Undefined symbol in an absolute run
        !          1019:                                         * (ignore undefined tv symbols)
        !          1020:                                         */
        !          1021:                                        svcreate(count, sltval1, sltval2, gsp->smoutndx,
        !          1022:                                                gsp->sment.n_scnum, SV_ERR);
        !          1023:                                        if( ! undefmsg ) {
        !          1024:                                                fprintf( stderr, "undefined\t\tfirst referenced\n" );
        !          1025:                                                fprintf( stderr, " symbol  \t\t    in file\n" );
        !          1026:                                                undefmsg = 1;
        !          1027:                                                errlev = (rflag) ? 1 : 2;
        !          1028:                                                }
        !          1029:                                        if( ! gsp->smundmsg ) {
        !          1030:                                                fprintf( stderr, "%-20.20s\t\t%s",
        !          1031:                                                        symname, infl->flname);
        !          1032:                                                fprintf( stderr, "\n" );
        !          1033:                                                gsp->smundmsg = 1;
        !          1034:                                                swrite_flag = 1;
        !          1035:                                                }
        !          1036:                                        }
        !          1037:                                else
        !          1038:                                        /*
        !          1039:                                         * Undefine symbol, but run not absoute
        !          1040:                                         * (or it has a tv slot)
        !          1041:                                         */
        !          1042:                                        svcreate(count, sltval1, sltval2, gsp->smoutndx,
        !          1043:                                                gsp->sment.n_scnum,
        !          1044:                                                (tvndx != -1) ? SV_TV : 0);
        !          1045:                                if( sm->n_numaux > 0 ) {
        !          1046:                                        if (fseek(IOPTR(infd), (long) (sm->n_numaux * SYMESZ), 1) != OKFSEEK)
        !          1047:                                                lderror(2,0,NULL,"fail to skip the aux entries of %s",
        !          1048:                                                infl->flname);
        !          1049:                                        count += sm->n_numaux;
        !          1050:                                        if (!sflag && (sectnum > 0 || (secnum == 0 && sm->n_value > 0 ))) {
        !          1051:                                                /*
        !          1052:                                                 * If symbol is defined here but not
        !          1053:                                                 * written here, relocate the tag index
        !          1054:                                                 * in the aux entry
        !          1055:                                                 */
        !          1056:                                                auxp = getaux(gsp->smauxid);
        !          1057:                                                if( auxp->axent.x_sym.x_tagndx > 0 ) {
        !          1058: #if UNIX || XL || DMERT
        !          1059: #if UNIX
        !          1060:                                                        if (xflag)
        !          1061: #endif
        !          1062: #if DMERT
        !          1063:                                                        if (infl->flplib)
        !          1064: #endif
        !          1065: #if XL
        !          1066:                                                        if (infl->flplib || xflag)
        !          1067: #endif
        !          1068:                                                                auxp->axent.x_sym.x_tagndx = 0;
        !          1069:                                                        else
        !          1070: #endif
        !          1071:                                                                auxp->axent.x_sym.x_tagndx += infl->flsymndx;
        !          1072:                                                        PUTAUX(auxp, 1);
        !          1073:                                                        }
        !          1074:                                                else
        !          1075:                                                        PUTAUX(auxp, 0);
        !          1076:                                                }
        !          1077:                                        }
        !          1078:                                }
        !          1079:                        PUTSYM(gsp, swrite_flag);
        !          1080:                        break;
        !          1081:                case C_STAT:
        !          1082:                case C_HIDDEN:
        !          1083:                        /*
        !          1084:                         * Absolute statics are generated by the assembler
        !          1085:                         */
        !          1086:                        if( sm->n_scnum <= 0 )
        !          1087:                                goto wrtsym;
        !          1088:                        sm->n_value += (npaddr[sm->n_scnum] - opaddr[sm->n_scnum]);
        !          1089: 
        !          1090:                        proclocstat(sm, infd, segment, newscnum, &tvndx, ovaddr, nvaddr, opaddr, npaddr, ndx, &sltval1, &sltval2, count);
        !          1091: 
        !          1092:                        if( ISFCN(sm->n_type) )
        !          1093:                                relocend = 1;
        !          1094: 
        !          1095:                case C_FIELD:
        !          1096:                case C_REGPARM:
        !          1097:                        /*
        !          1098:                         * .text, .data, and .bss are C_STATs with
        !          1099:                         * x_tagndx > 0. They also have secnum > 0,
        !          1100:                         * but they must not have x_tagndx relocated
        !          1101:                         * but static structs, unions and enums should
        !          1102:                         * so differentiate on BTYPE(fundamental type)
        !          1103:                         */
        !          1104: 
        !          1105:                        if ( (BTYPE(sm->n_type)==T_ENUM) || (BTYPE(sm->n_type)==T_UNION) ||
        !          1106:                                        (BTYPE(sm->n_type)==T_STRUCT) )
        !          1107:                                reloctag = 1;
        !          1108: 
        !          1109:                        goto wrtsym;
        !          1110:                case C_BLOCK:
        !          1111:                        relocend = 1;
        !          1112:                case C_LABEL:
        !          1113:                case C_FCN:
        !          1114:                        sm->n_value += (npaddr[sm->n_scnum] - opaddr[sm->n_scnum]);
        !          1115:            wrtsym:
        !          1116: #if UNIX
        !          1117:                        if (sm->n_sclass != C_STAT && sm->n_sclass != C_FILE && xflag)  {
        !          1118: #endif
        !          1119: #if XL
        !          1120:                        if (sm->n_sclass != C_STAT && sm->n_sclass != C_FILE && xflag || infl->flplib) {
        !          1121: #endif
        !          1122: #if DMERT
        !          1123:                        if (infl->flplib) {
        !          1124: #endif
        !          1125: #if UNIX || DMERT || XL
        !          1126:                                stripflag = 1;
        !          1127:                                if (!sflag)  {
        !          1128:                                                nsymstrip++;
        !          1129:                                                }
        !          1130:                                }
        !          1131:                        else 
        !          1132: #endif
        !          1133:                                stripflag = 0;
        !          1134: 
        !          1135:                        if( !sflag && !stripflag ) {
        !          1136:                                if( sm->n_scnum > 0 )
        !          1137:                                        sm->n_scnum = newscnum[sm->n_scnum];
        !          1138: #if FLEXNAMES
        !          1139:                                if (sm->n_zeroes == 0L)
        !          1140:                                        strwrite(strdes,sm, strlen( sm->n_nptr ) + 1);
        !          1141: #endif
        !          1142:                                fwrite(sm, SYMESZ, 1, sdes);
        !          1143:                                ndx++;
        !          1144:                                }
        !          1145:                        tmp_numaux = sm->n_numaux;
        !          1146:                        for( i = 0; i < tmp_numaux; i++ ) {
        !          1147:                                if (FREAD(ax,AUXESZ,1,infd) != 1)
        !          1148:                                        lderror(2,0,NULL,"fail to read aux entries of file %s",
        !          1149:                                        infl->flname);
        !          1150: #if UNIX || DMERT || XL
        !          1151:                                if (!sflag && stripflag)  {
        !          1152:                                        nsymstrip++;
        !          1153:                                        }
        !          1154: #endif
        !          1155: 
        !          1156:                                if( !sflag && !stripflag)  {
        !          1157:                                        if( reloctag && ax->x_sym.x_tagndx > 0 )
        !          1158: #if UNIX || XL || DMERT
        !          1159: #if UNIX
        !          1160:                                                if (xflag)
        !          1161: #endif
        !          1162: #if DMERT
        !          1163:                                                if (infl->flplib)
        !          1164: #endif
        !          1165: #if XL
        !          1166:                                                if (xflag || infl->flplib)
        !          1167: #endif
        !          1168:                                                        ax->x_sym.x_tagndx = 0;
        !          1169:                                                else
        !          1170: #endif
        !          1171:                                                        ax->x_sym.x_tagndx +=infl->flsymndx - nsymstrip;
        !          1172:                                        if( relocend && ax->x_sym.x_fcnary.x_fcn.x_endndx > 0 )
        !          1173: #if UNIX || XL
        !          1174:                                                if (xflag)
        !          1175:                                                        ax->x_sym.x_fcnary.x_fcn.x_endndx += ndx + 1;
        !          1176:                                                else
        !          1177: #endif
        !          1178:                                                        ax->x_sym.x_fcnary.x_fcn.x_endndx += infl->flsymndx - nsymstrip;
        !          1179: #if TRVEC
        !          1180:                                        if( (tvndx != -1)  &&  aflag )
        !          1181:                                                ax->x_sym.x_tvndx = tvndx;
        !          1182:                                        if (ax->x_sym.x_tvndx == P_TV)
        !          1183:                                                ax->x_sym.x_tvndx = N_TV;
        !          1184: #endif
        !          1185:                                        fwrite(ax, AUXESZ, 1, sdes);
        !          1186:                                        ndx++;
        !          1187:                                        }
        !          1188:                                count++;
        !          1189:                                }
        !          1190:                        break;
        !          1191:                case C_STRTAG:
        !          1192:                case C_UNTAG:
        !          1193:                case C_ENTAG:
        !          1194:                        /*
        !          1195:                         * Relocate x_tagndx and x_endndx
        !          1196:                         */
        !          1197:                        relocend = 1;
        !          1198:                case C_ARG:
        !          1199:                case C_AUTO:
        !          1200:                case C_EOS:
        !          1201:                case C_MOS:
        !          1202:                case C_MOU:
        !          1203:                case C_REG:
        !          1204:                case C_TPDEF:
        !          1205:                        /*
        !          1206:                         * Relocate only x_tagndx
        !          1207:                         */
        !          1208:                        reloctag = 1;
        !          1209:                        goto wrtsym;
        !          1210:                case C_FILE:
        !          1211:                        /*
        !          1212:                         * Don't relocate since it is not a symbol name
        !          1213:                         *
        !          1214:                         * Update previous .file entry (if any) and
        !          1215:                         * set new value for later update
        !          1216:                         * This should chain .file entries together,
        !          1217:                         * for field update, but it is assumed that
        !          1218:                         * each input *.o file contains a .file entry
        !          1219:                         * as the first entry in its symbol table
        !          1220:                         */
        !          1221: #if DMERT || XL
        !          1222:                        if (!sflag && !infl->flplib && (lastfile != -1L) && (nextfile != ndx))
        !          1223: #else
        !          1224:                        if (!sflag && (lastfile != -1L) && (nextfile != ndx))
        !          1225: #endif
        !          1226:                                setfile( sdes, ndx );
        !          1227:                        if (infl->flnext)
        !          1228:                        {
        !          1229:                                nextfile = infl->flnext->flsymndx;
        !          1230:                                sm->n_value = nextfile;
        !          1231:                        }
        !          1232:                        lastfile = ndx;
        !          1233: 
        !          1234: 
        !          1235:                default:
        !          1236:                        /*
        !          1237:                         * no relocation 
        !          1238:                         */
        !          1239:                        goto wrtsym;
        !          1240:                }
        !          1241:                }
        !          1242: 
        !          1243:        i = HEADER(infd).f_nscns + 1;
        !          1244:        free( newscnum );
        !          1245: 
        !          1246: #if FLEXNAMES
        !          1247:        if (last_string_ptr)
        !          1248:        {
        !          1249:                fwrite( last_string_ptr, string_buf_length, 1, strdes );
        !          1250:                last_string_ptr = NULL;
        !          1251:                string_buf_length = 0;
        !          1252:        }
        !          1253:        if (strtabptr && (strtabsz > MAXKEEPSIZE))
        !          1254:                free( strtabptr );
        !          1255: #endif
        !          1256:        
        !          1257:        return(ndx - infl->flsymndx);
        !          1258: }
        !          1259: 
        !          1260: 
        !          1261: 
        !          1262: 
        !          1263: wrtaout(fdes, fhdr)
        !          1264: FILE *fdes;            /* file descriptor seeked to start of optional hdr */
        !          1265: FILHDR *fhdr;
        !          1266: {
        !          1267: 
        !          1268: /*
        !          1269:  * Write UNIX aout header into optional header block, if -X flag set.
        !          1270:  * This function assumes that the sections .text, .data, and .bss
        !          1271:  * exist by name.
        !          1272:  */
        !          1273: 
        !          1274:        AOUTHDR aout;
        !          1275:        OUTSECT *osptr;
        !          1276:        SYMTAB *symp;
        !          1277:        char found;
        !          1278: 
        !          1279: #if M32
        !          1280:        aout.magic = ( Nflag ? AOUT1MAGIC : AOUT2MAGIC );
        !          1281: #else
        !          1282:        aout.magic = ( Nflag ? AOUT2MAGIC : AOUT1MAGIC );
        !          1283: #endif
        !          1284: #if PAGING
        !          1285:        if ( Fflag && !Nflag )
        !          1286:                aout.magic = PAGEMAGIC;
        !          1287: #endif
        !          1288:        found = 0;
        !          1289:        for( osptr = (OUTSECT *) outsclst.head; osptr; osptr=osptr->osnext ) {
        !          1290:                if( equal(osptr->oshdr.s_name, _TEXT, 8) ) {
        !          1291:                        aout.tsize = osptr->oshdr.s_size;
        !          1292:                        aout.text_start = osptr->oshdr.s_paddr;
        !          1293:                        found++;
        !          1294:                        }
        !          1295:                else if( equal(osptr->oshdr.s_name, _DATA, 8) ) {
        !          1296:                        aout.dsize = osptr->oshdr.s_size;
        !          1297:                        aout.data_start = osptr->oshdr.s_paddr;
        !          1298:                        found++;
        !          1299:                        }
        !          1300:                else if( equal(osptr->oshdr.s_name, _BSS, 8) ) {
        !          1301:                        aout.bsize = osptr->oshdr.s_size;
        !          1302:                        found++;
        !          1303:                        }
        !          1304:                }
        !          1305: 
        !          1306:        adjaout(&aout);
        !          1307: 
        !          1308:        if( found != 3 )
        !          1309:                lderror(0,0,NULL,
        !          1310:                   "Sections .text .data or .bss not found. Optional header may be useless");
        !          1311: 
        !          1312: #if OLDAOUT
        !          1313:        aout.ssize = fhdr->f_nsyms * SYMESZ;
        !          1314:        aout.nsize = 0L;
        !          1315:        aout.flags = 0;
        !          1316:        if( ! rflag )
        !          1317:                aout.flags |= RELFLG;
        !          1318:        if( aout.text_start != 0L )
        !          1319:                aout.flags |= SETTEXT;
        !          1320:        if( aout.text_start + aout.tsize != aout.data_start )
        !          1321:                aout.flags |= SETDATA;
        !          1322:        if( sflag )
        !          1323:                aout.flags |= NSYMFLG;
        !          1324: #else
        !          1325:        aout.vstamp = VSflag;
        !          1326: #endif
        !          1327: 
        !          1328: /*
        !          1329:  * The entry point is obtained from the following sources, in order:
        !          1330:  *
        !          1331:  *     1. value of the symbol given in the "-e" flag
        !          1332:  *     2. value of the symbol _CSTART
        !          1333:  *     3. value of the symbol MAIN
        !          1334:  */
        !          1335: 
        !          1336:        if ( (symp = findsym(epsymbol))  ||
        !          1337:             (symp = findsym(_CSTART)) ||
        !          1338:             (symp = findsym(_MAIN)) ) {
        !          1339:                aout.entry = symp->sment.n_value;
        !          1340:                PUTSYM(symp, 0);
        !          1341:        } else
        !          1342:                aout.entry = 0L;
        !          1343: 
        !          1344:        fwrite(&aout, sizeof(AOUTHDR), 1, fdes);
        !          1345: }
        !          1346: /*eject*/
        !          1347: wrtplst(fdes)
        !          1348: FILE *fdes;
        !          1349: {
        !          1350: /*
        !          1351:  * Output the patch list
        !          1352:  */
        !          1353: 
        !          1354:        register int index;
        !          1355:        register OUTSECT *osptr;
        !          1356:        long    count;
        !          1357:        char pname[10];
        !          1358:        PENTRY block;
        !          1359:        OUTSECT *fndoutsec();
        !          1360: 
        !          1361: /*
        !          1362:  * The file pointer fdes is assumed positioned at the start of the
        !          1363:  * patch list
        !          1364:  *
        !          1365:  * Step 1: Output the block count
        !          1366:  */
        !          1367: 
        !          1368:        count = ( (long)((psize() - sizeof(long)) / PESIZE));
        !          1369:        fwrite(&count, sizeof(long), 1, fdes);
        !          1370: 
        !          1371: /*
        !          1372:  * Step 2: Output a PENTRY structure for each patch segment
        !          1373:  */
        !          1374: 
        !          1375:        for( index = 0; index < count; index++ ) {
        !          1376:                if (index < 10)
        !          1377:                        sprintf( pname, ".patch0%d", index);
        !          1378:                else
        !          1379:                        sprintf(pname, ".patch%d", index);
        !          1380:                osptr = fndoutsec(pname);
        !          1381:                block.type01.blk_type = (char) FREE_patch;
        !          1382:                block.type01.blk_addr = osptr->oshdr.s_paddr;
        !          1383:                block.type01.blk_size = osptr->oshdr.s_size;
        !          1384:                block.type01.blk_scnum = (unsigned short) osptr->ossecnum;
        !          1385:                fwrite(&block, PESIZE, 1, fdes);
        !          1386:                }
        !          1387: }
        !          1388: 
        !          1389: 
        !          1390: setfile( symdes, cursym )
        !          1391: 
        !          1392: FILE   *symdes;
        !          1393: long   cursym;
        !          1394: {
        !          1395: 
        !          1396:        /*
        !          1397:         * Update the previous .file entry in the symbol table
        !          1398:         *
        !          1399:         *      symdes = symbol table output file
        !          1400:         *      cursym = index of symbol table entry about to be written
        !          1401:         *
        !          1402:         *      static lastfile = index of previous .file entry
        !          1403:         */
        !          1404: 
        !          1405:        long    here,           /* where we are now */
        !          1406:                there;          /* where to write update value */
        !          1407: 
        !          1408:        here = symtborg + cursym * (long)SYMESZ;
        !          1409:        there= symtborg + (lastfile * (long) SYMESZ) + (long)SYMNMLEN;
        !          1410:        fseek(symdes, there-here, 1);
        !          1411:        fwrite(&cursym, sizeof(long), 1, symdes);
        !          1412:        fseek(symdes, here-there-sizeof(long), 1);
        !          1413:        return(1);
        !          1414: }
        !          1415: 
        !          1416: #if FLEXNAMES
        !          1417: strwrite(strdes,sm, strlength)
        !          1418: FILE *strdes;  /* pointer to current position in string table */
        !          1419: SYMENT *sm;    /* ptr to symbol whose name is to be written in string table */
        !          1420: int strlength;
        !          1421: {
        !          1422:        if ((last_string_ptr + string_buf_length) == sm->n_nptr)
        !          1423:                string_buf_length += strlength;
        !          1424:        else
        !          1425:        {
        !          1426:                if (last_string_ptr && fwrite(last_string_ptr, string_buf_length, 1, strdes ) != 1)
        !          1427:                        lderror(2,0,NULL, "fail to write symbol name %s in string table for file %s",
        !          1428:                                last_string_ptr, outfilnm);
        !          1429:                last_string_ptr = sm->n_nptr;
        !          1430:                string_buf_length = strlength;
        !          1431:        }
        !          1432: 
        !          1433:        sm->n_offset = stroffset;
        !          1434:        stroffset += strlength;
        !          1435: }
        !          1436: #endif

unix.superglobalmegacorp.com

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