|
|
1.1 ! root 1: static char ID[] = "@(#) ld1.c: 1.21 12/10/83"; ! 2: #include "system.h" ! 3: ! 4: #include <stdio.h> ! 5: ! 6: #if TS || RT ! 7: #if PORTAR || PORT5AR ! 8: #define TABSZ 2000 ! 9: #endif ! 10: #include <ar.h> ! 11: #else ! 12: #include <archive.h> ! 13: #endif ! 14: ! 15: #include "structs.h" ! 16: #include "extrns.h" ! 17: #include "list.h" ! 18: #include "ldfcn.h" ! 19: #include "params.h" ! 20: #include "sgsmacros.h" ! 21: #include "reloc.h" ! 22: #if DMERT || XL ! 23: #include "aouthdr.h" ! 24: #include "magic.h" ! 25: #endif ! 26: #include "ldmacros.h" ! 27: ! 28: #if AR32W && !UNIX ! 29: #define MAXSCNBS 20 ! 30: #define MAXSYMBS 120 ! 31: #else ! 32: #define MAXSCNBS 4 ! 33: #if AR16WR ! 34: #define MAXSYMBS 30 ! 35: #else ! 36: #define MAXSYMBS 60 ! 37: #endif ! 38: #endif ! 39: ! 40: #if TRVEC ! 41: #define OKMAGIC(x) ((unsigned short) x == (unsigned short) magic) ! 42: #else ! 43: #include "sgs.h" ! 44: #define OKMAGIC ISMAGIC ! 45: #endif ! 46: ! 47: #if M32 ! 48: unsigned short macflags = 0; ! 49: #endif ! 50: ! 51: int lo_scnh, hi_scnh; ! 52: ! 53: /*eject*/ ! 54: psymdef() ! 55: { ! 56: ! 57: /* ! 58: * Process the symlist, to define/undefine global symbols ! 59: */ ! 60: ! 61: #if !ONEPROC ! 62: ACTITEM a; ! 63: #endif ! 64: ACTITEM *ap; ! 65: ! 66: #if DEBUG ! 67: if( dflag > 2 ) ! 68: fprintf( stderr, "\nDFNSYM data structures:" ); ! 69: #endif ! 70: ! 71: #if ONEPROC ! 72: ap = (ACTITEM *) symlist.head; ! 73: while( ap ) { ! 74: #else ! 75: ap = &a; ! 76: while( symcnt-- ) { ! 77: fread( &a, 1, sizeof(ACTITEM), trnfdes ); ! 78: ap->dfnsym.aiinflnm = (char *) ((int) ap->dfnsym.aiinflnm + (int) strbase); ! 79: ap->dfnsym.aisymbol = (char *) ((int) ap->dfnsym.aisymbol + (int) strbase); ! 80: ! 81: #endif ! 82: #if DEBUG ! 83: if( dflag > 2 ) ! 84: fprintf( stderr, "\n\t%04x AIDFNSYM (%s) %d (%s) %s %08lx", ! 85: ap->dfnsym.ainext, ap->dfnsym.aiinflnm, ! 86: ap->dfnsym.aiinlnno, ap->dfnsym.aisymbol, ! 87: (ap->dfnsym.aideflag ? "DEF" : "UNDEF"), ! 88: ap->dfnsym.aidefval ); ! 89: #endif ! 90: ! 91: if( ap->dfnsym.aideflag ) { ! 92: lderror(1, ap->dfnsym.aiinlnno, ap->dfnsym.aiinflnm, ! 93: "inimplemented feature: value definition for symbol %.8s", ! 94: ap->dfnsym.aisymbol ); ! 95: } ! 96: else ! 97: undefsm( ap->dfnsym.aisymbol ); ! 98: #if ONEPROC ! 99: ap = ap->ldlbry.ainext; ! 100: #endif ! 101: } ! 102: } ! 103: /*eject*/ ! 104: pmemreg() ! 105: { ! 106: ! 107: /* ! 108: * Input the MEMLIST and REGLIST built during PASS 1 ! 109: */ ! 110: ! 111: #if USEREGIONS ! 112: register REGION *rptr; ! 113: #endif ! 114: register MEMTYPE *mptr; ! 115: ADDRESS length; ! 116: ! 117: /* ! 118: * If no MEMORY directives are supplied, use a default, otherwise check ! 119: * for proper usage ! 120: */ ! 121: ! 122: #if ONEPROC ! 123: if (memlist.head == NULL ) { ! 124: #else ! 125: if( memcnt == 0 ) { ! 126: #endif ! 127: mptr = (MEMTYPE *) myalloc(sizeof(MEMTYPE)); ! 128: copy(mptr->mtname, "*dfltmem", 8); ! 129: #if PAGING ! 130: if (zflag) ! 131: memorg = max(memorg, NONULLORG); ! 132: #endif ! 133: mptr->mtorig = memorg; ! 134: mptr->mtlength = (MEMSIZE - memorg); ! 135: mptr->mtattr=15; /* all attrs set */ ! 136: listadd( l_MEM, &memlist, mptr ); ! 137: } ! 138: else { ! 139: #if DEBUG ! 140: if( dflag > 2 ) ! 141: fprintf( stderr, "\nMEMTYPE data structures:" ); ! 142: #endif ! 143: #if !ONEPROC ! 144: while( memcnt-- ) { ! 145: mptr = (MEMTYPE *) myalloc(sizeof(MEMTYPE)); ! 146: fread( mptr, 1, sizeof(MEMTYPE), trnfdes ); ! 147: mptr->mtnext = NULL; ! 148: #if DEBUG ! 149: if( dflag > 2 ) ! 150: fprintf( stderr, "\n\t%04x (%8.8s) %08lx %08lx %d %04x %04x", ! 151: mptr->mtnext, mptr->mtname, mptr->mtorig, mptr->mtlength, mptr->mtattr, ! 152: mptr->mtaddrhd, mptr->mtaddrtl ); ! 153: #endif ! 154: listadd( l_MEM, &memlist, mptr ); ! 155: } ! 156: #endif ! 157: mptr = (MEMTYPE *) memlist.head; ! 158: while ( mptr->mtnext ) { ! 159: length = mptr->mtorig + mptr->mtlength; ! 160: if( length > mptr->mtnext->mtorig ) { ! 161: lderror(1,0,NULL, "memory types %.8s and %.8s overlap", ! 162: mptr->mtname, mptr->mtnext->mtname); ! 163: free( mptr->mtnext ); ! 164: mptr->mtnext = mptr->mtnext->mtnext; ! 165: } ! 166: mptr = mptr->mtnext; ! 167: } ! 168: } ! 169: ! 170: #if USEREGIONS ! 171: /* ! 172: * If no REGIONS directives are supplied, use a default, otherwise check ! 173: * for proper usage ! 174: */ ! 175: ! 176: #if ONEPROC ! 177: if( reglist.head == NULL ) { ! 178: #else ! 179: if( regcnt == 0 ) { ! 180: #endif ! 181: if( (! iflag) && (! tvflag) ) { ! 182: /* ! 183: * No separate I and D space. No tv ! 184: */ ! 185: rptr = (REGION *) myalloc(sizeof(REGION)); ! 186: copy(rptr->rgname, "*dfltrgn", 8); ! 187: rptr->rgorig = 0L; ! 188: rptr->rglength = REGSIZE; ! 189: rptr->rgvaddr = 0L; ! 190: listadd(l_REG, ®list, rptr); ! 191: } ! 192: else if( ! tvflag ) { ! 193: /* ! 194: * Separate I and D space. No tv ! 195: */ ! 196: rptr = (REGION *) myalloc(sizeof(REGION)); ! 197: copy(rptr->rgname, "RTEXT", 8); ! 198: rptr->rgorig = 0L; ! 199: rptr->rglength = REGSIZE; ! 200: rptr->rgvaddr = 0L; ! 201: listadd(l_REG, ®list, rptr); ! 202: rptr = (REGION *) myalloc(sizeof(REGION)); ! 203: copy(rptr->rgname, "RDATA", 8); ! 204: rptr->rgorig = REGSIZE + 2; ! 205: rptr->rglength = REGSIZE - 2; ! 206: rptr->rgvaddr = 2L; ! 207: listadd(l_REG, ®list, rptr); ! 208: } ! 209: } ! 210: else { ! 211: #if DEBUG ! 212: if( dflag > 2 ) ! 213: fprintf( stderr, "\nREGION data structures:" ); ! 214: #endif ! 215: #if !ONEPROC ! 216: while( regcnt-- ) { ! 217: rptr = (REGION *) myalloc(sizeof(REGION)); ! 218: fread( rptr, 1, sizeof(REGION), trnfdes ); ! 219: rptr->rgnext = NULL; ! 220: #if DEBUG ! 221: if( dflag > 2 ) ! 222: fprintf( stderr, "\n\t%04x (%8.8s) %08lx %08lx %08lx %04x %04x", ! 223: rptr->rgnext, rptr->rgname, rptr->rgorig, ! 224: rptr->rglength, rptr->rgvaddr, ! 225: rptr->rgaddrhd, rptr->rgaddrtl ); ! 226: #endif ! 227: listadd( l_REG, ®list, rptr ); ! 228: } ! 229: #endif ! 230: rptr = (REGION *) reglist.head; ! 231: while( rptr->rgnext ) { ! 232: length = rptr->rgorig + rptr->rglength; ! 233: if( length > rptr->rgnext->rgorig ) { ! 234: lderror(2,0,NULL,"Can't allocate space for overlap regions %.8s and %.8s", ! 235: rptr->rgname, rptr->rgnext->rgname); ! 236: } ! 237: rptr = rptr->rgnext; ! 238: } ! 239: } ! 240: #endif ! 241: ! 242: } ! 243: /*eject*/ ! 244: ploadfil() ! 245: { ! 246: ! 247: /* ! 248: * Process the LDFILE list ! 249: */ ! 250: ! 251: extern LDFILE *myldopen(); ! 252: extern long sgetl(); ! 253: #if !ONEPROC ! 254: ACTITEM a; ! 255: #endif ! 256: ACTITEM *ap; ! 257: ARCHDR ahdr; ! 258: SCNHDR scnbuf[MAXSCNBS]; ! 259: SYMENT symbuf[MAXSYMBS]; ! 260: LDFILE fdesbuf; ! 261: register LDFILE *fdes; ! 262: #if AR16WR ! 263: char fbuf[BUFSIZ]; ! 264: #endif ! 265: register int done, count; ! 266: ! 267: /* ! 268: * For each separate file to go into some output section: ! 269: * 1. Make sure the file is of valid type (i.e., "good magic") ! 270: * 2. Input the file and section headers ! 271: * 3. Scan the symbol table, counting globals, etc. ! 272: */ ! 273: ! 274: #if DEBUG ! 275: if( dflag > 2 ) ! 276: fprintf( stderr, "\nLDFILE data structures:" ); ! 277: #endif ! 278: #if ONEPROC ! 279: ap = (ACTITEM *) ldfilist.head; ! 280: while ( ap ) { ! 281: #else ! 282: ap = &a; ! 283: while( ldfcnt-- ) { ! 284: fread( &a, 1, sizeof(ACTITEM), trnfdes ); ! 285: ap->ldlbry.aiinflnm = (char *) ((int) ap->ldlbry.aiinflnm + (int) strbase); ! 286: ap->ldlbry.aifilnam = (char *) ((int) ap->ldlbry.aifilnam + (int) strbase); ! 287: #endif ! 288: #if DEBUG ! 289: if( dflag > 2 ) ! 290: fprintf( stderr, "\n\t%04x AILDFILE (%s) %d (%s)", ! 291: ap->ldlbry.ainext, ap->ldlbry.aiinflnm, ! 292: ap->ldlbry.aiinlnno, ap->ldlbry.aifilnam ); ! 293: #endif ! 294: /* ! 295: * The same file can appear many times on the ldlist ! 296: * sequence, since the input sections from it can go ! 297: * into many different output sections ! 298: * ! 299: * Process a NON-ARCHIVE file exactly ONCE; but, ! 300: * process an ARCHIVE file each time it is given ! 301: */ ! 302: if( (ap->ldlbry.aitype == AILDFILE) && fndinfil(ap->ldlbry.aifilnam) ) { ! 303: #if ONEPROC ! 304: ap = ap->ldlbry.ainext; ! 305: #endif ! 306: continue; ! 307: } ! 308: ! 309: #if AR16WR ! 310: if( (fdes = myldopen(ap->ldlbry.aifilnam,&ahdr,&fdesbuf,fbuf)) == NULL ) ! 311: #else ! 312: if( (fdes = myldopen(ap->ldlbry.aifilnam,&ahdr,&fdesbuf)) == NULL ) ! 313: #endif ! 314: lderror(1, ap->ldlbry.aiinlnno, ap->ldlbry.aiinflnm, "Can't open file %s", ! 315: ap->ldlbry.aifilnam); ! 316: else if( OKMAGIC(TYPE(fdes))) { ! 317: #if DMERT || XL ! 318: if (HEADER(fdes).f_opthdr >= sizeof(AOUTHDR)) { ! 319: short o_magic; ! 320: if (FREAD(&o_magic,sizeof(o_magic),1,fdes) != 1) ! 321: lderror(2,0,NULL,"fail to read magic number of pfile %s", ! 322: ap->ldlbry.aifilnam); ! 323: if (o_magic == (short) PLIBMAGIC) ! 324: dmertplib = 1; ! 325: } ! 326: #endif ! 327: lo_scnh = 1; ! 328: if ((hi_scnh = getrec2(scnbuf,fdes,1)) == 0) ! 329: lderror(2,0,NULL,"fail to read section headers of file %s", ! 330: ap->ldlbry.aifilnam); ! 331: loadobjf(fdes,ap->ldlbry.aifilnam,-1,scnbuf,NULL); ! 332: #if DMERT || XL ! 333: dmertplib = 0; ! 334: #endif ! 335: fclose(IOPTR(fdes)); ! 336: } ! 337: else if( TYPE(fdes) == USH_ARTYPE ) { ! 338: #if PORTAR ! 339: /* Read in the archive symbol table and search it ! 340: * for unresolved symbol references. Keep passing ! 341: * over the symbol table, loading in archive members ! 342: * as you go until one complete pass is made with no ! 343: * additional loads of an archive member. ! 344: */ ! 345: ! 346: typedef union { long l; ! 347: char c[sizeof(long)/sizeof(char)]; ! 348: } longchar; ! 349: longchar arsymtab[TABSZ], sym_count; ! 350: char * arsymnmptr[TABSZ]; ! 351: char found_one; ! 352: long sym_ar_size; ! 353: int strtabsz; ! 354: char *j,*strtabptr; ! 355: int i; ! 356: struct ar_hdr arheader; ! 357: ! 358: /* read archive header */ ! 359: if (fseek(IOPTR(fdes),(long)SARMAG,0) != OKFSEEK ! 360: || FREAD(&arheader,sizeof(struct ar_hdr),1,fdes) != 1 ! 361: || strncmp(arheader.ar_fmag,ARFMAG,sizeof(arheader.ar_fmag)) ! 362: || sscanf(arheader.ar_size, "%ld", &sym_ar_size) !=1) ! 363: lderror(2,0,NULL, ! 364: "can't read archive header from archive %s", ! 365: ap->ldlbry.aifilnam); ! 366: if (arheader.ar_name[0] != '/') ! 367: lderror(2,0,NULL, ! 368: "archive symbol directory is missing from archive %s\nexecute 'ar ts %s' to restore archive symbol directory", ! 369: ap->ldlbry.aifilnam,ap->ldlbry.aifilnam); ! 370: ! 371: /* figure out number of archive symbols */ ! 372: if (FREAD(sym_count.c,sizeof(sym_count.c),1,fdes) != 1) ! 373: lderror(2,0,NULL, ! 374: "can't read archive symbol directory number of symbols from archive %s", ! 375: ap->ldlbry.aifilnam); ! 376: sym_count.l = sgetl( sym_count.c ); ! 377: /* check to make sure that you have a symbol table */ ! 378: if ( sym_count.l <= 0 ) ! 379: lderror(2,0,NULL, ! 380: "archive symbol table is empty in archive %s\nexecute 'ar ts %s' to restore archive symbol table", ! 381: ap->ldlbry.aifilnam,ap->ldlbry.aifilnam); ! 382: if ( sym_count.l > TABSZ ) ! 383: lderror(2,0,NULL, ! 384: "archive symbol directory in archive %s is too large", ! 385: ap->ldlbry.aifilnam); ! 386: ! 387: /* read in the archive symbol directory */ ! 388: ! 389: if (FREAD(arsymtab,sizeof(longchar),sym_count.l,fdes) ! 390: != sym_count.l) ! 391: lderror(2,0,NULL, ! 392: "can't read archive symbol directory of archive %s", ! 393: ap->ldlbry.aifilnam); ! 394: /* read in the symbol names string table */ ! 395: ! 396: strtabsz = sym_ar_size - (sym_count.l + 1) * ! 397: sizeof(longchar); ! 398: strtabptr = myalloc(strtabsz); ! 399: if ((FREAD(strtabptr,strtabsz,1,fdes) != 1) || ! 400: strtabptr[strtabsz - 1] != '\0') ! 401: lderror(2,0,NULL, ! 402: "can't read archive string table of archive %s", ! 403: ap->ldlbry.aifilnam); ! 404: j = strtabptr; /* ptr for walking thru string table */ ! 405: for (i=0; i<sym_count.l; i++) { ! 406: if (j > (strtabptr + strtabsz - 1)) ! 407: lderror(2,0,NULL, ! 408: "too few symbol names in string table for archive %s", ! 409: ap->ldlbry.aifilnam); ! 410: arsymtab[i].l = sgetl(arsymtab[i].c); ! 411: arsymnmptr[i] = j; ! 412: while (*++j != '\0'); ! 413: j++; ! 414: } ! 415: ! 416: /* loop thru symbol table until you can't find any more ! 417: unresolved symbols which are satisfied by this ! 418: archive */ ! 419: found_one = 1; ! 420: while (found_one) { ! 421: struct ar_hdr memberhdr; ! 422: SYMTAB *symptr; ! 423: int i; ! 424: found_one = 0; ! 425: for (i=0; i < sym_count.l; i++) { ! 426: symptr = findsym(arsymnmptr[i]); ! 427: if (symptr != NULL) /* found one ?? */ ! 428: if ( symptr->sment.n_value == 0 ! 429: && symptr->sment.n_scnum==0) { ! 430: PUTSYM(symptr,0); ! 431: /* seek to the archive location */ ! 432: OFFSET(fdes) = arsymtab[i].l ! 433: + sizeof(struct ar_hdr); ! 434: /* read this member's archive header */ ! 435: if (FSEEK(fdes,-(int)(sizeof(struct ar_hdr)),BEGINNING) ! 436: != OKFSEEK || ! 437: FREAD(&memberhdr,sizeof(struct ar_hdr),1,fdes) != 1 || ! 438: strncmp(memberhdr.ar_fmag,ARFMAG, ! 439: sizeof(memberhdr.ar_fmag))) ! 440: lderror(2,0,NULL, ! 441: "can't read archive header of archive %s", ! 442: ap->ldlbry.aifilnam); ! 443: if (sscanf(memberhdr.ar_size,"%ld",&ar_size) != 1) ! 444: lderror(2,0,NULL, ! 445: "invalid archive size for file %s", ! 446: ap->ldlbry.aifilnam); ! 447: /* read this member's header */ ! 448: if (FREAD(&(HEADER(fdes)),FILHSZ, 1, fdes) != 1) ! 449: lderror(2,0,NULL, ! 450: "can't read file header of archive %s", ! 451: ap->ldlbry.aifilnam); ! 452: if (OKMAGIC(HEADER(fdes).f_magic)) { ! 453: /* bind this member */ ! 454: loadobjf(fdes,ap->ldlbry.aifilnam,-1,NULL,NULL); ! 455: found_one = 1; ! 456: } ! 457: } ! 458: #if !NODSP ! 459: else ! 460: PUTSYM(symptr,0); ! 461: #endif ! 462: } /* end of for */ ! 463: } /* end of while */ ! 464: ! 465: /* we are done with this archive */ ! 466: fclose(IOPTR(fdes)); ! 467: #endif ! 468: #if PORT5AR ! 469: /* Read in the archive symbol table and search it ! 470: * for unresolved symbol references. Keep passing ! 471: * over the symbol table, loading in archive members ! 472: * as you go until one complete pass is made with no ! 473: * additional loads of an archive member. ! 474: */ ! 475: #if ONEPROC ! 476: struct ar_sym arsymtab[TABSZ]; ! 477: #else ! 478: struct ar_sym *arsymtab; ! 479: #endif ! 480: struct ar_hdr arheader; ! 481: long sym_count; ! 482: char found_one; ! 483: ! 484: /* read archive header */ ! 485: fseek(IOPTR(fdes),0L,0); ! 486: if (FREAD(&arheader,sizeof(struct ar_hdr),1,fdes) ! 487: != 1) ! 488: lderror(2,0,NULL, ! 489: "can't read archive header from archive %s", ! 490: ap->ldlbry.aifilnam); ! 491: ! 492: /* figure out number of archive symbols */ ! 493: sym_count = sgetl( arheader.ar_syms ); ! 494: #if !ONEPROC ! 495: arsymtab = (struct ar_sym *) myalloc(sym_count * sizeof(struct ar_sym)); ! 496: #endif ! 497: /* check to make sure that you have a symbol table */ ! 498: if (sym_count <= 0) ! 499: lderror(2,0,NULL, ! 500: "archive symbol table is empty in archive %s\nexecute 'ar ts %s' to restore archive symbol table", ! 501: ap->ldlbry.aifilnam,ap->ldlbry.aifilnam); ! 502: ! 503: /* read in the archive symbol table */ ! 504: if (FREAD(arsymtab,sizeof(struct ar_sym),sym_count,fdes) ! 505: != sym_count) ! 506: lderror(2,0,NULL, ! 507: "can't read archive symbol table of archive %s", ! 508: ap->ldlbry.aifilnam); ! 509: ! 510: found_one = 1; /* loop thru symbol table until you can't ! 511: find any more unresolved symbols which ! 512: are satisfied by this archive */ ! 513: while (found_one) { ! 514: SYMTAB *symptr; ! 515: int i; ! 516: short j; ! 517: long location; ! 518: char sym_name[sizeof(arsymtab->sym_name)+1]; ! 519: ! 520: found_one = 0; ! 521: for (i=0; i<=sym_count; i++) { ! 522: strncpy(sym_name,arsymtab[i].sym_name, ! 523: sizeof(arsymtab->sym_name)); ! 524: j = sizeof(arsymtab->sym_name); ! 525: while (sym_name[j-1] == ' ' && ! 526: j >= 1) j--; ! 527: sym_name[j] = '\0'; ! 528: symptr = findsym(sym_name); ! 529: if (symptr != NULL) /* found one ?? */ ! 530: if (symptr->sment.n_value == 0 && symptr->sment.n_scnum == 0) { ! 531: PUTSYM(symptr,0); ! 532: /* seek to the archive location */ ! 533: location = sgetl( arsymtab[i].sym_ptr ); ! 534: OFFSET(fdes) = location + ! 535: sizeof(struct arf_hdr); ! 536: /* read this member's header */ ! 537: FSEEK(fdes,0L,BEGINNING); ! 538: if (FREAD(&(HEADER(fdes)), ! 539: FILHSZ,1,fdes) != 1) ! 540: lderror(2,0,NULL, ! 541: "can't read file header of archive %s", ! 542: ap->ldlbry.aifilnam); ! 543: ! 544: if (OKMAGIC(HEADER(fdes).f_magic)) { ! 545: /* bind this member */ ! 546: loadobjf(fdes,ap->ldlbry.aifilnam,-1, ! 547: NULL,NULL); ! 548: found_one = 1; ! 549: } ! 550: } ! 551: #if !NOSDP ! 552: else ! 553: PUTSYM(symptr, 0); ! 554: #endif ! 555: }; ! 556: }; ! 557: ! 558: /* we are done with this archive */ ! 559: fclose(IOPTR(fdes)); ! 560: #endif ! 561: #if !PORTAR && !PORT5AR ! 562: /* ! 563: * Search each member of the archive library ! 564: * to see if it will resolve any unsatisfied ! 565: * references ! 566: */ ! 567: done = count = 0; ! 568: while( ! done ) { ! 569: if ( OKMAGIC(HEADER(fdes).f_magic)) { ! 570: lo_scnh = 1; ! 571: if ((hi_scnh = getrec2(scnbuf,fdes,1)) == 0) ! 572: lderror(2,0,NULL,"fail to read section headers of library %s member %d", ! 573: ap->ldlbry.aifilnam,count); ! 574: if (HEADER(fdes).f_nsyms > MAXSYMBS || ! 575: getrec3(symbuf,fdes) == FAILURE) { ! 576: if( libsrch(fdes,NULL) ) ! 577: loadobjf(fdes, ap->ldlbry.aifilnam,count,scnbuf,NULL); ! 578: } ! 579: else { ! 580: if( libsrch(fdes,symbuf) ) ! 581: loadobjf(fdes, ap->ldlbry.aifilnam,count,scnbuf,symbuf); ! 582: } ! 583: } ! 584: else { ! 585: if (FSEEK(fdes,HEADER(fdes).f_symptr+ ! 586: (HEADER(fdes).f_nsyms * SYMESZ),BEGINNING) != OKFSEEK) ! 587: lderror(2,0,NULL,"fail to seek to the end of library %s member %d", ! 588: ap->ldlbry.aifilnam,count); ! 589: } ! 590: done = myldclose(&ahdr,fdes); ! 591: count++; ! 592: } ! 593: #endif ! 594: } ! 595: else ! 596: procspecobj(fdes, ap); ! 597: #if ONEPROC ! 598: ap = ap->ldlbry.ainext; ! 599: #endif ! 600: } ! 601: } ! 602: #if !PORTAR && !PORT5AR ! 603: /*eject*/ ! 604: libsrch(fdes,symbuf) ! 605: LDFILE *fdes; ! 606: SYMENT *symbuf; ! 607: { ! 608: ! 609: /* ! 610: * Return true if current member of archive file defines an ! 611: * undefined symbol ! 612: */ ! 613: ! 614: register int i; ! 615: register SYMTAB *symp; ! 616: SYMENT *symbol; ! 617: SYMENT symbolbuf; ! 618: ! 619: if ( !OKMAGIC(HEADER(fdes).f_magic) ) ! 620: return (0); ! 621: ! 622: if (symbuf == NULL) { ! 623: if (FSEEK(fdes,HEADER(fdes).f_symptr,0) != OKFSEEK) ! 624: lderror(2,0,NULL,"fail to seek to symbol table when search libraries"); ! 625: symbol = &symbolbuf; ! 626: } ! 627: ! 628: for( i = 0; i < HEADER(fdes).f_nsyms; i++ ) { ! 629: if (symbuf == NULL) { ! 630: if (FREAD(symbol,SYMESZ,1,fdes) != 1) ! 631: lderror(2,0,NULL,"fail to read symbol table when search libraries"); ! 632: } ! 633: else { ! 634: symbol = symbuf++; ! 635: } ! 636: if( (symbol->n_sclass == C_EXT) && (symbol->n_scnum > 0) ) { ! 637: if( (symp = findsym(PTRNAME(symbol))) != NULL ) { ! 638: if( symp->sment.n_scnum == 0 ) { /*undefined*/ ! 639: PUTSYM(symp, 0); ! 640: return(1); ! 641: } ! 642: PUTSYM(symp, 0); ! 643: } ! 644: } ! 645: /* ! 646: * skip auxilliary entries for efficiency and ! 647: * to avoid misinterpreting garbage sment ! 648: */ ! 649: ! 650: if ( (int) symbol->n_numaux > 0 ) { ! 651: if (symbuf == NULL) { ! 652: if (fseek(IOPTR(fdes),(long) (SYMESZ * (int) symbol->n_numaux), 1) != OKFSEEK) ! 653: lderror(2,0,NULL,"fail to skip aux entries when search libraries"); ! 654: } ! 655: else { ! 656: symbuf++; ! 657: } ! 658: i += (int) symbol->n_numaux; ! 659: } ! 660: } ! 661: ! 662: return(0); ! 663: } ! 664: #endif ! 665: /*eject*/ ! 666: loadobjf(fdes,fnamp,filndx,scnbuf,symbuf) ! 667: LDFILE *fdes; /* file descriptor */ ! 668: char *fnamp; /* name of the file */ ! 669: int filndx; /* member number within library */ ! 670: SCNHDR *scnbuf; ! 671: SYMENT *symbuf; ! 672: { ! 673: ! 674: /* ! 675: * Given a file descriptor which has been "seeked" to the beginning ! 676: * of the file header, build the INFILE and INSECT structures ! 677: * and process the symbol table. ! 678: */ ! 679: ! 680: #if FLEXNAMES ! 681: char *strtabptr; ! 682: int strtabsz; ! 683: #endif ! 684: register int s; ! 685: register INSECT *sptr; ! 686: register INFILE *filptr; ! 687: ! 688: filptr = (INFILE *) myalloc(sizeof(INFILE)); ! 689: ! 690: curfilnm = fnamp; ! 691: filptr->flname = fnamp; ! 692: filptr->flfilndx = filndx; ! 693: filptr->flfiloff = OFFSET(fdes); ! 694: #if DMERT || XL ! 695: if (dmertplib) ! 696: filptr->flplib = 1; ! 697: else ! 698: filptr->flplib = 0; ! 699: #endif ! 700: ! 701: /* ! 702: * Build an INSECT data structure for every section in the ! 703: * input file. Check for two special cases: ! 704: * ! 705: * 1. Sections with illegal names - names that conflict ! 706: * predefined ld section names - are not processed, ! 707: * and yield an error message ! 708: * 2. Sections which are "padding sections" (see add_pad()) ! 709: * are skipped. They exist only to provide certain ! 710: * physical alignment in the file ! 711: */ ! 712: ! 713: for( s = 1; s <= HEADER(fdes).f_nscns; s++ ) { ! 714: sptr = (INSECT *) myalloc(sizeof(INSECT)); ! 715: if (scnbuf == NULL) { ! 716: if (FSEEK(fdes,(long) (FILHSZ+HEADER(fdes).f_opthdr+ ! 717: (s-1) * SCNHSZ),BEGINNING) != OKFSEEK || ! 718: FREAD(&sptr->ishdr,SCNHSZ,1,fdes) != 1) ! 719: lderror(2,0,NULL,"fail to read section headers of file %s",fnamp); ! 720: } ! 721: else { ! 722: if (s < lo_scnh || s > hi_scnh) { ! 723: lo_scnh = s; ! 724: if ((hi_scnh = getrec2(scnbuf,fdes,s)) == 0) ! 725: lderror(2,0,NULL,"fail to read section header of file %s", ! 726: fnamp); ! 727: hi_scnh = hi_scnh + lo_scnh - 1; ! 728: } ! 729: sptr->ishdr = scnbuf[s-lo_scnh]; ! 730: } ! 731: if( ! OKSCNNAME(sptr->ishdr.s_name) ) { ! 732: lderror(1,0,NULL, "file %s has a section name which is a reserved ld identifier: %.8s", ! 733: fnamp, sptr->ishdr.s_name); ! 734: continue; ! 735: } ! 736: if ( equal(sptr->ishdr.s_name, _TV, 8) ) ! 737: ++usrdeftv; ! 738: ! 739: if( sptr->ishdr.s_flags & (STYP_COPY | STYP_INFO)) ! 740: sptr->ishdr.s_flags |= STYP_DSECT; ! 741: /* COPY and INFO sections require the same treatment ! 742: as DSECT sections */ ! 743: ! 744: if( sptr->ishdr.s_flags & STYP_PAD ) { ! 745: free( sptr ); ! 746: continue; ! 747: } ! 748: sptr->isecnum = (short) s; ! 749: #if DMERT || XL ! 750: if (dmertplib) { ! 751: sptr->ishdr.s_relptr = 0; ! 752: sptr->ishdr.s_nreloc = 0; ! 753: sptr->ishdr.s_lnnoptr = 0; ! 754: sptr->ishdr.s_nlnno = 0; ! 755: } ! 756: #endif ! 757: listadd(l_IS,filptr,sptr); ! 758: } ! 759: #if FLEXNAMES ! 760: strtabsz = 0L; ! 761: strtabptr = strtabread(fdes, fnamp, &strtabsz); ! 762: if (strtabptr && (strtabsz <= MAXKEEPSIZE)) ! 763: filptr->flstrings = strtabptr; ! 764: else ! 765: filptr->flstrings = NULL; ! 766: #endif ! 767: ! 768: if (symbuf == NULL) ! 769: if (FSEEK(fdes,HEADER(fdes).f_symptr,BEGINNING) != OKFSEEK) ! 770: lderror(2,0,NULL,"fail to seek to symbol table of file %s",fnamp); ! 771: #if FLEXNAMES ! 772: filptr->flnlsyms = psymtab(IOPTR(fdes),HEADER(fdes).f_nsyms,filptr,symbuf,strtabptr); ! 773: #else ! 774: filptr->flnlsyms = psymtab(IOPTR(fdes),HEADER(fdes).f_nsyms,filptr,symbuf); ! 775: #endif ! 776: listadd(l_IF,&infilist,filptr); ! 777: ! 778: #if FLEXNAMES ! 779: if (strtabptr && (strtabsz > MAXKEEPSIZE)) ! 780: free( strtabptr ); ! 781: #endif ! 782: ! 783: /* ! 784: * Error check: warn the user about files which have no relocation ! 785: * information in them ! 786: * ! 787: * Such files are, however, permitted ! 788: */ ! 789: ! 790: if( HEADER(fdes).f_flags & F_RELFLG ) { ! 791: if( TYPE(fdes) == ARTYPE ) ! 792: lderror(0,0,NULL, "library %s, member has no relocation information", ! 793: fnamp); ! 794: else ! 795: lderror(0,0,NULL, "file %s has no relocation information", ! 796: fnamp); ! 797: } ! 798: ! 799: #if M32 ! 800: /* macflags is used to remember if any input file had F_BM32B on */ ! 801: macflags |= HEADER(fdes).f_flags & F_BM32B ; ! 802: #endif ! 803: ! 804: } ! 805: ! 806: #if FLEXNAMES ! 807: char * ! 808: strtabread(fdes,fnamp,sizeptr) ! 809: LDFILE *fdes; /* file descriptor */ ! 810: char *fnamp; /* name of the file */ ! 811: int *sizeptr; /* ptr to size of string table read */ ! 812: { ! 813: /* ! 814: * Given the file descriptor and the name of the file read the string table ! 815: * if there is one and return a pointer to it, otherwise return null. ! 816: */ ! 817: long symtabend; ! 818: char *strtabptr; ! 819: symtabend = HEADER(fdes).f_symptr + SYMESZ * HEADER(fdes).f_nsyms; ! 820: if (TYPE(fdes) == USH_ARTYPE ) { ! 821: if (ar_size > symtabend) { ! 822: if (FSEEK(fdes, symtabend, BEGINNING) != OKFSEEK || ! 823: FREAD(sizeptr,sizeof(*sizeptr),1,fdes) != 1) ! 824: lderror(2,0,NULL, ! 825: "fail to read string table of file %s", fnamp); ! 826: if (*sizeptr > 4) { ! 827: strtabptr = myalloc(*sizeptr); ! 828: if (FREAD(&strtabptr[4], *sizeptr - 4, 1, fdes) != 1) ! 829: lderror(2, 0, NULL, ! 830: "fail to read string table of file %s", ! 831: fnamp); ! 832: else ! 833: return(strtabptr); ! 834: } ! 835: else ! 836: return(NULL); ! 837: } ! 838: else ! 839: return(NULL); ! 840: } ! 841: else { ! 842: /* not a member of an archive so it must be a ! 843: * regular object file or a DMERT public library ! 844: * (both of which are processed the same way ! 845: */ ! 846: ! 847: if (FSEEK(fdes,symtabend,BEGINNING) == OKFSEEK && ! 848: FREAD(sizeptr,sizeof(*sizeptr),1,fdes) == 1) { ! 849: /* read string table */ ! 850: if (*sizeptr > 4) { ! 851: strtabptr = myalloc(*sizeptr); ! 852: if (FREAD(&strtabptr[4], *sizeptr - 4, 1, fdes) != 1) ! 853: lderror(2,0,NULL, ! 854: "fail to read string table of file %s", ! 855: fnamp); ! 856: else ! 857: return(strtabptr); ! 858: } ! 859: else ! 860: return(NULL); ! 861: } ! 862: else ! 863: return(NULL); ! 864: } ! 865: } ! 866: #endif ! 867: #if COMMON ! 868: /*eject*/ ! 869: pf77comm() ! 870: { ! 871: /* process F77 common data declarations, undefined (i.e., unitialized ! 872: * common) data is placed into the bss section. common data is indicated ! 873: * by an undefined external variable with a non zero value. the value ! 874: * indicates the size of the common data region. ! 875: */ ! 876: ! 877: register SYMTAB *symp; ! 878: long symsize; ! 879: register INSECT *sptr; ! 880: INFILE *fptr; ! 881: ! 882: /* look thru the symbol table to see if there are some symbols ! 883: * which are undefined and have non-zero values. allocate all ! 884: * such symbols to an imaginary bss segment defined in the ! 885: * COMF77 file. ! 886: */ ! 887: ! 888: /* initialize the dummy section to which common data is allocated */ ! 889: ! 890: fptr = (INFILE *)myalloc(sizeof(INFILE)); ! 891: fptr->flname = COMF77; ! 892: fptr->flfiloff = 0L; ! 893: ! 894: sptr = (INSECT *)myalloc(sizeof(INSECT)); ! 895: ! 896: listadd(l_IS,fptr,sptr); ! 897: listadd(l_IF,&infilist,fptr); ! 898: ! 899: strcpy(sptr->ishdr.s_name,".bss"); ! 900: sptr->ishdr.s_paddr = 0; ! 901: sptr->ishdr.s_vaddr = 0; ! 902: sptr->ishdr.s_size = 0; ! 903: sptr->ishdr.s_scnptr = NULL; ! 904: sptr->ishdr.s_relptr = NULL; ! 905: sptr->ishdr.s_lnnoptr = NULL; ! 906: sptr->ishdr.s_nreloc = 0; ! 907: sptr->ishdr.s_nlnno = 0; ! 908: sptr->ishdr.s_flags = 0; ! 909: ! 910: sptr->isoutsec = NULL; ! 911: sptr->isincnxt = NULL; ! 912: sptr->isdispl = 0; ! 913: sptr->isrldisp = 0; ! 914: sptr->islndisp = 0; ! 915: sptr->isnewvad = 0; ! 916: sptr->isnewpad = 0; ! 917: sptr->isecnum = 1; ! 918: sptr->isfillfg = 0; ! 919: ! 920: ! 921: symp = NULL; ! 922: while ((symp = loopsym(symp,1)) != NULL) { ! 923: if (symp->sment.n_sclass == C_EXT && ! 924: symp->sment.n_scnum == N_UNDEF && ! 925: symp->sment.n_value > 0) { /* we have a common symbol */ ! 926: ! 927: /* assign this common symbol to the dummy section */ ! 928: ! 929: symp->smscnptr = sptr; ! 930: symp->sment.n_scnum = 1; ! 931: ! 932: /* align common symbol on optimal boundary */ ! 933: ! 934: symsize = symp->sment.n_value; ! 935: if (symsize == 1) {} ! 936: else if (symsize == 2) { ! 937: sptr->ishdr.s_size += 1; ! 938: sptr->ishdr.s_size &= (~1); ! 939: } ! 940: #if XL ! 941: else if (symsize <= 4) { ! 942: sptr->ishdr.s_size += 3; ! 943: sptr->ishdr.s_size &= (~3); ! 944: } ! 945: else if (symsize <= 8) { ! 946: sptr->ishdr.s_size += 7; ! 947: sptr->ishdr.s_size &= (~7); ! 948: } ! 949: #endif ! 950: else ! 951: { ! 952: sptr->ishdr.s_size += COM_ALIGN; ! 953: sptr->ishdr.s_size &= (~COM_ALIGN); ! 954: } ! 955: ! 956: /* increase size of dummy bss section */ ! 957: ! 958: symp->sment.n_value = sptr->ishdr.s_size; ! 959: sptr->ishdr.s_size += symsize; ! 960: } ! 961: } ! 962: /* round up the section size to be a multiple of 4 bytes */ ! 963: sptr->ishdr.s_size += 03L; ! 964: sptr->ishdr.s_size &= (~03L); ! 965: } ! 966: #endif ! 967: ! 968: ! 969: ! 970: ! 971: LDFILE * ! 972: #if AR16WR ! 973: myldopen(filename,arhdr,ldptr,fbuf) ! 974: #else ! 975: myldopen(filename,arhdr,ldptr) ! 976: #endif ! 977: char *filename; ! 978: ARCHDR *arhdr; ! 979: LDFILE *ldptr; ! 980: #if AR16WR ! 981: char *fbuf; ! 982: #endif ! 983: { ! 984: ! 985: /* ! 986: * Open the file. If it is an arch file, read in the arch header ! 987: * and file header. Otherwise just read in the file header. ! 988: */ ! 989: ! 990: #if PORTAR || PORT5AR ! 991: unsigned short type; ! 992: char atype[SARMAG]; ! 993: #else ! 994: unsigned short type, ! 995: atype; ! 996: #endif ! 997: int count; ! 998: ! 999: if ((IOPTR(ldptr)=fopen(filename, "r")) == NULL) ! 1000: return(NULL); ! 1001: ! 1002: #if AR16WR ! 1003: setbuf( IOPTR(ldptr), fbuf ); ! 1004: #endif ! 1005: ! 1006: #if PORTAR || PORT5AR ! 1007: if (FREAD(atype,SARMAG,1,ldptr) != 1) ! 1008: atype[0] = '\0'; ! 1009: OFFSET(ldptr) = 0L; ! 1010: FSEEK(ldptr,0L,0); ! 1011: #endif ! 1012: ! 1013: if (FREAD(&type, sizeof(type), 1, ldptr) != 1) { ! 1014: fclose(IOPTR(ldptr)); ! 1015: return(NULL); ! 1016: } ! 1017: count = sizeof(type); ! 1018: ! 1019: #if PORT5AR || PORTAR ! 1020: if (strncmp(atype,ARMAG,SARMAG) == 0) { ! 1021: TYPE(ldptr) = USH_ARTYPE; ! 1022: OFFSET(ldptr) = 0L; ! 1023: FSEEK(ldptr,0L,0); ! 1024: #else ! 1025: if ( sizeof(ARTYPE) != sizeof(type) ) { ! 1026: if ( FREAD(&atype, sizeof(atype), 1, ldptr) != 1) ! 1027: atype = type; ! 1028: else ! 1029: count += sizeof(atype); ! 1030: } else { ! 1031: atype = type; ! 1032: } ! 1033: ! 1034: if ( (atype == USH_ARTYPE) || ! 1035: (type == USH_ARTYPE) ) { ! 1036: TYPE(ldptr) = USH_ARTYPE; ! 1037: OFFSET(ldptr) = ARCHSZ + sizeof(ARMAG); ! 1038: if (getrec1(arhdr,ldptr) == FAILURE) ! 1039: return(NULL); ! 1040: #endif ! 1041: } else { ! 1042: TYPE(ldptr) = type; ! 1043: OFFSET(ldptr) = 0L; ! 1044: HEADER(ldptr).f_magic = type; ! 1045: #if !PORTAR && !PORT5AR ! 1046: if (count > sizeof(type)) ! 1047: HEADER(ldptr).f_nscns = atype; ! 1048: #endif ! 1049: if ( FREAD( (char *) (&(HEADER(ldptr)))+count,FILHSZ-count,1,ldptr ) != 1) ! 1050: return(NULL); ! 1051: } ! 1052: ! 1053: return(ldptr); ! 1054: } ! 1055: #if !PORTAR && !PORT5AR ! 1056: /*eject*/ ! 1057: myldclose(arhdr,fdes) ! 1058: ARCHDR *arhdr; ! 1059: LDFILE *fdes; ! 1060: { ! 1061: OFFSET(fdes) += arhdr->ar_size + ARCHSZ; ! 1062: ! 1063: if (arhdr->ar_size & 01) { ! 1064: OFFSET(fdes) += 1; ! 1065: if (fseek(IOPTR(fdes),1L,1) != 0) { ! 1066: fclose(IOPTR(fdes)); ! 1067: return(SUCCESS); ! 1068: } ! 1069: } ! 1070: ! 1071: if (getrec1(arhdr,fdes) == SUCCESS) ! 1072: return(FAILURE); ! 1073: ! 1074: fclose(IOPTR(fdes)); ! 1075: return(SUCCESS); ! 1076: } ! 1077: /*eject*/ ! 1078: getrec1(arhdr,fdes) ! 1079: ARCHDR *arhdr; ! 1080: LDFILE *fdes; ! 1081: { ! 1082: ! 1083: /* ! 1084: * if the file is an arch file, read in arch header and file ! 1085: * header. Otherwise just read in file header. ! 1086: */ ! 1087: ! 1088: if (TYPE(fdes) == USH_ARTYPE) ! 1089: if (FREAD(arhdr,ARCHSZ,1,fdes) != 1) ! 1090: return(FAILURE); ! 1091: ! 1092: if (FREAD(&(HEADER(fdes)),FILHSZ,1,fdes) != 1) ! 1093: return(FAILURE); ! 1094: ! 1095: return(SUCCESS); ! 1096: } ! 1097: #endif ! 1098: /*eject*/ ! 1099: getrec2(shdrbuf,fdes,start_scnh) ! 1100: SCNHDR *shdrbuf; ! 1101: LDFILE *fdes; ! 1102: int start_scnh; ! 1103: { ! 1104: ! 1105: /* ! 1106: * read in section headers and store them in the buffer ! 1107: */ ! 1108: ! 1109: int i, lim; ! 1110: ! 1111: if (start_scnh != 1 || HEADER(fdes).f_opthdr > 0) ! 1112: if (FSEEK(fdes,(long) (FILHSZ+HEADER(fdes).f_opthdr+(SCNHSZ*(start_scnh-1))),BEGINNING) != OKFSEEK) ! 1113: return(FAILURE); ! 1114: ! 1115: lim = HEADER(fdes).f_nscns - start_scnh + 1; ! 1116: if (lim > MAXSCNBS) lim = MAXSCNBS; ! 1117: for (i = 0; i < lim; i++) { ! 1118: if (FREAD(shdrbuf++,SCNHSZ,1,fdes) != 1) ! 1119: return(FAILURE); ! 1120: } ! 1121: ! 1122: ! 1123: return(lim); ! 1124: } ! 1125: #if !PORT5AR && !PORTAR ! 1126: /*eject*/ ! 1127: getrec3(symbuf,fdes) ! 1128: SYMENT *symbuf; ! 1129: LDFILE *fdes; ! 1130: { ! 1131: ! 1132: /* ! 1133: * read in the symbol table and store it in the buffer. ! 1134: */ ! 1135: ! 1136: int i, lim; ! 1137: ! 1138: if (FSEEK(fdes,HEADER(fdes).f_symptr,BEGINNING) != OKFSEEK) ! 1139: return(FAILURE); ! 1140: ! 1141: lim = (HEADER(fdes).f_nsyms < MAXSYMBS ? HEADER(fdes).f_nsyms : MAXSYMBS); ! 1142: for (i = 0; i < lim; i++) { ! 1143: if (FREAD(symbuf++,SYMESZ,1,fdes) != 1) ! 1144: return(FAILURE); ! 1145: } ! 1146: ! 1147: return(SUCCESS); ! 1148: } ! 1149: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.