|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.