|
|
1.1 ! root 1: static char ID[] = "@(#) ld00.c: 1.17 8/18/83"; ! 2: #include "system.h" ! 3: ! 4: #include <stdio.h> ! 5: ! 6: #if TS || RT ! 7: #include <ar.h> ! 8: #else ! 9: #include <archive.h> ! 10: #endif ! 11: ! 12: #include "structs.h" ! 13: #include "extrns.h" ! 14: #include "list.h" ! 15: #include "ldfcn.h" ! 16: #include "sgs.h" ! 17: #include "sgsmacros.h" ! 18: #include "paths.h" ! 19: #include "y.tab.h" ! 20: ! 21: extern FILE *yyin; /* current lex input file */ ! 22: extern char inline[]; /* current input line up to current token */ ! 23: extern int yychar; /* current yacc lookahead token number */ ! 24: ! 25: extern int in_y_exp; /* ! 26: * See explanation in ld.yac. ! 27: * We must initialize this var. to zero ! 28: * before parsing an ifile. ! 29: */ ! 30: ! 31: #if FLEXNAMES ! 32: # define STRINCRE 2048 ! 33: #else ! 34: # define STRINCRE 1024 ! 35: #endif ! 36: #define MAXINFLS 16 ! 37: #define MAXDLEN 64 /* maximum lib search directory length*/ ! 38: ! 39: #ifndef LLIBDIR ! 40: #define LLIBDIR LIBDIR ! 41: #endif ! 42: #ifndef NDELDIRS ! 43: #define NDELDIRS 1 ! 44: #endif ! 45: ! 46: extern char *realloc(); ! 47: ! 48: static int nldirs = NDELDIRS; /* number of -L options used */ ! 49: static char *libdirs[MAXLDIRS] = { /* directories searched for libraries */ ! 50: LLIBDIR ! 51: #ifdef LLIBDIR1 ! 52: ,LLIBDIR1 ! 53: #endif ! 54: }; ! 55: ! 56: ! 57: /* ! 58: * A stack is kept of input ifile discriptors so that ! 59: * ifiles may include other ifiles. ! 60: * ! 61: * NOTE: currently, this only works if the ifile name ! 62: * is the last statement in an ifile, because YACC does ! 63: * not return from a recursive call properly. ! 64: */ ! 65: typedef struct instr INSTR; ! 66: struct instr { ! 67: FILE *infildes; /* file descriptor */ ! 68: char *infilnm; /* ptr to file name */ ! 69: int lastlnno; /* last line number read in the file */ ! 70: }; ! 71: char whichin = 0; /* index int instack */ ! 72: INSTR instack[MAXINFLS+1]; /* stack of input ifiles */ ! 73: /*eject*/ ! 74: filespec(filename) ! 75: char *filename; ! 76: { ! 77: ! 78: /* ! 79: * This routine is called when there is an input directive to load a ! 80: * file. It checks the type of file, to distinguish between an ifile ! 81: * and an object file ! 82: */ ! 83: ! 84: FILE *filedes; ! 85: #if PORTAR || PORT5AR ! 86: unsigned short firstword; ! 87: char atype[SARMAG]; ! 88: #else ! 89: unsigned short firstword, ! 90: atype; ! 91: #endif ! 92: ! 93: #if DEBUG ! 94: if (dflag > 1) ! 95: fprintf(stderr, "filespec : %s\n", filename); ! 96: #endif ! 97: ! 98: if ((filedes = fopen(filename,"r")) == NULL) { ! 99: lderror(2,0,sname(curfilnm),"Can't open file %s for input", filename); ! 100: return; ! 101: } ! 102: ! 103: in_y_exp = 0; ! 104: ! 105: if (fread( (char *) &firstword, sizeof(firstword), 1, filedes) != 1) ! 106: lderror(2,0,NULL,"Can't read 1st word of file %s",filename); ! 107: #if PORTAR || PORT5AR ! 108: fseek(filedes,0L,0); ! 109: if (fread(atype,SARMAG,1,filedes) != 1) ! 110: atype[0] = '\0'; ! 111: #else ! 112: if ( sizeof(firstword) != sizeof(ARMAG) ) ! 113: if ( fread( (char *)&atype, sizeof(atype), 1, filedes) != 1) ! 114: atype = firstword; ! 115: #endif ! 116: ! 117: if (ISMAGIC(firstword)) { ! 118: bldldfil( savefn(filename), 0 ); ! 119: fclose(filedes); ! 120: } ! 121: #if PORTAR || PORT5AR ! 122: else if (strncmp(atype,ARMAG,SARMAG) == 0) { ! 123: #else ! 124: else if ( (firstword == (unsigned short) ARMAG) || ! 125: ((sizeof(firstword) != sizeof(ARMAG)) && ! 126: (atype == (unsigned short) ARMAG)) ) { ! 127: #endif ! 128: bldldfil( savefn(filename), 1 ); ! 129: fclose(filedes); ! 130: } ! 131: else if (BADMAGIC(firstword)) { ! 132: yyerror("file %s is of unknown type: magic number = %6.2x", ! 133: filename, firstword); ! 134: fclose(filedes); ! 135: } ! 136: else { ! 137: /* ! 138: * Assume that the file is an ifile ! 139: */ ! 140: instack[whichin].infilnm = curfilnm; ! 141: instack[whichin].lastlnno = lineno; ! 142: instack[whichin].infildes = filedes; ! 143: curfilnm = savefn(filename); ! 144: lineno = 1; ! 145: if( ++whichin == MAXINFLS ) { ! 146: yyerror("ifile nesting limit exceeded with file %s", filename); ! 147: fclose(filedes); ! 148: curfilnm = instack[--whichin].infilnm; ! 149: lineno = instack[whichin].lastlnno++; ! 150: return; ! 151: } ! 152: ! 153: if (fseek(filedes, 0L, 0) != 0) ! 154: lderror(2,0,NULL,"Can't seek to the beginning of file %s", ! 155: filename); ! 156: yyin = filedes; ! 157: ! 158: #if DEBUG ! 159: if( dflag ) ! 160: fprintf(stderr, "reading cmds from file %s (%.2o)\n", ! 161: filename, filedes); ! 162: #endif ! 163: ! 164: yyparse(); ! 165: close(filedes); ! 166: ! 167: yyin = instack[--whichin].infildes; ! 168: curfilnm = instack[whichin].infilnm; ! 169: lineno = instack[whichin].lastlnno++; ! 170: yychar = -1; ! 171: ! 172: #if DEBUG ! 173: if( dflag ) ! 174: fprintf(stderr, "returning input to fildes %s (%.2o)\n", ! 175: curfilnm, yyin); ! 176: #endif ! 177: ! 178: } ! 179: } ! 180: /*eject*/ ! 181: bldldfil(fname, typflag) ! 182: char *fname; ! 183: int typflag; ! 184: { ! 185: ! 186: /* ! 187: * Build a LDFILE action item ! 188: */ ! 189: ! 190: ACTITEM *p; ! 191: ! 192: p = (ACTITEM *) myalloc(sizeof(ACTITEM)); ! 193: ! 194: p->ldlbry.aiinflnm = curfilnm; ! 195: p->ldlbry.aiinlnno = lineno; ! 196: p->ldlbry.aitype = typflag ? AILDLBRY : AILDFILE; ! 197: p->ldlbry.aifilnam = fname; ! 198: ! 199: listadd(l_AI, &ldfilist, p); ! 200: } ! 201: ! 202: ! 203: ! 204: ! 205: bldadscn(scname, fname, sp) ! 206: char *scname; ! 207: char *fname; ! 208: ACTITEM *sp; /* ptr to DFNSCN act_item */ ! 209: { ! 210: ! 211: /* ! 212: * Build a ADDSCN action item ! 213: */ ! 214: ! 215: ACTITEM *p; ! 216: ! 217: p = (ACTITEM *) myalloc(sizeof(ACTITEM)); ! 218: ! 219: p->addscn.aitype = AIADDSCN; ! 220: p->addscn.aiinflnm = curfilnm; ! 221: p->addscn.aiinlnno = lineno; ! 222: copy(p->addscn.ainame, scname, sizeof(p->addscn.ainame)); ! 223: p->addscn.aiscfile = fname; ! 224: ! 225: listadd(l_AI, &(sp->dfnscn.sectspec), p); ! 226: } ! 227: ! 228: ! 229: ! 230: ! 231: ACTITEM * ! 232: bldadfil(fname, sp) ! 233: char *fname; ! 234: ACTITEM *sp; /* ptr to DFNSCN act_item */ ! 235: { ! 236: ! 237: /* ! 238: * Build a ADFILE action item ! 239: */ ! 240: ! 241: ACTITEM *p; ! 242: ! 243: p = (ACTITEM *) myalloc(sizeof(ACTITEM)); ! 244: ! 245: p->adfile.aitype = AIADFILE; ! 246: p->adfile.aiinflnm = curfilnm; ! 247: p->adfile.aiinlnno = lineno; ! 248: p->adfile.aifilnam = fname; ! 249: ! 250: listadd(l_AI, &(sp->dfnscn.sectspec), p); ! 251: ! 252: return (p); ! 253: } ! 254: ! 255: ! 256: ! 257: ! 258: bldexp(ep, lp) ! 259: ENODE *ep; ! 260: LISTOWN *lp; ! 261: { ! 262: ! 263: /* ! 264: * Build an EVEXPR action item ! 265: */ ! 266: ! 267: ACTITEM *p; ! 268: ! 269: p = (ACTITEM *) myalloc(sizeof(ACTITEM)); ! 270: ! 271: p->evexpr.aitype = AIEVEXPR; ! 272: p->evexpr.aiinlnno = lineno; ! 273: p->evexpr.aiinflnm = curfilnm; ! 274: p->evexpr.aiexptr = ep; ! 275: ! 276: listadd(l_AI, lp, p); ! 277: } ! 278: ! 279: ! 280: ! 281: ! 282: bldsym(sym, value, op) ! 283: char *sym; ! 284: long value; ! 285: int op; ! 286: { ! 287: ! 288: /* ! 289: * Build an DFNSYM action item ! 290: */ ! 291: ! 292: ACTITEM *p; ! 293: ! 294: p = (ACTITEM *) myalloc(sizeof(ACTITEM)); ! 295: ! 296: p->dfnsym.aitype = AIDFNSYM; ! 297: p->dfnsym.aiinlnno = lineno; ! 298: p->dfnsym.aiinflnm = curfilnm; ! 299: p->dfnsym.aisymbol = savefn(sym); ! 300: p->dfnsym.aideflag = op; ! 301: p->dfnsym.aidefval = value; ! 302: ! 303: listadd(l_AI, &symlist, p); ! 304: } ! 305: /*eject*/ ! 306: pflags(flgname, ifile) ! 307: char *flgname; /* ptr to x, extracted from -x */ ! 308: int ifile; /* set TRUE iff the flag comes from an ifile */ ! 309: { ! 310: ! 311: /* ! 312: * Process flag specifications ! 313: * ! 314: * Note that flags can come from two sources: ! 315: * command line : everything is character strings ! 316: * ifile : parser has already converted tokens to binary ! 317: */ ! 318: ! 319: register int type; ! 320: ! 321: ! 322: /* ! 323: * -a : make the output file "executable": ! 324: * 1. complain about unresolved references ! 325: * 2. define several "_xxxx" symbols ! 326: * ! 327: * -cn : increment the partial execution flag. 'n' ! 328: * defaults to 1: ! 329: * 0 : normal, complete ld execution ! 330: * 1 : execute parser of PASS 1 only ! 331: * 2 : execute PASS 1 only ! 332: * 3 : execute through allocation (up ! 333: * to output()) ! 334: * 4 : complete ld execution, with ! 335: * /dev/null as the output ! 336: * file name ! 337: * ! 338: * -dn (-b for u3b): increment the internal ld debug flag. 'n' ! 339: * defaults to 1 ! 340: * ! 341: * -e name : generate a UNIX a.out header in the optional ! 342: * header field of the output file, and ! 343: * set the "entry point" entry to the ! 344: * address of the symbol "name". This ! 345: * flag forces the flag -X ! 346: * ! 347: * -f 0xaabb : use the two-byte value aabb to: ! 348: * 1. fill "holes" between sections ! 349: * 2. fill uninitialized .bss sections ! 350: * ! 351: * -h nnn : make the optional header field nnn bytes in ! 352: * size. Zero fill any unused bytes of this ! 353: * header ! 354: * ! 355: * -i : ***** b16ld and x86ld only ***** ! 356: * use two regions, to give separate I and ! 357: * D space (64 K each) ! 358: * ! 359: * -lx : search the library libx.a in directory ! 360: * libdirs[n] for any symbols which can ! 361: * satisfy outstanding unresolved references. ! 362: * ! 363: * -m : generate a memory map ! 364: * ! 365: * -o name : use "name" as the name of the output file. ! 366: * The default value is given by the ! 367: * constant A.OUT, defined in the include ! 368: * file paths.h ! 369: * ! 370: * -p[nnn] : generate a patch list. The size of the ! 371: * optional header is increased by the ! 372: * size of the patch list ! 373: * the output section size is set to nnn ! 374: * after allocation and patch list ! 375: * construction to save physical memory ! 376: * ! 377: * -r : keep relocation information in the output file ! 378: * ! 379: * -s : strip all relocation and symbol table ! 380: * information from the output file ! 381: * ! 382: * -t : ****** UNIX only ****** ! 383: * do type checking ! 384: ! 385: * -tv : ***** b16ld/x86ld/n3bld only ***** ! 386: * generate TV function linkage ! 387: * ! 388: * -x (only u3b) : do not preserve symbols in the output symbol ! 389: * table except static or external symbols ! 390: * ! 391: * -u name : add "name" to ld's symbol table, as an ! 392: * undefined symbol ! 393: * ! 394: * -z : ****** UNIX only ****** ! 395: * leave memory around zero unconfigured ro catch ! 396: * null pointers ! 397: * ! 398: * -B nn : generate "padding" output sections of nn bytes ! 399: * of zero following any output section ! 400: * which is either: ! 401: * 1. of zero length ! 402: * 2. all of uninitialzed .bss ! 403: * ! 404: * -F : ****** UNIX only ****** ! 405: * indicate in header file for paging, block ! 406: * for paging, memory configure for paging, etc. ! 407: * ! 408: * -H : change the type of all global symbol table ! 409: * entries to "static" ! 410: * ! 411: * -L<path> : provides alternate directories and orders ! 412: * search path for libraries (equivalent to ! 413: * -I flag for cpp includes). -L must precede ! 414: * -l to be effective. ! 415: * ! 416: * -M : ****** UNIX only ***** ! 417: * output message if external variables are ! 418: * multiply defined ! 419: * ! 420: * -N : squash text and data together ! 421: * ! 422: * -S : "silent" mode: only fatal errors will be ! 423: * listed - not warnings or diagnostics ! 424: * ! 425: * -V : output current ld environment definition. '-V' ! 426: * flags are cumulative: ! 427: * 1 : describe the ld version ! 428: * 2 : describe the machine and os version ! 429: * ! 430: * -VS nn : put nn as version stamp in the optional header ! 431: * ! 432: * -X : generate, in the optional header field, a ! 433: * standard UNIX a.out header ! 434: * (except for u3b, where it means ! 435: * elimate compiler generated labels) ! 436: * ! 437: * -ild : generate an "extra" output section for each ! 438: * unallocated area of configured memory ! 439: * ! 440: */ ! 441: ! 442: switch (flgname[0]) { ! 443: #if !UNIX || M32 ! 444: case 'a': ! 445: aflag++; ! 446: break; ! 447: #endif ! 448: #if !ONEPROC ! 449: case 'c': ! 450: type = 1; ! 451: if( flgname[1] ) ! 452: if( (type = stoi(&flgname[1])) == 0x8000 ) { ! 453: yyerror("-c flag does not specify a number: %s", &flgname[1]); ! 454: type = 1; ! 455: } ! 456: cflag += type; ! 457: break; ! 458: #endif ! 459: #if DEBUG ! 460: case 'd': ! 461: #if UNIX ! 462: lderror(0,0,NULL,"-d flag is not implemented"); ! 463: break; ! 464: case 'b': ! 465: #endif ! 466: type = 1; ! 467: if( flgname[1] ) ! 468: if( (type = stoi(&flgname[1])) == 0x8000 ) { ! 469: yyerror("-%c flag does not specify a number: %s", flgname[0],flgname[1]); ! 470: type = 1; ! 471: } ! 472: dflag += type; ! 473: break; ! 474: #endif ! 475: case 'e': ! 476: if( ifile ) ! 477: if (yylex() != NAME) ! 478: yyerror("-e flag does not specify a legal symbol name: %s", inline); ! 479: else ! 480: #if FLEXNAMES ! 481: strcpy(epsymbol, yylval.sptr); ! 482: #else ! 483: copy(epsymbol, yylval.sptr, 8); ! 484: #endif ! 485: else { ! 486: #if FLEXNAMES ! 487: strcpy(epsymbol, *++argptr); ! 488: #else ! 489: copy(epsymbol, *++argptr, 8); ! 490: #endif ! 491: argcnt--; ! 492: } ! 493: Xflag++; ! 494: #if DEBUG ! 495: if (dflag) ! 496: fprintf(stderr, "a.out entry point symbol: %s\n", ! 497: epsymbol); ! 498: #endif ! 499: break; ! 500: case 'f': ! 501: if( ifile ) ! 502: if (yylex() != LONGINT) ! 503: yyerror("-f flag does not specify a two-byte number: %s", inline); ! 504: else ! 505: globfill = (short) *yylval.lptr; ! 506: else { ! 507: if( (globfill = (short) stoi(*++argptr)) == (short) 0x8000 ) { ! 508: yyerror("-f flag does not specify a two-byte number: %s", *argptr); ! 509: globfill = 0; ! 510: } ! 511: argcnt--; ! 512: } ! 513: #if DEBUG ! 514: if (dflag) ! 515: fprintf(stderr, "global fill: %.2x\n", ! 516: globfill); ! 517: #endif ! 518: break; ! 519: #if !UNIX ! 520: case 'h': ! 521: if( ifile ) ! 522: if (yylex() != LONGINT) ! 523: yyerror("-h flag does not specify a numeric value: %s", inline); ! 524: else ! 525: hflag = *yylval.lptr; ! 526: else { ! 527: if( (hflag = stoi(*++argptr)) == 0x8000 ) { ! 528: yyerror("-h flag does not specify a numeric value: %s", *argptr); ! 529: hflag = 0; ! 530: } ! 531: argcnt--; ! 532: } ! 533: if( hflag < 0 ) { ! 534: yyerror("invalid value on -h flag: %.2x", hflag); ! 535: hflag = 0; ! 536: } ! 537: #if DEBUG ! 538: if(dflag) ! 539: fprintf(stderr, "optional header size: %d\n", ! 540: hflag); ! 541: #endif ! 542: break; ! 543: #endif ! 544: case 'i': ! 545: #if IANDD ! 546: if (flgname [1] == '\0') ! 547: { ! 548: iflag++; ! 549: break; ! 550: } ! 551: #endif ! 552: #if ILDOPT ! 553: if (flgname [1] == 'l' && flgname [2] == 'd') ! 554: { ! 555: ildflag++; ! 556: break; ! 557: } ! 558: ! 559: yyerror("%s is an invalid flag",flgname); ! 560: #endif ! 561: break; ! 562: case 'l': ! 563: if( flgname[1] != '\0' ) { ! 564: library(flgname); ! 565: } ! 566: else { ! 567: specflags(flgname, argptr); ! 568: } ! 569: break; ! 570: case 'm': ! 571: mflag++; ! 572: break; ! 573: #if !UNIX ! 574: case 'p': ! 575: pflag = -1; /* use default patch size */ ! 576: if( flgname[1] ) { ! 577: if( (pflag = stoi(&flgname[1])) == 0x8000 ) { ! 578: yyerror("-p flag does not specify a number: %s", &flgname[1]); ! 579: pflag = -1; ! 580: } else { ! 581: if (pflag <= 0) { ! 582: yyerror("-p flag size out of range: %s", &flgname[1]); ! 583: pflag = -1; ! 584: } ! 585: } /* else */ ! 586: } /* if flgname */ ! 587: break; ! 588: #endif ! 589: case 'o': ! 590: if( ifile ) { ! 591: type = yylex(); ! 592: if( (type == FILENAME) || (type == NAME) ) ! 593: copy(outfilnm, yylval.sptr, 128); ! 594: else ! 595: yyerror("-o flag does not specify a valid file name: %s", inline); ! 596: } ! 597: else { ! 598: copy(outfilnm, *++argptr, 128); ! 599: argcnt--; ! 600: } ! 601: if( outfilnm[127] != '\0' ) { ! 602: outfilnm[127] = '\0'; ! 603: yyerror("-o file name too large (> 128 char); truncated to (%s)", outfilnm); ! 604: } ! 605: #if DEBUG ! 606: if(dflag) ! 607: fprintf(stderr, "output file name: %s\n", ! 608: outfilnm); ! 609: #endif ! 610: break; ! 611: case 'r': ! 612: rflag++; ! 613: break; ! 614: case 's': ! 615: sflag++; ! 616: break; ! 617: case 't': ! 618: #if TRVEC ! 619: if (flgname[1] == 'v') { ! 620: tvflag = 1; ! 621: magic = (unsigned short) TVMAGIC; ! 622: break; ! 623: } ! 624: #endif ! 625: #if COMMON ! 626: tflag++; ! 627: #endif ! 628: break; ! 629: case 'u': ! 630: if( ifile ) ! 631: if( yylex() != NAME ) ! 632: yyerror("-u flag does not specify a legal symbol name: %s", inline); ! 633: else ! 634: bldsym(yylval.sptr, 0L, 0); ! 635: else { ! 636: bldsym(*++argptr, 0L, 0); ! 637: argcnt--; ! 638: } ! 639: break; ! 640: #if PAGING ! 641: case 'z': ! 642: zflag++; ! 643: break; ! 644: #endif ! 645: #if !UNIX ! 646: case 'B': ! 647: if( ifile ) ! 648: if (yylex() != LONGINT) ! 649: yyerror("-B flag does not specify a number: %s", inline); ! 650: else ! 651: Bflag = *yylval.lptr; ! 652: else { ! 653: if( (Bflag = stoi(*++argptr)) == 0x8000 ) { ! 654: yyerror("-B flag does not specify a number: %s", *argptr); ! 655: Bflag = 0; ! 656: } ! 657: argcnt--; ! 658: } ! 659: #if DEBUG ! 660: if (dflag) ! 661: fprintf(stderr, "pad-section size: %.2x\n", ! 662: Bflag); ! 663: #endif ! 664: break; ! 665: case 'H': ! 666: Hflag++; ! 667: break; ! 668: #endif ! 669: #if PAGING ! 670: case 'F': ! 671: Fflag++; ! 672: break; ! 673: #endif ! 674: #if COMMON ! 675: case 'M': ! 676: Mflag++; ! 677: break; ! 678: #endif ! 679: case 'N': ! 680: Nflag++; ! 681: break; ! 682: case 'L': ! 683: if ( nldirs >= MAXLDIRS ) ! 684: yyerror("too many -L options, %d allowed", MAXLDIRS-1); ! 685: else if ( flgname[1] == NULL ) ! 686: yyerror("no directory given with -L"); ! 687: else if ( strlen(&flgname[1]) > MAXDLEN ) ! 688: yyerror("-L path too long(%s)", &flgname[1]); ! 689: else { ! 690: libdirs[nldirs] = myalloc(size(&flgname[1])); ! 691: strcpy(libdirs[nldirs++], &flgname[1]); ! 692: } ! 693: break; ! 694: case 'S': ! 695: Sflag++; ! 696: break; ! 697: case 'V': ! 698: if (flgname[1] == 'S') { ! 699: if( ifile ) ! 700: if (yylex() != LONGINT) ! 701: yyerror("-VS flag does not specify a numeric value: %s", inline); ! 702: else ! 703: VSflag = *yylval.lptr; ! 704: else { ! 705: if( (VSflag = stoi(*++argptr)) == 0x8000 ) { ! 706: yyerror("-VS flag does not specify a numeric value: %s", *argptr); ! 707: VSflag = 0; ! 708: } ! 709: argcnt--; ! 710: } ! 711: } ! 712: else { ! 713: Vflag++; ! 714: } ! 715: break; ! 716: #if !UNIX ! 717: case 'X': ! 718: Xflag++; ! 719: break; ! 720: #endif ! 721: default: ! 722: specflags(flgname, argptr); ! 723: } ! 724: } ! 725: /*eject*/ ! 726: library(fname) ! 727: char *fname; ! 728: { ! 729: ! 730: /* ! 731: * For a library flag of the form "-lx", build a file name of the form ! 732: * ! 733: * "libdirs[n]/libx.a" ! 734: * ! 735: * where libdirs[0] is LIBDIR (defined in paths.h) and libdirs[n>0] ! 736: * are defined using the -L option. Then build a LDFILE action item. ! 737: */ ! 738: ! 739: static char libname[MAXDLEN+16]; /* -lx file name */ ! 740: int dndx; ! 741: char *p; ! 742: FILE *lfd; ! 743: ! 744: if ( *(++fname) == '\0' ) { ! 745: yyerror("the -l flag (specifying a default library) is not supported"); ! 746: return; ! 747: } ! 748: else ! 749: p = fname; ! 750: ! 751: /* ! 752: * Loop thru libdir[NDELDIRS] thru libdir[nldirs-1] ! 753: */ ! 754: for ( dndx = NDELDIRS; dndx < nldirs; dndx++) { ! 755: sprintf(libname, "%s%s%.8s%s", libdirs[dndx], "/lib", p, ".a"); ! 756: if ( (lfd = fopen(libname,"r")) != NULL) ! 757: goto liblab; ! 758: } ! 759: ! 760: /* ! 761: * loop thru libdirs[0] thru libdirs[NDELDIRS-1] ! 762: */ ! 763: for ( dndx = 0; dndx < NDELDIRS; dndx++) { ! 764: sprintf(libname, "%s%s%.8s%s", libdirs[dndx], "/lib", p, ".a"); ! 765: if ( (lfd = fopen(libname,"r")) != NULL) ! 766: goto liblab; ! 767: } ! 768: ! 769: yyerror("can't find library lib%s.a", p); ! 770: return; ! 771: ! 772: liblab: ! 773: fclose(lfd); ! 774: bldldfil(savefn(libname), 1); ! 775: } ! 776: /*eject*/ ! 777: char * ! 778: savefn(name) ! 779: char *name; ! 780: { ! 781: ! 782: /* ! 783: * Save the name of an ifile or input *.o or archive file ! 784: */ ! 785: ! 786: char *strbeg; ! 787: int length; ! 788: ! 789: length = strlen(name) + 1; ! 790: if (strnext + length > strlimit) ! 791: { ! 792: #if ONEPROC ! 793: strbase = myalloc( STRINCRE ); ! 794: strnext = strbase; ! 795: strlimit = strbase + STRINCRE; ! 796: #else ! 797: lderror( 0, 0, NULL, "too many strings, out of space" ); ! 798: lderror( 2, 0, NULL, "%sld run is too large and complex", SGS ); ! 799: #endif ! 800: } ! 801: strbeg = strnext; ! 802: strncpy( strbeg, name, length ); ! 803: strnext += length; ! 804: ! 805: return( strbeg ); ! 806: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.