|
|
1.1 ! root 1: %{ ! 2: static char ID[] = "@(#) ld.lex: 1.10 12/1/83"; ! 3: #include "system.h" ! 4: #include <stdio.h> ! 5: #include <signal.h> ! 6: #include "bool.h" ! 7: #include "paths.h" ! 8: #include "sgs.h" ! 9: #include "structs.h" /* global structure definitions */ ! 10: #include "extrns.h" /* external function definitions */ ! 11: #include "y.tab.h" /* tokens generated by yacc */ ! 12: ! 13: #if !ONEPROC || TRVEC ! 14: #include "tv.h" ! 15: #include "ldtv.h" ! 16: #endif ! 17: ! 18: #include "aouthdr.h" ! 19: #if ONEPROC ! 20: #include "instr.h" ! 21: #endif ! 22: ! 23: extern char version[]; /* ld version information */ ! 24: ! 25: /* ! 26: * There are four start states for the lex parse: ! 27: * ! 28: * A : look for initial keyword of a ld directive ! 29: * MEMoREG : scan a ld directive ! 30: * COMA : skip a stand-alone comment ! 31: * COMoMR : skip a comment at the end of a directive ! 32: */ ! 33: ! 34: #define RET1(a) {yylval.ivalue=a;moveit(1,a);return(a);} ! 35: #define RET2(a,b) {yylval.sptr=a;moveit(2,yylval.sptr);return(b);} ! 36: #define RET3(a,b) {yylval.lptr=a;moveit(3,yylval.lptr);return(b);} ! 37: ! 38: ! 39: ! 40: #define LSAVSIZE 6 ! 41: static long lsavarea[LSAVSIZE]; /* local save area for integer tokens */ ! 42: static int lsavndx = 0; ! 43: extern long *savelng(); ! 44: ! 45: #define CSAVSIZE 1024 ! 46: static char csavarea[CSAVSIZE]; /* local save area for string tokens */ ! 47: static char *csavptr = &csavarea[0]; ! 48: extern char *savestr(); ! 49: ! 50: char inline[256]; /* global save area for the current input line */ ! 51: char *inptr = &inline[0]; ! 52: ! 53: char **argptr; /* main procedure argument list */ ! 54: int argcnt; /* and count */ ! 55: ! 56: ! 57: extern int in_y_exp; /* in_y_exp : ! 58: * TRUE : yacc is parsing assignment ! 59: * FALSE : yacc is not in assignment ! 60: * ! 61: * See explanation is ld.yac. ! 62: */ ! 63: ! 64: int assigncnt; /* number of assignment slots */ ! 65: ! 66: ! 67: #if FLEXNAMES ! 68: # define STRBASE 6144 ! 69: #else ! 70: # define STRBASE 3072 ! 71: #endif ! 72: /*eject*/ ! 73: %} ! 74: %start A MEMoREG COMA COMoMR ! 75: %% ! 76: %{ ! 77: long longint; /* local variables used in processing */ ! 78: char *p; /* numbers and strings */ ! 79: %} ! 80: ! 81: <A>"/*" BEGIN COMA; ! 82: <MEMoREG>"/*" BEGIN COMoMR; ! 83: <COMA>"*/" BEGIN A; ! 84: <COMoMR>"*/" BEGIN MEMoREG; ! 85: <COMA,COMoMR>. ; ! 86: ! 87: <A>MEMORY { BEGIN MEMoREG; RET1(MEMORY); } ! 88: <A>REGIONS { BEGIN MEMoREG; RET1(REGIONS); } ! 89: <A>TV { BEGIN MEMoREG; RET1(TV); } ! 90: ! 91: <A>SECTIONS RET1(SECTIONS); ! 92: <A>DSECT RET1(DSECT); ! 93: <A>NOLOAD RET1(NOLOAD); ! 94: <A>COPY RET1(COPY); ! 95: <A>INFO RET1(INFO); ! 96: ! 97: <MEMoREG>"}" { BEGIN A; RET1(RBRACE); } ! 98: <MEMoREG>ORIGIN|origin|org|o RET1(ORG); ! 99: <MEMoREG>LENGTH|length|len|l RET1(LEN); ! 100: <MEMoREG>SPARE|spare|s RET1(SPARE); ! 101: <MEMoREG>RANGE|range RET1(RANGE); ! 102: <MEMoREG>ASSIGN|assign RET1(ASSIGN); ! 103: ! 104: <A,MEMoREG>"." RET1(DOT); ! 105: <A,MEMoREG>"}" RET1(RBRACE); ! 106: <A,MEMoREG>"{" RET1(LBRACE); ! 107: <A,MEMoREG>")" RET1(RPAREN); ! 108: <A,MEMoREG>"(" RET1(LPAREN); ! 109: <A,MEMoREG>":" RET1(COLON); ! 110: <A,MEMoREG>";" RET1(SEMICOL); ! 111: <A,MEMoREG>"-" RET1(MINUS); ! 112: <A,MEMoREG>"=" RET1(EQ); ! 113: <A,MEMoREG>">" RET1(GT); ! 114: <A,MEMoREG>"," RET1(COMMA); ! 115: <A,MEMoREG>"&" RET1(AND); ! 116: <A,MEMoREG>"&&" RET1(ANDAND); ! 117: <A,MEMoREG>"|" RET1(OR); ! 118: <A,MEMoREG>"||" RET1(OROR); ! 119: <A,MEMoREG>"==" RET1(EQEQ); ! 120: <A,MEMoREG>"!=" RET1(NE); ! 121: <A,MEMoREG>"~" RET1(BNOT); ! 122: <A,MEMoREG>"!" RET1(NOT); ! 123: <A,MEMoREG>"/" RET1(DIV); ! 124: <A,MEMoREG>"*" RET1(MULT); ! 125: <A,MEMoREG>"%" RET1(PC); ! 126: <A,MEMoREG>"<" RET1(LT); ! 127: <A,MEMoREG>">=" RET1(GE); ! 128: <A,MEMoREG>"<=" RET1(LE); ! 129: <A,MEMoREG>"<<" RET1(LSHIFT); ! 130: <A,MEMoREG>">>" RET1(RSHIFT); ! 131: <A,MEMoREG>"+" RET1(PLUS); ! 132: <A,MEMoREG>"+=" RET1(PLUSEQ); ! 133: <A,MEMoREG>"-=" RET1(MINUSEQ); ! 134: <A,MEMoREG>"*=" RET1(MULTEQ); ! 135: <A,MEMoREG>"/=" RET1(DIVEQ); ! 136: <A,MEMoREG>ALIGN|align RET1(ALIGN); ! 137: <A,MEMoREG>BLOCK|block RET1(BLOCK); ! 138: <A,MEMoREG>GROUP|group RET1(GROUP); ! 139: <A,MEMoREG>PHY|phy RET1(PHY); ! 140: ! 141: ! 142: "\n" { ! 143: lineno++; ! 144: inptr = &inline[0]; ! 145: } ! 146: [ \t]+ { ! 147: *inptr++ = ' '; ! 148: *inptr = '\0'; ! 149: } ! 150: ! 151: ! 152: <A,MEMoREG>[0][0-7]* { ! 153: longint = 0L; ! 154: for(p=yytext+1; *p != '\0'; p++) { ! 155: longint = longint * 8 + (*p-'0'); ! 156: } ! 157: RET3(savelng(longint), LONGINT); ! 158: } ! 159: <A,MEMoREG>[0-9]+ { ! 160: longint = 0L; ! 161: for(p=yytext; *p != '\0'; p++) { ! 162: longint = longint * 10 + (*p-'0'); ! 163: } ! 164: RET3(savelng(longint), LONGINT); ! 165: } ! 166: <A,MEMoREG>0[Xx][0-9a-fA-F]+ { ! 167: longint = 0L; ! 168: for(p=yytext+2; *p != '\0'; p++) { ! 169: longint = longint << 4; ! 170: if (*p >= '0' && *p <= '9') ! 171: longint += *p-'0'; ! 172: else if (*p >= 'a' && *p <= 'f') ! 173: longint += *p-'a'+10; ! 174: else longint += *p-'A'+10; ! 175: } ! 176: RET3(savelng(longint), LONGINT); ! 177: } ! 178: ! 179: <A,MEMoREG>[a-zA-Z0-9$._]+"/"("*"|"=") { ! 180: yyless(yyleng-2); ! 181: RET2(savestr(yytext), NAME); ! 182: } ! 183: ! 184: <A,MEMoREG>[a-zA-Z0-9$._/]+"/"("*"|"=") { ! 185: if ( in_y_exp ) ! 186: REJECT; ! 187: yyless(yyleng-2); ! 188: RET2(savestr(yytext), FILENAME); ! 189: } ! 190: ! 191: <A,MEMoREG>[a-zA-Z0-9$._]+ { ! 192: RET2(savestr(yytext), NAME); ! 193: } ! 194: ! 195: <A,MEMoREG>[a-zA-Z0-9$._/]+ { ! 196: if ( in_y_exp ) ! 197: REJECT; ! 198: RET2(savestr(yytext), FILENAME); ! 199: } ! 200: %% ! 201: /*eject*/ ! 202: main(argc,argv) ! 203: int argc; ! 204: char *argv[]; ! 205: { ! 206: ! 207: /* ! 208: * This is the MAIN procdure for PASS 1 of ld ! 209: * ! 210: * PASS 1 is the parsing pass: ! 211: * 1. The ld command line, and any specified ifiles, are ! 212: * scanned for good syntax. ! 213: * 2. Control blocks are constructed, containing the information ! 214: * extracted from the input. ! 215: * 3. If there are no errors, the control blocks are written out ! 216: * to a "transfer file", for reading by PASS 2. ! 217: * 4. If there are no errors, PASS 2 is called via a system ! 218: * "execl" call. ! 219: */ ! 220: ! 221: /* ! 222: * Initialize PASS 1 ! 223: */ ! 224: ! 225: initpass1(); ! 226: argptr = argv; ! 227: argcnt = argc; ! 228: if ( argcnt <= 1 ) ! 229: { ! 230: fprintf( stderr, "Usage: %sld [ options ] file ...\n", SGS ); ! 231: exit(1); ! 232: } ! 233: ! 234: /* ! 235: * Process the command-line arguments to ld ! 236: */ ! 237: ! 238: lineno = 0; ! 239: curfilnm = savefn("*command line*"); ! 240: ! 241: while( --argcnt ) ! 242: if( **++argptr == '-' ) ! 243: /* ! 244: * The argument is a flag ! 245: */ ! 246: pflags( ++(*argptr), FALSE ); ! 247: else { ! 248: /* ! 249: * The argument is a file name ! 250: */ ! 251: BEGIN A; ! 252: filespec(*argptr); ! 253: } ! 254: ! 255: /* ! 256: * Perform a consistency check among the ld flags: ! 257: * 1. "-h" and "-X" flags ! 258: * 2. "-ild", "-r", and "-a" flags ! 259: * 3. "-r" and "-s" flags ! 260: * 4. "-p" and "-B" flags ! 261: * ! 262: * Assign default values to the ld flags ! 263: * 1. "-h" flag ! 264: * 2. "-a" flag ! 265: * 3. "-p" flag ! 266: */ ! 267: ! 268: if( Xflag ) ! 269: if( hflag > 0 ) { ! 270: if( hflag < sizeof(AOUTHDR) ) ! 271: lderror(1, 0,NULL, "optional header size (%d bytes) is too small to contain the UNIX a.out header (%d bytes)", ! 272: hflag, sizeof(AOUTHDR) ); ! 273: } ! 274: else ! 275: hflag = sizeof(AOUTHDR); ! 276: #if ILDOPT ! 277: if (ildflag) { ! 278: rflag = 1; ! 279: if (sflag) { ! 280: lderror (0, 0, NULL, "both -ild and -s flags are set. -s flag turned off"); ! 281: sflag = 0; ! 282: } ! 283: } ! 284: #endif ! 285: if( rflag && sflag ) { ! 286: lderror(0, 0,NULL, "both -r and -s flags are set. -s flag turned off" ); ! 287: sflag = 0; ! 288: } ! 289: if ( Bflag && (pflag > 0) && (pflag < Bflag)) { ! 290: lderror(0, 0, NULL, "pflag(%d) less than Bflag, set to value of Bflag(%d)\n", ! 291: pflag, Bflag); ! 292: pflag = Bflag; ! 293: } ! 294: if( ! rflag ) ! 295: aflag = 1; ! 296: ! 297: /* ! 298: * Supply version information ! 299: */ ! 300: ! 301: if( Vflag ) { ! 302: fprintf( stderr, "\n%sld : %s : Version %s", ! 303: SGSNAME, RELEASE, version ); ! 304: if( Vflag == 2 ) { ! 305: #if AR16WR ! 306: fprintf( stderr, " : PDP 11/70-45 : " ); ! 307: #endif ! 308: #if AR32WR ! 309: fprintf( stderr, " : VAX 11/780 : " ); ! 310: #endif ! 311: #if ! AR16WR && ! AR32WR ! 312: #ifdef u3b ! 313: fprintf( stderr, " : 3B-20 : " ); ! 314: #else ! 315: fprintf( stderr, " : non-DEC : "); ! 316: #endif ! 317: #endif ! 318: #if TS ! 319: fprintf( stderr, "UN*X TS" ); ! 320: #else ! 321: fprintf( stderr, "UN*X" ); ! 322: #endif ! 323: } ! 324: fprintf( stderr, "\n" ); ! 325: } ! 326: ! 327: /* ! 328: * Exit if any errors were found, or if this is a "parse only" ! 329: * run ! 330: */ ! 331: ! 332: if( (errlev != 0) || (cflag == 1) ) { ! 333: #if !ONEPROC ! 334: unlink( trnname ); ! 335: #endif ! 336: exit(errlev); ! 337: } ! 338: ! 339: /* ! 340: * Call PASS 2 ! 341: */ ! 342: ! 343: #if ONEPROC ! 344: pass2(); ! 345: } ! 346: #else ! 347: callpass2(); ! 348: ! 349: unlink( trnname ); ! 350: lderror(2, 0,NULL, "failure to load pass 2 of %sld", SGS); ! 351: } ! 352: /*eject*/ ! 353: ldexit() ! 354: { ! 355: ! 356: /* ! 357: * PASS 1: clean up and exit after a fatal error ! 358: */ ! 359: ! 360: signal(SIGINT, SIG_IGN); ! 361: signal(SIGQUIT, SIG_DFL); ! 362: signal(SIGTERM, SIG_IGN); ! 363: signal(SIGHUP, SIG_DFL); ! 364: ! 365: exit(13); /* unlucky break */ ! 366: } ! 367: /*eject*/ ! 368: #endif ! 369: long * ! 370: savelng(l) ! 371: long l; ! 372: { ! 373: ! 374: /* ! 375: * Copy a long token into local save area and return a pointer to it. ! 376: * ! 377: * The save area is used as a circular buffer ! 378: */ ! 379: ! 380: lsavndx++; ! 381: lsavndx %= LSAVSIZE; ! 382: lsavarea[lsavndx] = l; ! 383: ! 384: return( &lsavarea[lsavndx] ); ! 385: } ! 386: ! 387: ! 388: ! 389: ! 390: char * ! 391: savestr(p) ! 392: char *p; ! 393: { ! 394: ! 395: /* ! 396: * Copy a string into local save area and return a pointer to it ! 397: * ! 398: * The save area is used as a circular buffer ! 399: */ ! 400: ! 401: register char *saveptr; ! 402: ! 403: if( csavptr > (csavarea + CSAVSIZE - 256) ) ! 404: csavptr = csavarea; ! 405: saveptr = csavptr; ! 406: ! 407: while( *csavptr++ = *p++ ); ! 408: ! 409: return( saveptr ); ! 410: } ! 411: ! 412: ! 413: ! 414: ! 415: moveit(type, value) ! 416: int type, value; ! 417: { ! 418: register char *p; ! 419: ! 420: p = &yytext[0]; ! 421: ! 422: while( *inptr++ = *p++ ); ! 423: inptr--; ! 424: ! 425: #if DEBUG ! 426: if( dflag > 3 ) { ! 427: fprintf(stderr, "line: <%s> return: <", inline); ! 428: switch( type ) { ! 429: case 1: ! 430: fprintf(stderr, "%d>\n", value); ! 431: break; ! 432: case 2: ! 433: fprintf(stderr, "%s>\n", (char *) value); ! 434: break; ! 435: case 3: ! 436: fprintf(stderr, "%08lx>\n", * (long *) value); ! 437: break; ! 438: } ! 439: } ! 440: #endif ! 441: } ! 442: /*eject*/ ! 443: initpass1() ! 444: { ! 445: register int oldmode; ! 446: int ldexit(); ! 447: #if ONEPROC ! 448: long times(); ! 449: #endif ! 450: ! 451: /* ! 452: * Set the following signals to be caught, unless ld is running in the ! 453: * background. In this case, leave them set at "ignore" ! 454: */ ! 455: ! 456: if( signal(SIGINT, ldexit) == SIG_IGN ) ! 457: signal(SIGINT, SIG_IGN); ! 458: if( signal(SIGHUP, ldexit) == SIG_IGN ) ! 459: signal(SIGHUP, SIG_IGN); ! 460: if( signal(SIGQUIT, ldexit) == SIG_IGN ) ! 461: signal(SIGQUIT, SIG_IGN); ! 462: ! 463: ! 464: #if ONEPROC ! 465: ttime = times(&ptimes); ! 466: #else ! 467: /* ! 468: * Create the "transfer file" used to pass information to PASS 2 ! 469: */ ! 470: ! 471: sprintf(trnname, "%s/%s", TMPDIR, "ldXXXXX"); ! 472: mktemp(trnname); ! 473: ! 474: oldmode = umask( 0 ); ! 475: if( close( creat(trnname,0644) ) == -1 ) { ! 476: umask( oldmode ); ! 477: lderror(2, 0,NULL, "can't create intermediate %sld file %s", ! 478: SGS, trnname); ! 479: } ! 480: umask( oldmode ); ! 481: #endif ! 482: ! 483: /* ! 484: * Allocate the global file name save area ! 485: */ ! 486: ! 487: strbase = myalloc(STRBASE); ! 488: strnext = strbase; ! 489: strlimit = strbase + STRBASE; ! 490: ! 491: #if ONEPROC && (!NOSDP) ! 492: /* ! 493: * Initialize the Software Demand Paging System ! 494: */ ! 495: syminit(); ! 496: #endif ! 497: } ! 498: /*eject*/ ! 499: #if !ONEPROC ! 500: callpass2() ! 501: { ! 502: ! 503: /* ! 504: * Output PASS 1 information to the "transfer file" ! 505: * ! 506: * 1. reserve space for flags and list headers ! 507: * 2. output lists ! 508: * 3. output flags and list headers ! 509: */ ! 510: ! 511: trnfdes = fopen(trnname, "w"); ! 512: skp_tf_hdr(); ! 513: wrt_tf(); ! 514: wrt_tf_hdr(); ! 515: fclose( trnfdes ); ! 516: ! 517: /* ! 518: * Exit, if this is a "generate transfer file run" only ! 519: */ ! 520: ! 521: if( cflag == 2 ) { ! 522: fprintf( stderr, "ld transfer file name: %s\n", trnname ); ! 523: exit(0); ! 524: } ! 525: #if DEBUG ! 526: if( dflag > 2 ) ! 527: fprintf( stderr, "ld transfer file name: %s\n", trnname ); ! 528: #endif ! 529: ! 530: /* ! 531: * Execute PASS 2 ! 532: */ ! 533: ! 534: execl(LD2, LD2, trnname, 0); ! 535: ! 536: } ! 537: /*eject*/ ! 538: skp_tf_hdr() ! 539: { ! 540: ! 541: /* ! 542: * Reserve space for control and descriptor information collected during ! 543: * PASS 1 ! 544: * ! 545: * This information is of fixed length, and comes at the very beginning ! 546: * of the transfer file ! 547: */ ! 548: ! 549: register long length; ! 550: ! 551: length = ! 552: 7 * sizeof(int) + /* list sizes */ ! 553: 13 * sizeof(char) + /* flags */ ! 554: #if UNIX || XL ! 555: 1 * sizeof(char) + /* xflag */ ! 556: #endif ! 557: #if ILDOPT ! 558: 1 * sizeof(char) + /* ildflag */ ! 559: #endif ! 560: #if PAGING ! 561: 1 * sizeof(char) + /* Fflag */ ! 562: #endif ! 563: #if PAGING ! 564: 1 * sizeof(char) + /* zflag */ ! 565: #endif ! 566: #if COMMON ! 567: 2 * sizeof(char) + /* tflag and Mflag */ ! 568: #endif ! 569: 3 * sizeof(int) + /* control values */ ! 570: 3 * sizeof(short) + /* VStamp, fill and magic */ ! 571: 128 + /* output file name */ ! 572: 8 + /* program entry pt */ ! 573: sizeof(TVINFO) + /* tv information */ ! 574: 1 * sizeof(int); /* flags + counts */ ! 575: ! 576: fseek( trnfdes, length, 0 ); ! 577: } ! 578: /*eject*/ ! 579: wrt_tf() ! 580: { ! 581: ! 582: /* ! 583: * Output the bulk of the information extracted from PASS 1: ! 584: * ! 585: * 1. The names of input ifiles, input *.o and archive files, and ! 586: * output sections ! 587: * 2. The data structures describing the ld directives ! 588: */ ! 589: ! 590: MEMTYPE *outds1(); ! 591: REGION *outds2(); ! 592: ACTITEM *outds3(), *outds4(), *outds6(); ! 593: TVASSIGN *outds8(); ! 594: ! 595: /* ! 596: * 1. Output saved strings ! 597: */ ! 598: ! 599: fwrite( strbase, 1, (strnext - strbase), trnfdes ); ! 600: ! 601: ! 602: /* ! 603: * 2a. Output DEFSYM data structures ! 604: */ ! 605: ! 606: symcnt = 0; ! 607: if( symlist.head ) { ! 608: register ACTITEM *a; ! 609: a = (ACTITEM *) symlist.head; ! 610: while( a ) { ! 611: a = outds3(a); ! 612: symcnt++; ! 613: } ! 614: } ! 615: ! 616: /* ! 617: * 2b. Output MEMTYPE data structures ! 618: */ ! 619: ! 620: memcnt = 0; ! 621: if( memlist.head ) { ! 622: register MEMTYPE *m; ! 623: m = (MEMTYPE *) memlist.head; ! 624: while( m ) { ! 625: m = outds1(m); ! 626: memcnt++; ! 627: } ! 628: } ! 629: ! 630: /* ! 631: * 2c. Output REGION data structures ! 632: */ ! 633: ! 634: regcnt = 0; ! 635: if( reglist.head ) { ! 636: register REGION *r; ! 637: r = (REGION *) reglist.head; ! 638: while( r ) { ! 639: r = outds2(r); ! 640: regcnt++; ! 641: } ! 642: } ! 643: ! 644: /* ! 645: * 2d. Output information on input *.o and archive library files ! 646: */ ! 647: ! 648: ldfcnt = 0; ! 649: if( ldfilist.head ) { ! 650: register ACTITEM *a; ! 651: a = (ACTITEM *) ldfilist.head; ! 652: while( a ) { ! 653: a = outds3(a); ! 654: ldfcnt++; ! 655: } ! 656: } ! 657: ! 658: ! 659: /* ! 660: * 2e. Output information on output sections ! 661: */ ! 662: ! 663: bldcnt = 0; ! 664: if( bldoutsc.head ) { ! 665: register ACTITEM *a; ! 666: a = (ACTITEM *) bldoutsc.head; ! 667: while( a ) { ! 668: a = outds4(a); ! 669: bldcnt++; ! 670: } ! 671: } ! 672: ! 673: ! 674: /* ! 675: * 2f. Output information on assignments ! 676: */ ! 677: ! 678: expcnt = 0; ! 679: if( explist.head ) { ! 680: register ACTITEM *a; ! 681: a = (ACTITEM *) explist.head; ! 682: while( a ) { ! 683: a = outds6(a); ! 684: expcnt++; ! 685: } ! 686: } ! 687: ! 688: /* ! 689: * 2g. Output information on slot assignments ! 690: */ ! 691: ! 692: tvslotcnt = 0; ! 693: if (tvslot1 != NULL) { ! 694: register TVASSIGN *s; ! 695: s = tvslot1; ! 696: while (s != NULL) { ! 697: s = outds8(s); ! 698: ++tvslotcnt; ! 699: } ! 700: } ! 701: } ! 702: /*eject*/ ! 703: wrt_tf_hdr() ! 704: { ! 705: ! 706: /* ! 707: * Output control and descriptor information obtained during PASS 1 ! 708: * ! 709: * This information is of fixed length, and comes at the very beginning ! 710: * of the transfer file ! 711: */ ! 712: ! 713: int length; ! 714: ! 715: fseek( trnfdes, 0L, 0 ); ! 716: ! 717: /* ! 718: * Output the sizes of the lists built during PASS 1 ! 719: * ! 720: * 1. symbol definition/undefinition ! 721: * 2. MEMORY directives ! 722: * 3. REGIONS directives ! 723: * 4. input *.o and archive library files ! 724: * 5. output sections ! 725: * 6. assignment directives ! 726: * 7. tv slot assignment directives ! 727: */ ! 728: ! 729: fwrite( &symcnt, sizeof(int), 1, trnfdes ); ! 730: fwrite( &memcnt, sizeof(int), 1, trnfdes ); ! 731: fwrite( ®cnt, sizeof(int), 1, trnfdes ); ! 732: fwrite( &ldfcnt, sizeof(int), 1, trnfdes ); ! 733: fwrite( &bldcnt, sizeof(int), 1, trnfdes ); ! 734: fwrite( &expcnt, sizeof(int), 1, trnfdes ); ! 735: fwrite(&tvslotcnt, sizeof(int), 1, trnfdes); ! 736: ! 737: /* ! 738: * Output the ld control flags ! 739: */ ! 740: ! 741: fwrite( &aflag, sizeof(char), 1, trnfdes ); ! 742: fwrite( &cflag, sizeof(char), 1, trnfdes ); ! 743: fwrite( &dflag, sizeof(char), 1, trnfdes ); ! 744: fwrite( &iflag, sizeof(char), 1, trnfdes ); ! 745: fwrite( &mflag, sizeof(char), 1, trnfdes ); ! 746: fwrite( &rflag, sizeof(char), 1, trnfdes ); ! 747: fwrite( &sflag, sizeof(char), 1, trnfdes ); ! 748: fwrite( &tvflag, sizeof(char), 1, trnfdes ); ! 749: fwrite( &Hflag, sizeof(char), 1, trnfdes ); ! 750: fwrite( &Nflag, sizeof(char), 1, trnfdes ); ! 751: fwrite( &Sflag, sizeof(char), 1, trnfdes ); ! 752: fwrite( &Vflag, sizeof(char), 1, trnfdes ); ! 753: fwrite( &Xflag, sizeof(char), 1, trnfdes ); ! 754: fwrite( &hflag, sizeof(int), 1, trnfdes ); ! 755: fwrite( &pflag, sizeof(int), 1, trnfdes ); ! 756: fwrite( &Bflag, sizeof(int), 1, trnfdes ); ! 757: fwrite( &VSflag, sizeof(short), 1, trnfdes); ! 758: #if UNIX || XL ! 759: fwrite( &xflag, sizeof(char), 1, trnfdes ); ! 760: #endif ! 761: #if COMMON ! 762: fwrite( &tflag, sizeof(char), 1, trnfdes ); ! 763: fwrite( &Mflag, sizeof(char), 1, trnfdes ); ! 764: #endif ! 765: #if PAGING ! 766: fwrite( &Fflag, sizeof(char), 1, trnfdes ); ! 767: #endif ! 768: #if PAGING ! 769: fwrite( &zflag, sizeof(char), 1, trnfdes ); ! 770: #endif ! 771: #if ILDOPT ! 772: fwrite( &ildflag, sizeof(char), 1, trnfdes ); ! 773: #endif ! 774: ! 775: /* ! 776: * Output various values extracted from the parse ! 777: */ ! 778: ! 779: fwrite( &globfill, sizeof(short), 1, trnfdes ); ! 780: fwrite( &magic, sizeof(unsigned short), 1, trnfdes ); ! 781: ! 782: fwrite( outfilnm, 128, 1, trnfdes ); ! 783: fwrite( epsymbol, 8, 1, trnfdes ); ! 784: ! 785: /* convert filename from ptr to index */ ! 786: if (tvspec.tvinflnm != NULL) ! 787: tvspec.tvinflnm = (char *) ((int) tvspec.tvinflnm - (int) strbase); ! 788: fwrite( &tvspec, sizeof(TVINFO), 1, trnfdes ); ! 789: ! 790: /* ! 791: * Output the size of the saved strings ! 792: */ ! 793: ! 794: length = strnext - strbase; ! 795: fwrite( &length, sizeof(int), 1, trnfdes ); ! 796: } ! 797: /*eject*/ ! 798: MEMTYPE * ! 799: outds1(m) ! 800: MEMTYPE *m; ! 801: { ! 802: ! 803: /* ! 804: * Output one MEMTYPE data structure ! 805: */ ! 806: ! 807: fwrite( m, 1, sizeof(MEMTYPE), trnfdes ); ! 808: ! 809: return( m->mtnext ); ! 810: } ! 811: ! 812: ! 813: ! 814: REGION * ! 815: outds2(r) ! 816: REGION *r; ! 817: { ! 818: ! 819: /* ! 820: * Output one REGION data structure ! 821: */ ! 822: ! 823: fwrite( r, 1, sizeof(REGION), trnfdes ); ! 824: ! 825: return( r->rgnext ); ! 826: } ! 827: /*eject*/ ! 828: ACTITEM * ! 829: outds3(a) ! 830: ACTITEM *a; ! 831: { ! 832: ! 833: /* ! 834: * Output one AILDFILE, AILDLBRY, AIADFILE, or AIDFNSYM data structure ! 835: * ! 836: * Convert a "pointer to a string" to a "index to a string" ! 837: */ ! 838: ! 839: a->ldlbry.aiinflnm = (char *) ((int) a->ldlbry.aiinflnm - (int) strbase); ! 840: a->ldlbry.aifilnam = (char *) ((int) a->ldlbry.aifilnam - (int) strbase); ! 841: ! 842: fwrite( a, 1, sizeof(ACTITEM), trnfdes ); ! 843: ! 844: return( a->ldlbry.ainext ); ! 845: } ! 846: ! 847: ! 848: ! 849: ACTITEM * ! 850: outds4(a) ! 851: ACTITEM *a; ! 852: { ! 853: ! 854: /* ! 855: * Output one AIDFNSCN or AIDFNGRP data structure ! 856: * ! 857: * Convert a "pointer to a string" to a "index to a string" ! 858: */ ! 859: ! 860: register ACTITEM *anext, *b; ! 861: ACTITEM *outds5(); ! 862: ! 863: anext = a->dfnscn.ainext; ! 864: a->dfnscn.aiinflnm = (char *) ((int) a->dfnscn.aiinflnm - (int) strbase); ! 865: ! 866: fwrite( a, 1, sizeof(ACTITEM), trnfdes ); ! 867: ! 868: b = (ACTITEM *) a->dfnscn.sectspec.head; ! 869: switch( a->dfnscn.aitype ) { ! 870: case AIDFNSCN: ! 871: while( b ) ! 872: switch( b->addscn.aitype ) { ! 873: case AIADDSCN: ! 874: b = outds5(b); ! 875: break; ! 876: case AIADFILE: ! 877: b = outds3(b); ! 878: break; ! 879: case AIEVEXPR: ! 880: b = outds6(b); ! 881: break; ! 882: } ! 883: break; ! 884: case AIDFNGRP: ! 885: while( b ) ! 886: b = outds4(b); ! 887: break; ! 888: default: ! 889: lderror(2,0,NULL,"failure dumping an AIDFNxxx data structure\n"); ! 890: } ! 891: ! 892: return( a->dfnscn.ainext ); ! 893: } ! 894: ! 895: ! 896: ! 897: ACTITEM * ! 898: outds5(a) ! 899: ACTITEM *a; ! 900: { ! 901: ! 902: /* ! 903: * Output one AIADDSCN data structure ! 904: * ! 905: * Convert a "pointer to a string" to a "index to a string" ! 906: */ ! 907: ! 908: a->addscn.aiinflnm = (char *) ((int) a->addscn.aiinflnm - (int) strbase); ! 909: a->addscn.aiscfile = (char *) ((int) a->addscn.aiscfile - (int) strbase); ! 910: ! 911: fwrite( a, 1, sizeof(ACTITEM), trnfdes ); ! 912: ! 913: return( a->addscn.ainext ); ! 914: } ! 915: ! 916: ! 917: ! 918: ACTITEM * ! 919: outds6(a) ! 920: ACTITEM *a; ! 921: { ! 922: ! 923: /* ! 924: * Output one AIEVEXPR data structure ! 925: * ! 926: * Convert a "pointer to a string" to a "index to a string" ! 927: */ ! 928: ! 929: a->evexpr.aiinflnm = (char *) ((int) a->evexpr.aiinflnm - (int) strbase); ! 930: ! 931: fwrite( a, 1, sizeof(ACTITEM), trnfdes ); ! 932: ! 933: outds7( a->evexpr.aiexptr ); ! 934: ! 935: return( a->evexpr.ainext ); ! 936: } ! 937: ! 938: ! 939: ! 940: outds7(e) ! 941: ENODE *e; ! 942: { ! 943: ! 944: /* ! 945: * Output one ENODE data structure ! 946: */ ! 947: ! 948: switch( (unsigned) e->gnode.exop ) { ! 949: case INT: ! 950: case DOT: ! 951: fwrite( e, 1, sizeof(ENODE), trnfdes ); ! 952: break; ! 953: case NAME: ! 954: fwrite( e, 1, sizeof(ENODE), trnfdes ); ! 955: break; ! 956: default: ! 957: fwrite( e, 1, sizeof(ENODE), trnfdes ); ! 958: if( e->gnode.exleft ) ! 959: outds7(e->gnode.exleft); ! 960: if( e->gnode.exright ) ! 961: outds7(e->gnode.exright); ! 962: } ! 963: ! 964: } ! 965: ! 966: ! 967: ! 968: TVASSIGN * ! 969: outds8(s) ! 970: TVASSIGN *s; ! 971: { ! 972: ! 973: /* ! 974: * Output one tv slot assignment (TVASSIGN) structure ! 975: */ ! 976: ! 977: fwrite( s, sizeof(TVASSIGN), 1, trnfdes); ! 978: return( s->nxtslot ); ! 979: } ! 980: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.