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