|
|
1.1 ! root 1: static char ID[] = "@(#) ld2.c: 1.16 12/1/83"; ! 2: #include "system.h" ! 3: ! 4: #include <stdio.h> ! 5: #include "reloc.h" ! 6: #include "linenum.h" ! 7: #include "structs.h" ! 8: #include "y.tab.h" ! 9: ! 10: #if TRVEC ! 11: #include "tv.h" ! 12: #include "ldtv.h" ! 13: #endif ! 14: ! 15: #include "extrns.h" ! 16: #include "list.h" ! 17: #include "params.h" ! 18: #include "sgsmacros.h" ! 19: #include "patch.h" ! 20: ! 21: ! 22: #define BASIC_TYPES (STYP_TEXT | STYP_DATA | STYP_BSS) ! 23: #define K8 0x2000L ! 24: static ITEMID dotacid; ! 25: static OUTSECT *dotosptr; ! 26: /*eject*/ ! 27: pboslist() ! 28: { ! 29: ! 30: /* ! 31: * Process the BLDOUTSC List ! 32: */ ! 33: ! 34: register OUTSECT *osptr; ! 35: register INSECT *insptr; ! 36: register INFILE *inflptr; ! 37: #if !ONEPROC ! 38: ACTITEM a; ! 39: #endif ! 40: OUTSECT *dfn_scn_grp(); ! 41: long check_sect(); ! 42: ! 43: ! 44: /* ! 45: * Process the list of output sections. Output sections can be ! 46: * defined in two places: ! 47: * ! 48: * 1. PASS 1: user-supplied; bldcnt will be > 0, and the bldoutsc ! 49: * list head will be NULL ! 50: * 2. PASS 2: default-generation; bldcnt will be 0, and the ! 51: * bldoutsc list will describe the output ! 52: * sections ! 53: * ! 54: * These two uses are mutually exclusive ! 55: */ ! 56: ! 57: #if DEBUG ! 58: if( dflag > 2 ) ! 59: fprintf( stderr, "\nBLDOSCN data structures:" ); ! 60: #endif ! 61: #if !ONEPROC ! 62: while( bldcnt-- ) { ! 63: ! 64: fread( &a, 1, sizeof(ACTITEM), trnfdes ); ! 65: a.dfnscn.aiinflnm = (char *) ((int) a.dfnscn.aiinflnm + (int) strbase); ! 66: ! 67: osptr = dfn_scn_grp(&a, 0); ! 68: copy(osptr->oshdr.s_name, a.dfnscn.ainame, 8); ! 69: #if TRVEC ! 70: /* ! 71: * User can define attributes of TV in two ways: ! 72: * (1) using TV { } directive ! 73: * (2) using SECTIONS { .tv : {} } directive ! 74: * so force them to agree ! 75: */ ! 76: if ( equal(a.dfnscn.ainame, _TV, 8) ) { /* defining .tv */ ! 77: if ( tvspec.tvbndadr == -1L ) ! 78: tvspec.tvbndadr = a.dfnscn.aibndadr; ! 79: else ! 80: a.dfnscn.aibndadr = tvspec.tvbndadr; ! 81: } ! 82: #endif ! 83: if( a.dfnscn.aitype == AIDFNSCN ) ! 84: numoutsc++; ! 85: ! 86: osptr->oshdr.s_paddr = -1L; ! 87: listadd(l_OS, &outsclst, osptr); ! 88: } ! 89: #endif ! 90: ! 91: /* ! 92: * We now know everything there is to know about the ! 93: * transfer vector: ! 94: * At the end of ploadfil(), we knew how big it ! 95: * had to be. ! 96: * Here we know whether it was defined by ld or ! 97: * whether it is defined by .tv input sections ! 98: * together with a .tv SECTION directive ! 99: * Go check everything and complete tvspec definition. ! 100: */ ! 101: ! 102: #if TRVEC ! 103: if ( tvflag ) ! 104: tvupdat(); /* update definition of tv */ ! 105: #endif ! 106: ! 107: if( bldoutsc.head ) { ! 108: register ACTITEM *aptr, *a2ptr; ! 109: ! 110: aptr = (ACTITEM *) bldoutsc.head; ! 111: while( aptr ) { ! 112: ! 113: osptr = dfn_scn_grp(aptr, 1); ! 114: ! 115: copy(osptr->oshdr.s_name, aptr->dfnscn.ainame, 8); ! 116: if( aptr->dfnscn.aitype == AIDFNSCN ) ! 117: numoutsc++; ! 118: ! 119: osptr->oshdr.s_paddr = -1L; ! 120: listadd(l_OS, &outsclst, osptr); ! 121: ! 122: a2ptr = aptr; ! 123: aptr = aptr->dfnscn.ainext; ! 124: free( (char *) a2ptr); ! 125: } ! 126: } ! 127: ! 128: /* ! 129: * Make sure all input sections are allocated ! 130: * into some output section. ! 131: */ ! 132: ! 133: for( inflptr = (INFILE *) infilist.head; inflptr; inflptr = inflptr->flnext ) { ! 134: for( insptr = inflptr->flishead; insptr; insptr=insptr->isnext ) { ! 135: if (insptr->isoutsec <= 0) { ! 136: if ((osptr = fndoutsec(insptr->ishdr.s_name)) != NULL) ! 137: inscadd(insptr,osptr); ! 138: else { ! 139: osptr = (OUTSECT *) myalloc(sizeof(OUTSECT)); ! 140: numoutsc++; ! 141: copy(osptr->oshdr.s_name, insptr->ishdr.s_name, 8); ! 142: osptr->osfill = globfill; ! 143: osptr->oshdr.s_paddr = -1l; ! 144: listadd(l_OS,&outsclst,osptr); ! 145: inscadd(insptr,osptr); ! 146: } ! 147: } ! 148: } ! 149: } ! 150: ! 151: /* ! 152: * for each output section, check the flags, and for a group, ! 153: * check the size. ! 154: */ ! 155: ! 156: for( osptr = (OUTSECT *) outsclst.head; osptr; osptr = osptr->osnext ) ! 157: { ! 158: #if PAGING ! 159: ACTITEM *aptr; ! 160: ADDRESS textbegin, textsize; ! 161: textbegin = hflag + FILHSZ + SCNHSZ * numoutsc + memorg; ! 162: #endif ! 163: if (osptr->oshdr.s_flags & STYP_GROUP) { ! 164: OUTSECT *op; ! 165: for( op = ((OUTSECT *) osptr->osinclhd); op; op = op->osnext ) { ! 166: #if PAGING ! 167: if (bond_t_d && !Nflag && equal(op->oshdr.s_name,_DATA,8)) { ! 168: osptr->osalign = 0L; ! 169: aptr = (ACTITEM *) myalloc(sizeof(ACTITEM)); ! 170: aptr->bond.aitype = AIBOND; ! 171: aptr->bond.aiinflnm = "*default.bond.file*"; ! 172: aptr->bond.aiinlnno = 3; ! 173: aptr->bond.aioutsec = osptr; ! 174: aptr->bond.aiadrbnd = ((textsize + textbegin) / BOUNDARY + 1) ! 175: * BOUNDARY + (textsize + textbegin) % K8; ! 176: listadd(l_AI,&bondlist,aptr); ! 177: } ! 178: #endif ! 179: osptr->oshdr.s_size += check_sect( op ); ! 180: } ! 181: if (osptr->oshdr.s_size > MAXSCNSIZE) ! 182: lderror(1,0,NULL, "GROUP containing section %.8s is too big", ! 183: osptr->osinclhd->ishdr.s_name); ! 184: } else { ! 185: #if PAGING ! 186: if (bond_t_d && !Nflag && equal(osptr->oshdr.s_name,_TEXT,8)) { ! 187: textsize = osptr->oshdr.s_size; ! 188: aptr = (ACTITEM *) myalloc(sizeof(ACTITEM)); ! 189: aptr->bond.aitype = AIBOND; ! 190: aptr->bond.aiinflnm = "*default.bond.file*"; ! 191: aptr->bond.aiinlnno = 2; ! 192: aptr->bond.aioutsec = osptr; ! 193: aptr->bond.aiadrbnd = textbegin; ! 194: listadd(l_AI,&bondlist,aptr); ! 195: } ! 196: #endif ! 197: check_sect( osptr ); ! 198: } ! 199: } ! 200: ! 201: /* ! 202: * If .tv is user-defined, we now know the true size of ! 203: * the section ( the sum of the sizes of the input ! 204: * sections) which we didn't know before. Now call the ! 205: * the final update routine to insure .tv symtab entry ! 206: * is correct ! 207: */ ! 208: ! 209: #if TRVEC ! 210: if ( tvflag ) ! 211: tvupdt2(); /* final update of tvrange and tvlength */ ! 212: #endif ! 213: ! 214: #if DEBUG ! 215: if (dflag) ! 216: dmp_outsects(); ! 217: #endif ! 218: } ! 219: /*eject*/ ! 220: OUTSECT * ! 221: dfn_scn_grp(aptr, dflt) ! 222: ! 223: ACTITEM *aptr; /* DFNSCN or DFNGRP entry */ ! 224: int dflt; /* user-supplied or ld-default entry */ ! 225: { ! 226: ! 227: /* ! 228: * Process one AIDFNSCN or AIDFNGRP data structure from ! 229: * the list of output sections ! 230: */ ! 231: ! 232: OUTSECT *osptr, *op; ! 233: INFILE *inflptr; ! 234: INSECT *insptr; ! 235: ENODE *ep; ! 236: long val; ! 237: int fill, fillflag; ! 238: ACTITEM *a2ptr; ! 239: #if !ONEPROC ! 240: ACTITEM b; ! 241: #endif ! 242: ! 243: #if DEBUG ! 244: if( dflag > 2 ) ! 245: fprintf( stderr, "\n\t%04x %s (%s) %d (%s) %04x (%s)\n\t\t%08lx %d %08lx %08lx %d %d (%04x,%04x)", ! 246: aptr->dfnscn.ainext, ! 247: (aptr->dfnscn.aitype == AIDFNSCN) ? "AIDFNSCN" : "AIDFNGRP", ! 248: aptr->dfnscn.aiinflnm, ! 249: aptr->dfnscn.aiinlnno, aptr->dfnscn.ainame, aptr->dfnscn.aifill, ! 250: aptr->dfnscn.aiowname, aptr->dfnscn.aibndadr, aptr->dfnscn.aiattown, ! 251: aptr->dfnscn.aialign, aptr->dfnscn.aiblock, (unsigned) aptr->dfnscn.aifillfg, ! 252: (unsigned) aptr->dfnscn.aisctype, aptr->dfnscn.sectspec.head, aptr->dfnscn.sectspec.tail ); ! 253: #endif ! 254: ! 255: osptr = (OUTSECT *) myalloc(sizeof(OUTSECT)); ! 256: if (aptr->dfnscn.aibndadr != -1L) { /* section bonded */ ! 257: a2ptr = (ACTITEM *) myalloc(sizeof(ACTITEM)); ! 258: a2ptr->bond.aitype = AIBOND; ! 259: a2ptr->bond.aiinflnm = aptr->dfnscn.aiinflnm; ! 260: a2ptr->bond.aiinlnno = aptr->dfnscn.aiinlnno; ! 261: a2ptr->bond.aioutsec = osptr; ! 262: a2ptr->bond.aiadrbnd = aptr->dfnscn.aibndadr; ! 263: listadd(l_AI,&bondlist,a2ptr); ! 264: } ! 265: else if (aptr->dfnscn.aiowname[0] != '\0') { /*owner specified */ ! 266: a2ptr = (ACTITEM *) myalloc(sizeof(ACTITEM)); ! 267: a2ptr->dfownr.aitype = AIDFOWNR; ! 268: a2ptr->dfownr.aiinflnm = aptr->dfnscn.aiinflnm; ! 269: a2ptr->dfownr.aiinlnno = aptr->dfnscn.aiinlnno; ! 270: a2ptr->dfownr.aioutsec = osptr; ! 271: copy(a2ptr->dfownr.ainamown, aptr->dfnscn.aiowname, 8); ! 272: listadd(l_AI,&ownlist,a2ptr); ! 273: } ! 274: else if (aptr->dfnscn.aiattown != 0) { /* attr of owner */ ! 275: a2ptr = (ACTITEM *) myalloc(sizeof(ACTITEM)); ! 276: a2ptr->ownatr.aitype = AIOWNATR; ! 277: a2ptr->ownatr.aiinflnm = aptr->dfnscn.aiinflnm; ! 278: a2ptr->ownatr.aiinlnno = aptr->dfnscn.aiinlnno; ! 279: a2ptr->ownatr.aioutsec = osptr; ! 280: a2ptr->ownatr.aiownatt = aptr->dfnscn.aiattown; ! 281: listadd(l_AI,&atownlst,a2ptr); ! 282: } ! 283: ! 284: if (aptr->dfnscn.aitype == AIDFNGRP) ! 285: osptr->oshdr.s_flags = STYP_GROUP; ! 286: else ! 287: osptr->oshdr.s_flags = aptr->dfnscn.aisctype; ! 288: osptr->osalign = aptr->dfnscn.aialign; ! 289: osptr->osblock = aptr->dfnscn.aiblock; ! 290: osptr->osfill = aptr->dfnscn.aifill; ! 291: osptr->osflags |= aptr->dfnscn.aifillfg; ! 292: ! 293: /* ! 294: * A DFNSCN need have no subordinate entries, since the following is ! 295: * legal: ! 296: * .text : {} ! 297: */ ! 298: ! 299: if( aptr->dfnscn.sectspec.head == NULL ) ! 300: return( osptr ); ! 301: ! 302: /* ! 303: * A DFNGRP is a sequence of one or more DFNSCN entries ! 304: */ ! 305: ! 306: if( aptr->dfnscn.aitype == AIDFNGRP ) { ! 307: a2ptr = (ACTITEM *) aptr->dfnscn.sectspec.head; ! 308: do { ! 309: if( ! dflt ) { ! 310: #if !ONEPROC ! 311: fread( &b, 1, sizeof(ACTITEM), trnfdes ); ! 312: b.dfnscn.aiinflnm = (char *) ((int) b.dfnscn.aiinflnm + (int) strbase); ! 313: a2ptr = &b; ! 314: #endif ! 315: } ! 316: ! 317: op = dfn_scn_grp(a2ptr, dflt); ! 318: ! 319: op->oshdr.s_paddr = -1L; ! 320: listadd(l_GRP, osptr, op); ! 321: numoutsc++; ! 322: copy(op->oshdr.s_name, a2ptr->dfnscn.ainame, 8); ! 323: ! 324: if( (a2ptr = a2ptr->dfnscn.ainext) == NULL ) ! 325: return( osptr ); ! 326: } ! 327: while( 1 ); ! 328: } ! 329: ! 330: /* ! 331: * Process a DFNSCN with one or more subordinate entries, of type ! 332: * AIADFILE, AIADDSCN, or AIEVEXPR ! 333: */ ! 334: ! 335: a2ptr = (ACTITEM *) aptr->dfnscn.sectspec.head; ! 336: do { ! 337: if( ! dflt ) { ! 338: #if !ONEPROC ! 339: fread( &b, 1, sizeof(ACTITEM), trnfdes ); ! 340: b.adfile.aiinflnm = (char *) ((int) b.adfile.aiinflnm + (int) strbase); ! 341: a2ptr = &b; ! 342: #endif ! 343: } ! 344: ! 345: switch( a2ptr->adfile.aitype ) { ! 346: ! 347: case AIADFILE: ! 348: ! 349: if( ! dflt ) ! 350: a2ptr->adfile.aifilnam = (char *) ((int) a2ptr->adfile.aifilnam + (int) strbase); ! 351: ! 352: #if DEBUG ! 353: if( dflag > 2 ) ! 354: fprintf( stderr, "\n\t%04x AIADFILE (%s) %d (%s) %d %d %d", ! 355: a2ptr->adfile.ainext, a2ptr->adfile.aiinflnm, ! 356: a2ptr->adfile.aiinlnno, a2ptr->adfile.aifilnam, a2ptr->adfile.ainadscs, ! 357: a2ptr->adfile.aifill2, (unsigned) a2ptr->adfile.aifilflg ); ! 358: #endif ! 359: ! 360: if( (inflptr = fndinfil(a2ptr->adfile.aifilnam)) == NULL ) ! 361: break; ! 362: if( a2ptr->adfile.ainadscs == 0 ) { ! 363: insptr = inflptr->flishead; ! 364: while( insptr ) { ! 365: if( insptr->isoutsec == NULL ) { ! 366: inscadd(insptr, osptr); ! 367: insptr->isfill = a2ptr->adfile.aifill2; ! 368: insptr->isfillfg = a2ptr->adfile.aifilflg; ! 369: } ! 370: insptr = insptr->isnext; ! 371: /* ! 372: * In case inflptr is library, ! 373: * get next one ! 374: */ ! 375: if( (insptr == NULL) && (inflptr->flfiloff > 0L) ) ! 376: while( (inflptr = inflptr->flnext) ) ! 377: if (strcmp(a2ptr->adfile.aifilnam,inflptr->flname) == 0) { ! 378: insptr = inflptr->flishead; ! 379: break; ! 380: } ! 381: } ! 382: } ! 383: else { ! 384: fill = a2ptr->adfile.aifill2; ! 385: fillflag = a2ptr->adfile.aifilflg; ! 386: } ! 387: break; ! 388: ! 389: case AIADDSCN: ! 390: ! 391: if( ! dflt ) ! 392: a2ptr->addscn.aiscfile = (char *) ((int) a2ptr->addscn.aiscfile + (int) strbase); ! 393: ! 394: #if DEBUG ! 395: if( dflag > 2 ) ! 396: fprintf( stderr, "\n\t%04x AIADDSCN (%s) %d (%s) %04x (%s)", ! 397: a2ptr->addscn.ainext, a2ptr->addscn.aiinflnm, ! 398: a2ptr->addscn.aiinlnno, a2ptr->addscn.ainame, a2ptr->addscn.aifill, ! 399: a2ptr->addscn.aiscfile ); ! 400: #endif ! 401: ! 402: if( (inflptr = fndinfil(a2ptr->addscn.aiscfile)) == NULL ) ! 403: break; ! 404: insptr = inflptr->flishead; ! 405: while(insptr) { ! 406: if (equal(a2ptr->addscn.ainame,insptr->ishdr.s_name,8)) { ! 407: if (insptr->isoutsec) { ! 408: lderror(1, a2ptr->addscn.aiinlnno, a2ptr->addscn.aiinflnm, ! 409: "adding %s(%.8s) to multiple output sections", ! 410: inflptr->flname, ! 411: insptr->ishdr.s_name); ! 412: goto contin1; ! 413: } ! 414: inscadd(insptr,osptr); ! 415: insptr->isfill = fill; ! 416: insptr->isfillfg = fillflag; ! 417: insptr = NULL; ! 418: if (inflptr->flfiloff > 0L) ! 419: /* ! 420: * In case inflptr is library, ! 421: * get next one ! 422: */ ! 423: while( (inflptr = inflptr->flnext) ) ! 424: if (strcmp(a2ptr->addscn.aiscfile,inflptr->flname) == 0) { ! 425: insptr = inflptr->flishead; ! 426: break; ! 427: } ! 428: if ( insptr != NULL ) ! 429: continue; ! 430: else ! 431: goto contin1; ! 432: } ! 433: insptr = insptr->isnext; ! 434: } ! 435: lderror(1, a2ptr->addscn.aiinlnno, a2ptr->addscn.aiinflnm, ! 436: "%s(%.8s) not found", ! 437: a2ptr->addscn.aiscfile,a2ptr->addscn.ainame); ! 438: break; ! 439: ! 440: case AIEVEXPR: ! 441: ! 442: #if DEBUG ! 443: if( dflag > 2 ) ! 444: fprintf( stderr, "\n\t%04x AIEVEXPR (%s) %d %04x\n\t\tROOT:", ! 445: a2ptr->evexpr.ainext, a2ptr->evexpr.aiinflnm, ! 446: a2ptr->evexpr.aiinlnno, a2ptr->evexpr.aiexptr ); ! 447: #endif ! 448: ! 449: #if ONEPROC ! 450: aptr = a2ptr; ! 451: #else ! 452: aptr = ldexp( &b ); ! 453: #endif ! 454: ! 455: a2ptr = a2ptr->adfile.ainext; ! 456: ep = aptr->evexpr.aiexptr; ! 457: cur_dot = osptr->oshdr.s_size; ! 458: ! 459: if (ep->gnode.exleft->gnode.exop != DOT) { ! 460: /* ! 461: * LHS of assnment is regular symbol ! 462: */ ! 463: dotacid = 0; ! 464: dotosptr = osptr; ! 465: chgdot(ep->gnode.exright); ! 466: listadd(l_AI, &explist, aptr); ! 467: } ! 468: else { ! 469: /* ! 470: * LHS is DOT symbol ! 471: */ ! 472: curexp = aptr; ! 473: val = eval(ep->gnode.exright); ! 474: if (val < cur_dot) ! 475: lderror(1, aptr->evexpr.aiinlnno, aptr->evexpr.aiinflnm, ! 476: "attempt to decrement DOT"); ! 477: else ! 478: osptr->oshdr.s_size = val; ! 479: ! 480: clrexp( aptr ); ! 481: } ! 482: goto contin2; ! 483: } ! 484: ! 485: contin1: ! 486: a2ptr = a2ptr->adfile.ainext; ! 487: contin2: ! 488: if (a2ptr == NULL) ! 489: return( osptr ); ! 490: ! 491: } ! 492: while( 1 ); ! 493: } ! 494: /*eject*/ ! 495: inscadd(pin,pout) ! 496: INSECT *pin; ! 497: OUTSECT *pout; ! 498: { ! 499: ! 500: /* ! 501: * Add an input section to an output section. ! 502: * ! 503: * The text, relocation, and lineno info of the input section ! 504: * are allocated at the end of the output section. ! 505: */ ! 506: ! 507: long btype; ! 508: ! 509: pin->isoutsec = pout; ! 510: pin->isdispl = pout->oshdr.s_size; ! 511: pin->islndisp = ((long) pout->oshdr.s_nlnno * (long) LINESZ); ! 512: pout->oshdr.s_size += pin->ishdr.s_size; ! 513: pout->oshdr.s_nlnno += pin->ishdr.s_nlnno; ! 514: ! 515: if (rflag) { ! 516: pin->isrldisp = ((long) pout->oshdr.s_nreloc * (long) RELSZ); ! 517: pout->oshdr.s_nreloc += pin->ishdr.s_nreloc; ! 518: } ! 519: ! 520: btype = pin->ishdr.s_flags & BASIC_TYPES; ! 521: if (btype) ! 522: pout->oshdr.s_flags |= btype; ! 523: else if ( equal( _TEXT, pin->ishdr.s_name, 8 )) ! 524: pout->oshdr.s_flags |= STYP_TEXT; ! 525: else if ( equal( _DATA, pin->ishdr.s_name, 8 )) ! 526: pout->oshdr.s_flags |= STYP_DATA; ! 527: else if ( equal( _BSS, pin->ishdr.s_name, 8 )) ! 528: pout->oshdr.s_flags |= STYP_BSS; ! 529: ! 530: pout->osflags |= (pin->ishdr.s_flags & STYP_DSECT) ? OSDSECT : OSREG; ! 531: if (pin->ishdr.s_flags & STYP_INFO) ! 532: pout->osflags |= OSINFO; ! 533: if (pin->ishdr.s_flags & STYP_COPY) ! 534: pout->osflags |= OSCOPY; ! 535: ! 536: listadd(l_INC,pout,pin); ! 537: } ! 538: /*eject*/ ! 539: INFILE * ! 540: fndinfil(fnam) ! 541: char *fnam; ! 542: { ! 543: ! 544: /* ! 545: * Locate the input file structure by a given name, and ! 546: * return a pointer to the structure. ! 547: * ! 548: * Note: fnam must be a null terminated string. ! 549: */ ! 550: ! 551: register INFILE *p; ! 552: ! 553: p = (INFILE *) infilist.head; ! 554: while (p) { ! 555: if (strcmp(fnam,p->flname) == 0) ! 556: return(p); ! 557: p = p->flnext; ! 558: } ! 559: ! 560: return(NULL); ! 561: } ! 562: /*eject*/ ! 563: chgdot(p) ! 564: ENODE *p; ! 565: { ! 566: register SYMTAB *sym; ! 567: ITEMID add_dot(); ! 568: ! 569: /* ! 570: * This function is called when an assignment is encountered ! 571: * within an output section specification, and the LHS of the ! 572: * assnment is to a symbol other than DOT. Any occurances of ! 573: * DOT within the RHS expression must be replaced by a reference ! 574: * to a dummy symbol table entry, which will have the correct ! 575: * value after the output section is relocated. ! 576: */ ! 577: ! 578: switch(p->gnode.exop) { ! 579: case DOT: ! 580: if( dotacid == 0 ) ! 581: dotacid = add_dot(cur_dot, dotosptr); ! 582: p->nnode.exsymptr = dotacid; ! 583: break; ! 584: case NAME: ! 585: case INT: ! 586: break; ! 587: default: ! 588: if (p->gnode.exleft) ! 589: chgdot(p->gnode.exleft); ! 590: if (p->gnode.exright) ! 591: chgdot(p->gnode.exright); ! 592: } ! 593: } ! 594: /*eject*/ ! 595: add_pad() ! 596: { ! 597: ! 598: /* ! 599: * If the "-B" flag was specified, add any necessary "padding sections" ! 600: * to the outpt file ! 601: */ ! 602: ! 603: register ANODE *ap; /* ptr into avlist */ ! 604: ANODE *newap; /* ptr to padding section node */ ! 605: register OUTSECT *osp; ! 606: register INSECT *isp; ! 607: int no_need_pad, /* = 1 iff don't need padding */ ! 608: counter; /* used to make unique names */ ! 609: char padname[8]; /* padding section name */ ! 610: ! 611: /* ! 612: * Look for an output section which meets one of two conditions: ! 613: * ! 614: * 1. The section is comprised entirely of uninitialized .bss ! 615: * sections ! 616: * 2. The section is of zero length ! 617: * ! 618: * For every output section of these types, add an additional output ! 619: * section immediatly after it. This "padding section" has only two ! 620: * non-zero/non-NULL/non-trivial characteristics: ! 621: * 1. It is composed of Bflag bytes of zero ! 622: * 2. It is written under control of BLOCK(Bflag) ! 623: * ! 624: * Note that padding sections have a virtual/physical address ! 625: * of -1 (to generate errors from any user program or utility ! 626: * attempting to use these values), and flags indicating that ! 627: * it is a padding section ! 628: */ ! 629: ! 630: counter = 0; ! 631: for( ap = (ANODE *) avlist.head; ap; ap = ap->adnext ) { ! 632: if( ap->adtype != ADSECT ) ! 633: continue; ! 634: ! 635: osp = ap->adscnptr; ! 636: no_need_pad = (osp->osflags & FILL); ! 637: for( isp = osp->osinclhd; isp; isp = isp->isincnxt ) ! 638: if( (isp->ishdr.s_scnptr > 0) || (isp->isfillfg) ) ! 639: no_need_pad = 1; ! 640: if( ap->adsize == 0L ) ! 641: no_need_pad = 0; ! 642: ! 643: if( no_need_pad ) ! 644: continue; ! 645: ! 646: osp = (OUTSECT *) myalloc(sizeof(OUTSECT)); ! 647: numoutsc++; ! 648: sprintf( padname, "-pad%2d-", counter++ ); ! 649: copy( osp->oshdr.s_name, padname, 8 ); ! 650: osp->oshdr.s_paddr = -1L; ! 651: osp->oshdr.s_vaddr = -1L; ! 652: osp->oshdr.s_size = Bflag; ! 653: osp->oshdr.s_flags = STYP_PAD; ! 654: osp->osblock = Bflag; ! 655: ! 656: newap = (ANODE *) myalloc(sizeof(ANODE)); ! 657: newap->adtype = ADPAD; ! 658: newap->adsize = Bflag; ! 659: newap->adscnptr = osp; ! 660: ! 661: listins( l_ADR, &avlist, ap, newap ); ! 662: } ! 663: ! 664: #if DEBUG ! 665: if( dflag > 1 ) { ! 666: fprintf( stderr, "\nadd_pad" ); ! 667: dump_mem(); ! 668: } ! 669: #endif ! 670: ! 671: } ! 672: /*eject*/ ! 673: updatsms() ! 674: { ! 675: ! 676: /* ! 677: * After allocation, this function sets ! 678: * 1. The section number of all output sections ! 679: * 2. The virtual addresses of all input sections (isnewvad) ! 680: * 3. The file offset of output sections ! 681: * ! 682: * In addition, the relocated value for all global symbols is ! 683: * computed and stored in the symbol table, along with the new ! 684: * section number. ! 685: * ! 686: * The virtual addresses of output sections are set by ! 687: * audit_regions in allocation. ! 688: */ ! 689: ! 690: register SYMTAB *symp; ! 691: register OUTSECT *osp; ! 692: register INSECT *isp; ! 693: int snum, init; ! 694: long vaddr, indx; ! 695: long filoffst, lnnoptr, nrelocs; ! 696: ANODE *ap; ! 697: INFILE *fp; ! 698: ! 699: /* ! 700: * Compute the starting file offset of the first output section ! 701: * ! 702: * ********** NOTE NOTE NOTE NOTE ********** ! 703: * ! 704: * Increase the size of the optional header by the amount of ! 705: * space needed to generate a patch list ! 706: * ! 707: * ********** NOTE NOTE NOTE NOTE ********** ! 708: */ ! 709: ! 710: hflag += psize(); ! 711: filoffst = (long) FILHSZ + hflag + SCNHSZ * numoutsc; ! 712: ! 713: nrelocs = 0L; ! 714: snum = 0; ! 715: ! 716: for( ap = (ANODE *) avlist.head; ap; ap = ap->adnext ) { ! 717: if (ap->adtype == ADSECT) { ! 718: osp = ap->adscnptr; ! 719: /* ! 720: ***** Special processing ***** ! 721: * ! 722: * The description of the _TV output section is ! 723: * changed, so as to make it equivalent to that ! 724: * section of the transfer vector actually used ! 725: * in this ld run ! 726: * ! 727: * Note that in the default case - no ASSIGN or ! 728: * RANGE commands, the entire transfer vector ! 729: * is used, and hence this code produces no ! 730: * change. ! 731: * ! 732: * When ASSIGN and RANGE commands are present, ! 733: * the actual section of the transfer vector ! 734: * used is typically a subset of the entire ! 735: * vector. Output only the piece used ! 736: */ ! 737: #if TRVEC ! 738: if( tvflag && equal(osp->oshdr.s_name,_TV,8) ) { ! 739: osp->oshdr.s_paddr += ! 740: (tvspec.tvrange[0] * TVENTSZ); ! 741: osp->oshdr.s_vaddr += ! 742: (tvspec.tvrange[0] * TVENTSZ); ! 743: osp->oshdr.s_size = ! 744: ((tvspec.tvrange[1]-tvspec.tvrange[0]+1)*TVENTSZ); ! 745: } ! 746: #endif ! 747: init = (osp->osflags & FILL); /* section is initialized*/ ! 748: osp->ossecnum = ++snum; ! 749: vaddr = osp->oshdr.s_vaddr; ! 750: for( isp = osp->osinclhd; isp; isp = isp->isincnxt ) { ! 751: isp->isnewvad = vaddr + isp->isdispl; ! 752: isp->isnewpad = osp->oshdr.s_paddr + isp->isdispl; ! 753: if (isp->ishdr.s_scnptr > 0 || isp->isfillfg) ! 754: init = 1; ! 755: } ! 756: ! 757: if ((osp->oshdr.s_flags & STYP_NOLOAD) || (osp->oshdr.s_flags & STYP_DSECT)) ! 758: init = 0; ! 759: if (init) { ! 760: filoffst += alignment(osp->osblock,filoffst); ! 761: osp->oshdr.s_scnptr = filoffst; ! 762: filoffst += osp->oshdr.s_size; ! 763: if (rflag) ! 764: nrelocs += (long) osp->oshdr.s_nreloc; ! 765: if (filoffst % 2) ! 766: ++filoffst; ! 767: } ! 768: else ! 769: osp->oshdr.s_scnptr = 0L; ! 770: } ! 771: else if( ap->adtype == ADPAD ) { ! 772: osp = ap->adscnptr; ! 773: osp->ossecnum = ++snum; ! 774: filoffst += alignment(osp->osblock,filoffst); ! 775: osp->oshdr.s_scnptr = filoffst; ! 776: filoffst += osp->oshdr.s_size; ! 777: if( filoffst % 2 ) ! 778: ++filoffst; ! 779: } ! 780: } ! 781: ! 782: /* ! 783: * Do the same for the "dummy" sections (DSECTS) ! 784: */ ! 785: ! 786: for( osp = (OUTSECT *) dsectlst.head; osp; osp = osp->osdsnext ) { ! 787: osp->ossecnum = ++snum; ! 788: for( isp = osp->osinclhd; isp; isp = isp->isincnxt ) { ! 789: isp->isnewvad = osp->oshdr.s_vaddr + isp->isdispl; ! 790: isp->isnewpad = osp->oshdr.s_paddr + isp->isdispl; ! 791: } ! 792: if ( osp->oshdr.s_flags & (STYP_COPY | STYP_INFO)) { ! 793: filoffst += alignment(osp->osblock,filoffst); ! 794: osp->oshdr.s_scnptr = filoffst; ! 795: filoffst += osp->oshdr.s_size; ! 796: if ( rflag ) ! 797: nrelocs += (long) osp->oshdr.s_nreloc; ! 798: if ( filoffst % 2) ! 799: ++filoffst; ! 800: } else { ! 801: osp->oshdr.s_nreloc = 0; ! 802: osp->oshdr.s_nlnno = 0; ! 803: } ! 804: } ! 805: ! 806: /* ! 807: * Loop through sections a 2nd time to set the ! 808: * file pointer to relocation and line numbers for each section ! 809: */ ! 810: ! 811: lnnoptr = filoffst + nrelocs * (long) RELSZ; ! 812: for( ap = (ANODE *) avlist.head; ap; ap = ap->adnext ) { ! 813: if (ap->adtype == ADSECT) { ! 814: osp = ap->adscnptr; ! 815: if (osp->oshdr.s_flags & STYP_NOLOAD) { ! 816: osp->oshdr.s_nreloc = 0; ! 817: osp->oshdr.s_nlnno = 0; ! 818: continue; ! 819: } ! 820: if( rflag && (osp->oshdr.s_nreloc != 0) ) { ! 821: osp->oshdr.s_relptr = filoffst; ! 822: filoffst += ((long)osp->oshdr.s_nreloc * ! 823: (long) RELSZ); ! 824: } ! 825: #if UNIX || XL ! 826: if( (!sflag && !xflag) && (osp->oshdr.s_nlnno != 0) ) { ! 827: #else ! 828: if( (!sflag ) && (osp->oshdr.s_nlnno != 0) ) { ! 829: #endif ! 830: osp->oshdr.s_lnnoptr = lnnoptr; ! 831: lnnoptr += ((long)osp->oshdr.s_nlnno * ! 832: (long) LINESZ); ! 833: } ! 834: } ! 835: } ! 836: ! 837: /* ! 838: * Do the same for the "copy" sections (COPY) ! 839: */ ! 840: ! 841: for( osp = (OUTSECT *) dsectlst.head; osp; osp = osp->osdsnext ) { ! 842: if ( osp->oshdr.s_flags & (STYP_COPY | STYP_INFO)) { ! 843: if ( rflag && (osp->oshdr.s_nreloc != 0) ) { ! 844: osp->oshdr.s_relptr = filoffst; ! 845: filoffst += ((long) osp->oshdr.s_nreloc ! 846: * (long) RELSZ); ! 847: } ! 848: if ( (! sflag) && (osp->oshdr.s_nlnno != 0) ) { ! 849: osp->oshdr.s_lnnoptr = lnnoptr; ! 850: lnnoptr += ((long) osp->oshdr.s_nlnno * ! 851: (long) LINESZ); ! 852: } ! 853: } ! 854: } ! 855: ! 856: symtborg = filoffst = lnnoptr; ! 857: fp = (INFILE *) infilist.head; ! 858: indx = 0; ! 859: while (fp) { ! 860: fp->flsymndx = indx; ! 861: indx += fp->flnlsyms; ! 862: fp = fp->flnext; ! 863: } ! 864: ! 865: symp = NULL; ! 866: while( (symp = loopsym(symp, 1)) != NULL ) { ! 867: if( symp->sment.n_scnum > 0 ) { ! 868: isp = symp->smscnptr; ! 869: symp->sment.n_scnum = isp->isoutsec->ossecnum; ! 870: symp->smnewval = symp->sment.n_value ! 871: + isp->isnewpad - isp->ishdr.s_paddr; ! 872: symp->smnewvirt = symp->smnewval ! 873: - isp->isnewpad + isp->isnewvad; ! 874: if( symp->smlocflg ) { ! 875: symp->smoutndx += isp->isfilptr->flsymndx; ! 876: } ! 877: else { ! 878: symp->smoutndx = indx++; ! 879: indx += symp->sment.n_numaux; ! 880: } ! 881: } ! 882: else { ! 883: if ((symp->sment.n_zeroes == 0) || ! 884: (strncmp( symp->sment.n_name, ".dot", 4 ) != 0)) ! 885: symp->smoutndx = indx++; ! 886: symp->smnewval = symp->sment.n_value; ! 887: symp->smnewvirt = symp->sment.n_value; ! 888: indx += symp->sment.n_numaux; ! 889: } ! 890: } ! 891: #if FLEXNAMES ! 892: tnumsyms = indx; ! 893: #endif ! 894: } ! 895: /*eject*/ ! 896: OUTSECT * ! 897: findoscn(number) ! 898: int number; /* number of desired section */ ! 899: { ! 900: ! 901: /* ! 902: * Look through the output section list, outsclst, ! 903: * for a section with the specified number. Return ! 904: * a pointer to that element of the list. If no ! 905: * section exists with that number, return NULL. ! 906: */ ! 907: ! 908: register OUTSECT *osptr; ! 909: ! 910: osptr = (OUTSECT *) outsclst.head; ! 911: while ( osptr != NULL ) { ! 912: if ( osptr->ossecnum == number ) ! 913: return (osptr); ! 914: osptr = osptr->osnext; ! 915: } ! 916: ! 917: return (NULL); ! 918: } ! 919: /*eject*/ ! 920: split_scns() ! 921: { ! 922: ! 923: /* ! 924: * Run though the output section list. If the size of any output ! 925: * section is greater then MAXSCNSZ, split the output section into ! 926: * two (or more) output sections ! 927: * ! 928: * The name of a new section is the first char of the old name, ! 929: * followed by a number, followed by the rest of the old ! 930: * name. Only eight characters are kept. ! 931: */ ! 932: ! 933: OUTSECT *osp, *newosp, *nxtosp; ! 934: INSECT *isp, *nxtisp; ! 935: char *oldname, newname[20]; /* 8 + 4 + extra */ ! 936: int scnnumber; ! 937: long newdisp, startdisp; /* OUTSECT displacements */ ! 938: ! 939: /* ! 940: * "osp" scans down the outsclst, and "nxtosp" will ! 941: * always point to the next section on the original ! 942: * list. If we have to split osp, the new node ! 943: * will be newosp, and nxtosp will not change. ! 944: */ ! 945: ! 946: for( osp = (OUTSECT *) outsclst.head; osp; osp = nxtosp ) { ! 947: nxtosp = osp->osnext; ! 948: ! 949: /* begin KLUDGE */ ! 950: adjsize(osp); ! 951: /* end KLUDGE */ ! 952: ! 953: if (osp->oshdr.s_flags & STYP_DSECT) ! 954: continue; ! 955: ! 956: if( (osp->osinclhd == osp->osincltl) || (osp->oshdr.s_size <= MAXSCNSZ) ) { ! 957: /* Either there is only one input section in the ! 958: * output section, or the output section is ! 959: * within the permissible size ! 960: */ ! 961: if( (isp = osp->osinclhd) == NULL ) ! 962: continue; ! 963: if( isp->ishdr.s_size > MAXSCNSIZE ) { ! 964: lderror(1,0,NULL, "section %.8s in file %s too big", ! 965: isp->ishdr.s_name, isp->isfilptr->flname); ! 966: osp->osinclhd = osp->osincltl = NULL; ! 967: } ! 968: continue; ! 969: } ! 970: ! 971: /* ! 972: * An output section is too large, and must be split. ! 973: * ! 974: * Walk through the list of input sections, to build ! 975: * two (or more) output sections which are all within ! 976: * the permissible size range ! 977: */ ! 978: ! 979: osp->oshdr.s_nreloc = 0; ! 980: osp->oshdr.s_nlnno = 0; ! 981: isp = osp->osinclhd; ! 982: osp->osinclhd = osp->osincltl = NULL; ! 983: scnnumber = 0; ! 984: oldname = osp->oshdr.s_name; ! 985: ! 986: newdisp = 0L; ! 987: if( isp != NULL ) ! 988: startdisp = osp->oshdr.s_size = isp->isdispl; ! 989: else ! 990: startdisp = osp->oshdr.s_size = 0L; ! 991: ! 992: /* ! 993: * "isp" points to the current input section which we ! 994: * are trying to add to the output section given by ! 995: * "osp" ! 996: */ ! 997: ! 998: for(; isp; isp = nxtisp ) { ! 999: nxtisp = isp->isincnxt; ! 1000: if( osp->oshdr.s_size + isp->ishdr.s_size <= MAXSCNSZ ) { ! 1001: newdisp = isp->isdispl - startdisp; ! 1002: if( osp->oshdr.s_size > newdisp ) ! 1003: lderror(1,0, NULL, ! 1004: "internal error: split_scns, size of %.8s exceeds its new displacement", ! 1005: osp->oshdr.s_name); ! 1006: ! 1007: osp->oshdr.s_size = newdisp; ! 1008: isp->isincnxt = NULL; ! 1009: inscadd(isp, osp); ! 1010: } ! 1011: else if ( osp->oshdr.s_size != 0 ) { ! 1012: nxtisp = isp; /* back up to reprocess */ ! 1013: newosp = (OUTSECT *) myalloc(sizeof(OUTSECT)); ! 1014: numoutsc++; ! 1015: sprintf(newname, "%c%x%.6s", *oldname, ! 1016: scnnumber++, oldname + 1); ! 1017: copy(newosp->oshdr.s_name, newname, 8); ! 1018: newosp->oshdr.s_paddr = -1L; ! 1019: newosp->osnext = osp->osnext; ! 1020: osp->osnext = newosp; ! 1021: if( (OUTSECT *) outsclst.tail == osp ) ! 1022: outsclst.tail = (char *) newosp; ! 1023: osp = newosp; ! 1024: newdisp = 0L; ! 1025: startdisp = isp->isdispl; ! 1026: } ! 1027: else if ( isp->ishdr.s_size <= MAXSCNSIZE ) { ! 1028: isp->isincnxt = NULL; ! 1029: inscadd(isp, osp); ! 1030: } ! 1031: else ! 1032: lderror(1,0,NULL, "section %.8s in file %s is too big", ! 1033: isp->ishdr.s_name, isp->isfilptr->flname); ! 1034: } ! 1035: ! 1036: } ! 1037: ! 1038: } ! 1039: /*eject*/ ! 1040: psize() ! 1041: { ! 1042: /* ! 1043: * Determine the size of the patch list. This is done by looking for ! 1044: * all output sections having the name of ".patchnn", where nn is a ! 1045: * two-digit number ! 1046: * ! 1047: * This routine returns, as an int value, the size of the patch list ! 1048: */ ! 1049: ! 1050: register int index, space; ! 1051: char pname[10]; ! 1052: OUTSECT *fndoutsec(); ! 1053: ! 1054: if( ! pflag ) ! 1055: return( 0 ); ! 1056: else ! 1057: space = sizeof(long); ! 1058: ! 1059: /* ! 1060: * Patch sections, if they exist, must be named consecutively, starting ! 1061: * at ".patch00" ! 1062: */ ! 1063: ! 1064: for( index = 0; index < 100; index++ ) { ! 1065: if (index < 10) ! 1066: sprintf(pname, ".patch0%d", index); ! 1067: else ! 1068: sprintf( pname, ".patch%d", index ); ! 1069: if( fndoutsec(pname) == NULL ) ! 1070: break; ! 1071: space += PESIZE; ! 1072: } ! 1073: ! 1074: return( space ); ! 1075: } ! 1076: /*eject*/ ! 1077: OUTSECT * ! 1078: fndoutsec(nam) ! 1079: char *nam; ! 1080: { ! 1081: register OUTSECT *p, *q; ! 1082: ! 1083: for( p = (OUTSECT *) outsclst.head; p; p=p->osnext ) { ! 1084: if (p->oshdr.s_flags & STYP_GROUP) ! 1085: for( q = (OUTSECT *) p->osinclhd; q; q=q->osnext ) { ! 1086: if (equal(nam,q->oshdr.s_name,8)) ! 1087: return(q); ! 1088: } ! 1089: else ! 1090: if (equal(nam,p->oshdr.s_name,8)) ! 1091: return(p); ! 1092: } ! 1093: return(NULL); ! 1094: } ! 1095: ! 1096: ! 1097: ! 1098: ! 1099: #if ILDOPT ! 1100: add_extra() ! 1101: { ! 1102: ! 1103: /* If the "-ild" flag was specified, add sections to the output file to ! 1104: * cover any remaining configured memory. ! 1105: */ ! 1106: ! 1107: register ANODE *ap, *newap; /* ptr into avlist */ ! 1108: OUTSECT *osp1, *osp2; /* ptrs to the new output section headers */ ! 1109: int counter; /* used to make unique names */ ! 1110: char sectname[9]; /* new section name */ ! 1111: ! 1112: /* For each remaining area of available memory, create a fake output section ! 1113: * that fits in that area. The purpose of this is to cover all of configured ! 1114: * memory so that the incremental ld will be able to determine the memory ! 1115: * configuration. Increase numoutsc to leave room for the .history section ! 1116: * header. ! 1117: */ ! 1118: ! 1119: numoutsc++; ! 1120: counter = 0; ! 1121: for (ap = (ANODE *) avlist.head; ap; ap = ap->adnext) { ! 1122: if (counter > 99) ! 1123: break; ! 1124: if (ap->adtype != ADAVAIL) ! 1125: continue; ! 1126: if ( ap != (ANODE *) avlist.head && ap->adprev->adtype != ADAVAIL && ! 1127: ap->adprev->adscnptr != NULL && ! 1128: (ap->adprev->adscnptr->oshdr.s_flags & STYP_NOLOAD) && ! 1129: ap != (ANODE *) avlist.tail && ap->adnext->adtype != ADAVAIL && ! 1130: ap->adnext->adscnptr != NULL && ! 1131: (ap->adnext->adscnptr->oshdr.s_flags & STYP_NOLOAD) ) ! 1132: continue; ! 1133: ! 1134: ap->adtype = ADSECT; ! 1135: newap = (ANODE *) myalloc( sizeof(ANODE) + 2 * sizeof(OUTSECT)); ! 1136: osp1 = (OUTSECT *) (newap + 1); ! 1137: osp2 = osp1 + 1; ! 1138: numoutsc += 2; ! 1139: if (counter < 10) ! 1140: sprintf(sectname, ".i_l_d0%d", counter++); ! 1141: else ! 1142: sprintf( sectname, ".i_l_d%d", counter++); ! 1143: copy( osp1->oshdr.s_name, sectname, 8 ); ! 1144: osp1->oshdr.s_flags = STYP_DSECT; ! 1145: ap->adscnptr = osp1; ! 1146: ! 1147: if (counter < 10) ! 1148: sprintf( sectname, ".i_l_d0%d", counter++); ! 1149: else ! 1150: sprintf( sectname, ".i_l_d%d", counter++ ); ! 1151: copy( osp2->oshdr.s_name, sectname, 8 ); ! 1152: osp2->oshdr.s_paddr = ap->adpaddr; ! 1153: osp2->oshdr.s_vaddr = ap->adpaddr; ! 1154: osp2->oshdr.s_size = ap->adsize; ! 1155: osp2->oshdr.s_flags = STYP_DSECT; ! 1156: osp2->osflags = 0; ! 1157: ! 1158: newap->adtype = ADSECT; ! 1159: newap->adpaddr = ap->adpaddr; ! 1160: newap->adsize = ap->adsize; ! 1161: newap->adscnptr = osp2; ! 1162: newap->admemp = ap->admemp; ! 1163: newap->adregp = ap->adregp; ! 1164: listins( l_ADR, &avlist, ap, newap ); ! 1165: } ! 1166: } ! 1167: #endif ! 1168: ! 1169: ! 1170: ! 1171: ! 1172: long ! 1173: check_sect( osptr ) ! 1174: OUTSECT *osptr; ! 1175: { ! 1176: ! 1177: /* ! 1178: * check the flags in the output section. if all the input sections are dummy ! 1179: * sections, the output section should be a dummy section. ! 1180: * If no input section was a regular section and one was a copy section ! 1181: * the output will be a copy section. If any input section was an info ! 1182: * section, the output section will have the info flag on. (Most flags ! 1183: * are not mutually exclusive.) ! 1184: * if a bss section is combined with data or text, the bss section is ! 1185: * initialized, and becomes data. ! 1186: * return the size of the section if the output section is not a dummy ! 1187: * (the size is used in allocating space for a group). ! 1188: */ ! 1189: ! 1190: if ((osptr->osflags & OSDSECT) && !(osptr->osflags & OSREG)) { ! 1191: osptr->oshdr.s_flags |= STYP_DSECT; ! 1192: /* remember COPY section also has OSDSECT on */ ! 1193: if (osptr->osflags & OSCOPY) ! 1194: osptr->oshdr.s_flags |= STYP_COPY; ! 1195: } ! 1196: if (osptr->osflags & OSINFO) ! 1197: osptr->oshdr.s_flags |= STYP_INFO; ! 1198: ! 1199: if ((osptr->oshdr.s_flags & STYP_BSS) && ! 1200: ((osptr->oshdr.s_flags & (STYP_TEXT | STYP_DATA)) || ! 1201: (osptr->osflags & FILL))) { ! 1202: osptr->oshdr.s_flags ^= STYP_BSS; ! 1203: osptr->oshdr.s_flags |= STYP_DATA; ! 1204: } ! 1205: ! 1206: if ( !(osptr->oshdr.s_flags & BASIC_TYPES)) ! 1207: if (equal( _TEXT, osptr->oshdr.s_name, 8 )) ! 1208: osptr->oshdr.s_flags |= STYP_TEXT; ! 1209: else if (equal( _DATA, osptr->oshdr.s_name, 8 )) ! 1210: osptr->oshdr.s_flags |= STYP_DATA; ! 1211: else if (equal( _BSS, osptr->oshdr.s_name, 8 )) ! 1212: osptr->oshdr.s_flags |= STYP_BSS; ! 1213: ! 1214: return ((osptr->oshdr.s_flags & STYP_DSECT) ? 0L : osptr->oshdr.s_size); ! 1215: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.