|
|
1.1 ! root 1: static char ID[] = "@(#) syms.c: 1.18 10/5/83"; ! 2: #include "system.h" ! 3: #include <stdio.h> ! 4: #include <fatal.h> ! 5: #include <signal.h> ! 6: #if !NOSDP ! 7: #include "sdp1.h" ! 8: #include "sdpsrc/hd/define2.h" ! 9: #include "sdpsrc/hd/define4.h" ! 10: #include "sdpsrc/hd/struct.h" ! 11: #endif ! 12: #include "structs.h" ! 13: #include "paths.h" ! 14: #include "extrns.h" ! 15: #if TRVEC ! 16: #include "tv.h" ! 17: #include "ldtv.h" ! 18: #endif ! 19: #include "sgsmacros.h" ! 20: #include "instr.h" ! 21: #include "ldmacros.h" ! 22: ! 23: ! 24: ! 25: /* ! 26: * ***** NOTICE ***** NOTICE ***** NOTICE ******* ! 27: * * ! 28: * This version of syms.c is designed to * ! 29: * permit multiple aux entries per symbol * ! 30: * * ! 31: * This version of syms.c uses a one-way * ! 32: * circular list to link all symbols that * ! 33: * hash to the same hashtab[] entry * ! 34: * * ! 35: * ***** NOTICE ***** NOTICE ***** NOTICE ******* ! 36: */ ! 37: ! 38: #if NOSDP && !UNIX ! 39: #define HASHSIZE 1021 ! 40: #else ! 41: #define HASHSIZE 521 ! 42: #endif ! 43: /* ! 44: * VAX cc bug KLUDGE ! 45: */ ! 46: #define abs(x) (x < 0 ? -x : x) ! 47: ! 48: ITEMID hashtab[HASHSIZE]; ! 49: ! 50: #if NOSDP ! 51: #if UNIX ! 52: #define MAXEXTRA 100 ! 53: #define XSMTBSZ 100 ! 54: #define XAXTBSZ 50 ! 55: #define MYSMTBSZ 200 ! 56: #define MYAXTBSZ 100 ! 57: #else ! 58: #if AR16WR ! 59: #define MAXEXTRA 20 ! 60: #define XSMTBSZ 80 ! 61: #define XAXTBSZ 40 ! 62: #define MYSMTBSZ 400 ! 63: #define MYAXTBSZ 200 ! 64: #endif ! 65: #if AR32W ! 66: #define MAXEXTRA 100 ! 67: #define XSMTBSZ 800 ! 68: #define XAXTBSZ 400 ! 69: #define MYSMTBSZ 4000 ! 70: #define MYAXTBSZ 2000 ! 71: #endif ! 72: #if AR32WR ! 73: #define MAXEXTRA 10 ! 74: #define XSMTBSZ 400 ! 75: #define XAXTBSZ 200 ! 76: #define MYSMTBSZ 2000 ! 77: #define MYAXTBSZ 1000 ! 78: #endif ! 79: #endif ! 80: int xsymcnt = 0; ! 81: int xauxcnt = 0; ! 82: SYMTAB *xsymptr[MAXEXTRA]; ! 83: AUXTAB *xauxptr[MAXEXTRA]; ! 84: SYMTAB mysymtab[MYSMTBSZ+1]; ! 85: AUXTAB myauxtab[MYAXTBSZ+1]; ! 86: #else ! 87: extern HEADER global_frames[MAXATTACH]; ! 88: static char sdpname[sizeof(TMPDIR)+20] = ""; ! 89: static char auxname[sizeof(TMPDIR)+20] = ""; ! 90: ! 91: static int sdp_called = 0; /* indicates when syminit() has been called */ ! 92: static int aux_called = 0; /* indicates when auxinit() has been called */ ! 93: /*eject*/ ! 94: syminit() ! 95: { ! 96: ! 97: /* ! 98: * Initialize the Software Demand Paging System ! 99: */ ! 100: ! 101: if( sdp_called ) ! 102: lderror(2,0,NULL,"Attempt to re-initialize SDP symbol space"); ! 103: ! 104: sprintf( sdpname, "%s/%s", TMPDIR, "ldXXXXXX" ); ! 105: mktemp( sdpname ); ! 106: ! 107: sdp_called++; ! 108: ! 109: if( sdpinit(sdpname, CREATE, SYMSPACE) != SYMSPACE ) ! 110: lderror(2,0,NULL,"Failed to initialize SDP symbol space"); ! 111: else ! 112: sdp_called++; ! 113: ! 114: auxinit(); /* initialize aux entry space */ ! 115: } ! 116: ! 117: ! 118: ! 119: symfini() ! 120: { ! 121: char buf[sizeof(sdpname)*2 + 20]; ! 122: ! 123: /* ! 124: * Ignore BREAK, HANGUP, and QUIT signals, to insure that the cleanup ! 125: * is done ! 126: */ ! 127: ! 128: signal(SIGINT, SIG_IGN); ! 129: signal(SIGQUIT, SIG_IGN); ! 130: ! 131: if( sdp_called == 2 ) { ! 132: sdp_called--; ! 133: if( sdpterm(SYMSPACE) < 0 ) ! 134: lderror(2,0,NULL,"Failed to close SDP symbol space"); ! 135: } ! 136: ! 137: if( sdp_called != 1 ) ! 138: return; ! 139: sdp_called--; ! 140: ! 141: #if TS || RT ! 142: sprintf(buf, "rm -r %s", sdpname); ! 143: #else ! 144: sprintf(buf, "rm -r %s; rmdir %s", sdpname, sdpname); ! 145: #endif ! 146: ! 147: if( fork() == 0 ) { ! 148: execl("/bin/sh", "sh", "-c", buf, 0); ! 149: lderror(0,0,NULL, "Execl(%s) failed", buf); ! 150: _exit(127); ! 151: } ! 152: ! 153: auxfini(); /* close aux entry space */ ! 154: } ! 155: /*eject*/ ! 156: #endif ! 157: hash(name) ! 158: register char *name; ! 159: { ! 160: ! 161: /* ! 162: * Compute hash value for a symbol name ! 163: */ ! 164: ! 165: register unsigned hashval; ! 166: register int tmp; /* VAX CC BUG KLUDGE */ ! 167: ! 168: hashval = 0; ! 169: while (*name) ! 170: hashval = hashval * 10 + *name++; /*used to be 13*/ ! 171: ! 172: /* ! 173: * Because of a bug in the current VAX compiler, the following ! 174: * line has temporarily been replaced by the KLUDGE following ! 175: * this comment. The define of abs() is also added above ! 176: * ! 177: * return( (int) (hashval % HASHSIZE) ); ! 178: */ ! 179: ! 180: tmp = (int) hashval; ! 181: tmp = abs(tmp); ! 182: return ( tmp % HASHSIZE ); ! 183: } ! 184: /*eject*/ ! 185: SYMTAB * ! 186: findsym(name) ! 187: char *name; ! 188: { ! 189: ! 190: /* ! 191: * Return a pointer to the ld symbol table entry for a symbol. ! 192: * ! 193: * NULL indicates that the symbol does not exist ! 194: */ ! 195: ! 196: register SYMTAB *p; /* ld symbol table entry */ ! 197: register int chain; /* size of a collision chain */ ! 198: int hashval; /* hashtab[] index for the sym */ ! 199: register ITEMID acid, /* SDP id for ld symbol entry */ ! 200: base; /* head of collision chain */ ! 201: ! 202: ! 203: /* ! 204: * All symbols that hash to the same value are connected in a one-way, ! 205: * circular linked list. The most recently referenced symbol on ! 206: * the chain is considered the head of the chain, and its id is ! 207: * stored in the hash table ! 208: * ! 209: * Get the head of the collision chain, and walk down it looking for ! 210: * a match ! 211: */ ! 212: ! 213: hashval = hash(name); ! 214: if( (acid = hashtab[hashval]) == 0 ) ! 215: return( NULL ); ! 216: base = acid; ! 217: chain = 1; ! 218: ! 219: do { ! 220: char sym_space[9]; ! 221: char *sym_name; ! 222: #if NOSDP ! 223: p = getsym(acid); ! 224: #else ! 225: p = (SYMTAB *) lock(acid, MISPARTITION, RNLY); ! 226: #endif ! 227: if (p->smnamelength == 9) ! 228: { ! 229: strncpy( sym_space, p->sment.n_name, 8 ); ! 230: sym_space[8] = '\0'; ! 231: sym_name = sym_space; ! 232: } ! 233: #if FLEXNAMES ! 234: else if (p->smnamelength > 9) ! 235: sym_name = p->sment.n_nptr; ! 236: #endif ! 237: else ! 238: sym_name = p->sment.n_name; ! 239: ! 240: if (equal( sym_name, name, p->smnamelength )) ! 241: { ! 242: maxchain = max(maxchain,chain); ! 243: nwalks += (chain - 1); ! 244: hashtab[hashval] = acid; ! 245: return( p ); ! 246: } ! 247: #if !NOSDP ! 248: unlock(acid, RNLY); ! 249: #endif ! 250: ! 251: acid = p->smchainid; ! 252: chain++; ! 253: ! 254: } ! 255: while( acid != base ); ! 256: ! 257: nfwalks += (chain - 1); ! 258: ! 259: return( NULL ); /* not found */ ! 260: } ! 261: /*eject*/ ! 262: AUXTAB * ! 263: findaux(sym, ndx) ! 264: SYMTAB *sym; ! 265: int ndx; ! 266: { ! 267: ! 268: /* ! 269: * Return a pointer to the ndx'th aux entry for the ld symbol table ! 270: * entry given by sym ! 271: * ! 272: * NULL indicates that no such aux entry exists ! 273: */ ! 274: ! 275: register AUXTAB *a; /* pointer to a symbol aux entry*/ ! 276: ITEMID acid; /* SDP id for ld aux entry */ ! 277: ! 278: #if DEBUG ! 279: if( dflag > 15 ) ! 280: fprintf( stderr, "\nfindaux %s ", SYMNAME( sym->sment )); ! 281: #endif ! 282: ! 283: /* ! 284: * All aux entries belonging to a symbol are linked together in a ! 285: * one-way linked list. The entries are ordered by aux-entry ! 286: * number: the first aux entry is the head of the list; it is ! 287: * linked to the 2'nd aux entry, which is linked to the 3'rd, etc ! 288: * ! 289: * Get the head of the aux entry list, and walk down it looking for ! 290: * the specified aux entry ! 291: */ ! 292: ! 293: acid = sym->smauxid; ! 294: ! 295: while( acid != 0 ) { ! 296: ! 297: #if NOSDP ! 298: a = getaux(acid); ! 299: #else ! 300: a = (AUXTAB *) lock(acid, MISPARTITION, RNLY); ! 301: #endif ! 302: ! 303: if( a->axord == ndx ) ! 304: return( a ); ! 305: #if !NOSDP ! 306: unlock(acid, RNLY); ! 307: #endif ! 308: ! 309: acid = a->axchainid; ! 310: ! 311: } ! 312: ! 313: return( NULL ); /* not found */ ! 314: } ! 315: /*eject*/ ! 316: SYMTAB * ! 317: makesym(sym, filp) ! 318: register SYMENT *sym; ! 319: INFILE *filp; ! 320: { ! 321: ! 322: /* ! 323: * Given a (new) *.o symbol table entry, add it to the ld ! 324: * symbol table ! 325: * ! 326: * A ld symbol table entry is built and initialized. Appropriate ! 327: * entries are made in the hash table and in the SDP address space ! 328: * ! 329: * The address of the ld symbol table entry is returned ! 330: */ ! 331: ! 332: register SYMTAB *p; /* pointer to a ld symbol entry */ ! 333: register ITEMID acid; /* SDP id of a ld symbol entry */ ! 334: int hashval; /* index into hash table for sym*/ ! 335: int auxcnt; ! 336: char *name; ! 337: ! 338: name = PTRNAME( sym ); ! 339: if( (p = findsym(name)) == NULL ) { ! 340: /* ! 341: * Case 1: The symbol is not in the ld symbol table. ! 342: * Add a new entry, making it the head of the ! 343: * collision chain ! 344: * Update the hash table ! 345: */ ! 346: #if NOSDP ! 347: if (numldsyms >= MYSMTBSZ + (xsymcnt * XSMTBSZ)) { ! 348: if (xsymcnt >= MAXEXTRA) ! 349: lderror(2,0,"internal error: ","symbol table overflow"); ! 350: xsymptr[xsymcnt++] = (SYMTAB *) myalloc(XSMTBSZ * SYMSIZ); ! 351: } ! 352: acid = ++numldsyms; ! 353: p = getsym(acid); ! 354: #else ! 355: numldsyms++; ! 356: acid = allocate(SYMSIZ, SYMSPACE, MISPARTITION); ! 357: p = (SYMTAB *) lock(acid, MISPARTITION, WRTN); ! 358: zero( p, SYMSIZ ); ! 359: #endif ! 360: p->sment = *sym; ! 361: p->smnamelength = strlen( name ) + 1; ! 362: #if FLEXNAMES ! 363: if ((sym->n_zeroes == 0L) && ((filp == NULL) ! 364: || (filp && (filp->flstrings == NULL)))) ! 365: p->sment.n_nptr = savefn(sym->n_nptr); ! 366: #endif ! 367: p->sment.n_numaux = 0; ! 368: p->smmyacid = acid; ! 369: ! 370: hashval = hash(name); ! 371: if( hashtab[hashval] > 0 ) { ! 372: SYMTAB *p2; ! 373: #if NOSDP ! 374: p2 = getsym(hashtab[hashval]); ! 375: #else ! 376: p2 = (SYMTAB *) lock(hashtab[hashval], HITPARTITION, WRTN); ! 377: #endif ! 378: p->smchainid = p2->smchainid; ! 379: p2->smchainid = acid; ! 380: #if !NOSDP ! 381: unlock(hashtab[hashval], WRTN); ! 382: #endif ! 383: ncolisns++; ! 384: } ! 385: else ! 386: p->smchainid = acid; ! 387: ! 388: hashtab[hashval] = acid; ! 389: return( p ); ! 390: } ! 391: ! 392: /* ! 393: * Case 2: The symbol is already in the symbol table ! 394: * Update the existing entry ! 395: */ ! 396: ! 397: if( sym->n_scnum != 0 ) { ! 398: /* ! 399: * The makesym() argument 'sym' is the defining entry ! 400: * for the symbol ! 401: */ ! 402: if( p->sment.n_scnum == 0 ) { ! 403: ! 404: /* ! 405: * The existing ld symbol table entry ! 406: * was from a reference ! 407: * ! 408: * Merge the information from the function ! 409: * argument and the ld symbol table ! 410: * ! 411: * The ld symbol table entry may have a ld- ! 412: * generated aux entry. If so, carry this ! 413: * entry over. ! 414: */ ! 415: #if COMMON ! 416: if (Mflag && p->sment.n_value > 0) ! 417: lderror(0,0,NULL, "Symbol %s in %s is multiply defined.", ! 418: name,curfilnm ); ! 419: #endif ! 420: p->sment.n_value = sym->n_value; ! 421: p->sment.n_scnum = sym->n_scnum; ! 422: p->sment.n_type = sym->n_type; ! 423: p->sment.n_sclass = sym->n_sclass; ! 424: } ! 425: else if( p->sment.n_scnum != -1 ) ! 426: lderror(1,0,NULL, "Symbol %s in %s is multiply defined. First defined in %s", ! 427: name, curfilnm, p->smscnptr->isfilptr->flname ); ! 428: } ! 429: ! 430: #if COMMON ! 431: else if (sym->n_value > 0) /* & sym->n_scnum == 0 => common sym */ ! 432: { ! 433: if (Mflag && (p->sment.n_scnum != 0 || ! 434: (p->sment.n_scnum == 0 && p->sment.n_value > 0))) ! 435: lderror(0, 0, NULL, "Symbol %s in %s is multiply defined.", ! 436: name, curfilnm); ! 437: ! 438: /* set value for .common symbol */ ! 439: ! 440: if ( p->sment.n_scnum == N_UNDEF ) ! 441: { ! 442: if ( !tflag && ( p->sment.n_value > 0 ) ! 443: && ( p->sment.n_value != sym->n_value )) ! 444: { ! 445: lderror(0, 0, NULL, ! 446: "Multiply defined symbol %s, in %s, has more than one size", ! 447: PTRNAME(sym), curfilnm); ! 448: } ! 449: ! 450: p->sment.n_value = /* max of old & new val */ ! 451: (p->sment.n_value > sym->n_value) ? ! 452: p->sment.n_value : sym->n_value; ! 453: ! 454: if (sym->n_type != T_NULL && p->sment.n_type == T_NULL) ! 455: p->sment.n_type = sym->n_type; ! 456: } ! 457: } ! 458: #endif ! 459: return( p ); ! 460: } ! 461: /*eject*/ ! 462: AUXTAB * ! 463: makeaux(sym, aux, ndx) ! 464: register SYMTAB *sym; /* symbol table entry to which the aux entry belongs */ ! 465: register AUXENT *aux; /* new aux entry */ ! 466: int ndx; /* number of aux entries already added to entry */ ! 467: { ! 468: ! 469: /* ! 470: * Given a (*.o) aux entry, add it to an existing ld symbol ! 471: * table entry ! 472: * ! 473: * The address of the ld aux entry is returned ! 474: */ ! 475: ! 476: register AUXTAB *a; ! 477: register int tvndx; ! 478: ITEMID acid; ! 479: ! 480: #if DEBUG ! 481: if( dflag > 15 ) ! 482: fprintf( stderr, "\nmakeaux %s ", SYMNAME( sym->sment ) ); ! 483: else if( dflag > 2 ) ! 484: fprintf(stderr, "makeaux: %s (%d) : %08lx %04x %04x %08lx %08lx %04x\n", ! 485: SYMNAME(sym->sment), ndx, ! 486: aux->x_sym.x_tagndx, aux->x_sym.x_misc.x_lnsz.x_lnno, ! 487: aux->x_sym.x_misc.x_lnsz.x_size, ! 488: aux->x_sym.x_fcnary.x_fcn.x_lnnoptr, ! 489: aux->x_sym.x_fcnary.x_fcn.x_endndx, ! 490: aux->x_sym.x_tvndx); ! 491: #endif ! 492: ! 493: /* ! 494: * Add the new aux entry to the symbol table entry ! 495: */ ! 496: ! 497: if( (acid = sym->smauxid) == 0 ) { ! 498: /* ! 499: * Add the first aux entry for a symbol ! 500: */ ! 501: if( ndx != 0 ) ! 502: lderror(1,0,NULL,"Making aux entry %d for symbol %s out of sequence", ! 503: ndx+1, SYMNAME( sym->sment )); ! 504: #if NOSDP ! 505: if (numldaux >= MYAXTBSZ + (xauxcnt * XAXTBSZ)) { ! 506: if (xauxcnt >= MAXEXTRA) ! 507: lderror(2,0,"internal error: ","aux table overflow"); ! 508: xauxptr[xauxcnt++] = (AUXTAB *) myalloc(XAXTBSZ * AUXSIZ); ! 509: } ! 510: acid = ++numldaux; ! 511: a = getaux(acid); ! 512: #else ! 513: numldaux++; ! 514: acid = allocate(AUXSIZ, AUXSPACE, MISPARTITION); ! 515: a = (AUXTAB *) lock(acid, MISPARTITION, WRTN); ! 516: ! 517: zero( a, AUXSIZ ); ! 518: #endif ! 519: a->axent = *aux; ! 520: a->axord = 1; ! 521: a->axmyacid = acid; ! 522: a->axchainid = 0; ! 523: ! 524: sym->sment.n_numaux++; ! 525: sym->smauxid = acid; ! 526: ! 527: return( a ); ! 528: } ! 529: ! 530: #if NOSDP ! 531: a = getaux(acid); ! 532: #else ! 533: a = (AUXTAB *) lock(acid, MISPARTITION, WRTN); ! 534: #endif ! 535: ! 536: ! 537: if( ndx == 0 ) { ! 538: /* ! 539: * The symbol table entry already has a aux entry. ! 540: * ! 541: * This occurs when ld generates an aux entry for ! 542: * the symbol, to contain a tv slot index. ! 543: * ! 544: * Merge this ld-entry with the entry obtained from ! 545: * the input file ! 546: * ! 547: * Two cases: due to a tv ref in an earlier ! 548: * input file, the aux entry in the symbol ! 549: * table is a dummy one and should be ! 550: * overwritten except for the tvndx. ! 551: * ! 552: * (2) we are doing subsystem linking and ! 553: * we are getting dummy and real auxents ! 554: * in an unknown order. in this case ! 555: * we have to test to see which one is ! 556: * the dummy and either overwrite it ! 557: * or throw it away. We have this info ! 558: * in psymtab() and should be an arg ! 559: * to makeaux(). However a KLUDGE is ! 560: * to see which one is all 0's except ! 561: * for the tvndx and call that one the ! 562: * dummy. This should be cleaned up ! 563: * and made reasonable later. ! 564: */ ! 565: ! 566: /* if incoming is not dummy */ ! 567: if ( ! ( (aux->x_sym.x_tagndx == 0L) && ! 568: (aux->x_sym.x_misc.x_fsize == 0L) && ! 569: (aux->x_sym.x_fcnary.x_fcn.x_lnnoptr == 0L) && ! 570: (aux->x_sym.x_fcnary.x_fcn.x_endndx == 0L) ) ) { ! 571: tvndx = a->axent.x_sym.x_tvndx; ! 572: a->axent = *aux; ! 573: if (tvndx != N_TV) ! 574: a->axent.x_sym.x_tvndx = tvndx; ! 575: } ! 576: ! 577: return( a ); ! 578: } ! 579: ! 580: /* ! 581: * Step down the chain of aux entries, to the correct position for the ! 582: * new entry ! 583: */ ! 584: ! 585: while( a->axord != ndx ) { ! 586: #if NOSDP ! 587: acid = a->axchainid; ! 588: a = getaux(acid); ! 589: #else ! 590: unlock(acid, RNLY); ! 591: acid = a->axchainid; ! 592: a = (AUXTAB *) lock(acid, MISPARTITION, RNLY); ! 593: #endif ! 594: } ! 595: ! 596: if( a->axchainid != 0 ) { ! 597: /* ! 598: * Overwriting an existing aux entry (but not the first aux ! 599: * entry). Warn the user ! 600: */ ! 601: lderror(0,0,NULL,"Overwriting aux entry %d of symbol %s", ! 602: ndx+1, SYMNAME( sym->sment )); ! 603: ! 604: #if NOSDP ! 605: acid = a->axchainid; ! 606: a = getaux(acid); ! 607: #else ! 608: unlock(acid, RNLY); ! 609: acid = a->axchainid; ! 610: a = (AUXTAB *) lock(acid, MISPARTITION, WRTN); ! 611: #endif ! 612: ! 613: a->axent = *aux; ! 614: ! 615: return( a ); ! 616: } ! 617: else { ! 618: /* ! 619: * Add the new aux entry at the end of the list ! 620: */ ! 621: #if NOSDP ! 622: if (numldaux >= MYAXTBSZ + (xauxcnt * XAXTBSZ)) { ! 623: if (xauxcnt >= MAXEXTRA) ! 624: lderror(2,0,"internal error: ","aux table overflow"); ! 625: xauxptr[xauxcnt++] = (AUXTAB *) myalloc(XAXTBSZ * AUXSIZ); ! 626: } ! 627: acid = a->axchainid = ++numldsyms; ! 628: a = getaux(acid); ! 629: #else ! 630: numldaux++; ! 631: a->axchainid = allocate(AUXSIZ, AUXSPACE, MISPARTITION); ! 632: unlock(acid, WRTN); ! 633: acid = a->axchainid; ! 634: a = (AUXTAB *) lock(acid, MISPARTITION, WRTN); ! 635: ! 636: zero( a, AUXSIZ ); ! 637: #endif ! 638: a->axent = *aux; ! 639: a->axord = ndx + 1; ! 640: a->axmyacid = acid; ! 641: a->axchainid = 0; ! 642: ! 643: sym->sment.n_numaux++; ! 644: ! 645: return( a ); ! 646: } ! 647: } ! 648: ! 649: ITEMID ! 650: putsym(sym, changed) ! 651: SYMTAB *sym; ! 652: int changed; ! 653: { ! 654: ! 655: /* ! 656: * Return a ld symbol table entry to the SDP empire ("unlock") ! 657: * Return the SDP access ID ! 658: */ ! 659: ! 660: #if DEBUG ! 661: if( dflag > 15 ) ! 662: fprintf( stderr, "\n putsym %s ", SYMNAME( sym->sment )); ! 663: #endif ! 664: ! 665: #if !NOSDP ! 666: unlock(sym->smmyacid, (changed ? WRTN : RNLY)); ! 667: #endif ! 668: return( sym->smmyacid ); ! 669: } ! 670: ! 671: ! 672: ITEMID ! 673: putaux(aux, changed) ! 674: AUXTAB *aux; ! 675: int changed; ! 676: { ! 677: ! 678: /* ! 679: * Return an auxiliary entry to the SDP empire ("unlock") ! 680: * ! 681: * Return the SDP access ID ! 682: */ ! 683: ! 684: #if DEBUG ! 685: if( dflag > 15 ) ! 686: fprintf( stderr, "\n putaux %8lx ", aux->axmyacid ); ! 687: #endif ! 688: ! 689: #if !NOSDP ! 690: unlock(aux->axmyacid, (changed ? WRTN : RNLY)); ! 691: #endif ! 692: return( aux->axmyacid ); ! 693: } ! 694: ! 695: ! 696: ! 697: SYMTAB * ! 698: getsym(acid) ! 699: register ITEMID acid; ! 700: { ! 701: ! 702: /* ! 703: * Return a pointer to an ld symbol table entry, given the ! 704: * SDP access ID ! 705: */ ! 706: ! 707: #if DEBUG ! 708: if( dflag > 15 ) ! 709: fprintf( stderr, "\n getsym %8lx ", acid ); ! 710: #endif ! 711: ! 712: #if NOSDP ! 713: if (acid <= 0) ! 714: lderror(2,0,"internal error: ","negative symbol table id"); ! 715: if (acid <= MYSMTBSZ) ! 716: return(&mysymtab[acid]); ! 717: acid -= (MYSMTBSZ + 1); ! 718: if (acid < xsymcnt * XSMTBSZ) ! 719: return( (SYMTAB *) ( (long) xsymptr[acid/XSMTBSZ] + ((acid % XSMTBSZ) * SYMSIZ)) ); ! 720: lderror(2,0,"internal error: ","invalid symbol table id"); ! 721: #else ! 722: return( (SYMTAB *) lock(acid, MISPARTITION, RNLY) ); ! 723: #endif ! 724: } ! 725: ! 726: AUXTAB * ! 727: getaux(acid) ! 728: ITEMID acid; ! 729: { ! 730: ! 731: /* ! 732: * Return a pointer to a ld aux entry, given the ! 733: * SDP access ID ! 734: */ ! 735: ! 736: #if DEBUG ! 737: if( dflag > 15 ) ! 738: fprintf( stderr, "\n getaux %8lx ", acid ); ! 739: #endif ! 740: ! 741: #if NOSDP ! 742: if (acid <= 0) ! 743: lderror(2,0,"internal error: ","negative aux table id"); ! 744: if (acid <= MYAXTBSZ) ! 745: return(&myauxtab[acid]); ! 746: acid -= (MYAXTBSZ + 1); ! 747: if (acid < xauxcnt * XAXTBSZ) ! 748: return( (AUXTAB *) ( (long) xauxptr[acid/XAXTBSZ] + ((acid % XAXTBSZ) * AUXSIZ)) ); ! 749: lderror(2,0,"internal error: ","invalid aux table id"); ! 750: #else ! 751: return( (AUXTAB *) lock(acid, MISPARTITION, RNLY) ); ! 752: #endif ! 753: } ! 754: /*eject*/ ! 755: long ! 756: #if FLEXNAMES ! 757: psymtab(fdes, numsyms, filp, symbuf,strtabptr) ! 758: char *strtabptr; /* pointer to string table with long symbol names, if ! 759: one exists */ ! 760: #else ! 761: psymtab(fdes, numsyms, filp, symbuf, strtabptr) ! 762: #endif ! 763: FILE *fdes; /* pointer to the file, positioned to the symbol table */ ! 764: long numsyms; /* total number of symbol table entries for the file */ ! 765: INFILE *filp; /* pointer to the infilist entry for the file */ ! 766: register SYMENT *symbuf; ! 767: { ! 768: ! 769: /* ! 770: * This routine is called during the scanning of the LDFILE list. ! 771: * ! 772: * Every *.o and archive library member which is to be link edited ! 773: * is processed exactly once by this function: ! 774: * ! 775: * 1. Add all ld symbols from the file to ld's cumulative ! 776: * ld symbol table ! 777: * ********** for FLEXNAMES *********** ! 778: * 1a. When there is a long symbol name, change the ! 779: * offset of the name in the symbol table to a pointer ! 780: * to the name ! 781: * ************************************ ! 782: * 2. Compute and return the number of local symbol table ! 783: * entries (locals, statics, functions, etc.) for this ! 784: * file ! 785: */ ! 786: ! 787: ! 788: register SYMENT *sym; /* input file symbol table entry */ ! 789: register AUXENT *aux; /* symbol aux entry */ ! 790: register SYMTAB *symp; /* ld symbol table entry pointer */ ! 791: register long n; ! 792: long locsyms, /* nbr local symbols from input file */ ! 793: relsyms, /* nbr relocatable symbols */ ! 794: l; ! 795: int i; /* for-loop index */ ! 796: char tmp_numaux, ! 797: tmp_sclass; ! 798: SYMENT lsymbuf; ! 799: AUXENT lauxbuf; ! 800: ! 801: sym = &lsymbuf; ! 802: aux = &lauxbuf; ! 803: ! 804: locsyms = 0L; ! 805: relsyms = 0L; ! 806: ! 807: for( n = 0L; n < numsyms; n++ ) { ! 808: ! 809: #if !PORTAR && !PORT5AR ! 810: if (symbuf != NULL) ! 811: sym = symbuf++; ! 812: else ! 813: #endif ! 814: if (fread(sym,SYMESZ,1,fdes) != 1) ! 815: lderror(2,0,NULL,"fail to read symbol table of file %s", ! 816: filp->flname); ! 817: ! 818: #if FLEXNAMES ! 819: /* this symbol has a long name - change offset to ptr */ ! 820: if (sym->n_zeroes == 0L) ! 821: { ! 822: if (strtabptr == NULL) ! 823: lderror( 2, 90, NULL, "no string table in file %s", filp->flname ); ! 824: sym->n_nptr = strtabptr + sym->n_offset; ! 825: } ! 826: #endif ! 827: ! 828: switch( sym->n_sclass ) { ! 829: ! 830: /* ! 831: * Symbols of type C_EXT are global, and must be added ! 832: * to ld's cumulative symbol table ! 833: */ ! 834: case C_EXT: ! 835: relsyms++; ! 836: symp = makesym(sym, filp); ! 837: ! 838: if( sym->n_scnum > 0 ) ! 839: symp->smscnptr = sectnum(sym->n_scnum,filp); ! 840: ! 841: ! 842: /* ! 843: * Functions, although added to ld's symbol ! 844: * table, must be put in the "local symbol" ! 845: * section of the final output file ! 846: */ ! 847: if( ISFCN(sym->n_type) ) { ! 848: symp->smoutndx = locsyms; ! 849: locsyms += (long) (sym->n_numaux + 1); ! 850: symp->smlocflg = 1; ! 851: } ! 852: ! 853: n += (long) sym->n_numaux; ! 854: tmp_numaux = sym->n_numaux; ! 855: for( i = 0; i < tmp_numaux; i++ ) { ! 856: #if !PORTAR && !PORT5AR ! 857: if (symbuf != NULL) ! 858: aux = (AUXENT *) symbuf++; ! 859: else ! 860: #endif ! 861: if (fread(aux,AUXESZ,1,fdes) != 1) ! 862: lderror(2,0,NULL,"fail to read aux entries of file %s", ! 863: filp->flname); ! 864: ! 865: #if TRVEC ! 866: if ( i == 0 && (ISFCN( sym->n_type ) || (sym->n_type == 0))) ! 867: if (aux->x_sym.x_tvndx == N_TV) { ! 868: aux->x_sym.x_tvndx = P_TV; ! 869: tvspec.tvosptr->oshdr.s_size += TVENTSZ; ! 870: } ! 871: #endif ! 872: putaux( makeaux(symp, aux, i), 1 ); ! 873: } ! 874: ! 875: PUTSYM(symp, 1); ! 876: break; ! 877: ! 878: case C_FILE: ! 879: #if DMERT || XL ! 880: if (!dmertplib) ! 881: #endif ! 882: locsyms += 1 + (long) sym->n_numaux; ! 883: if (sym->n_numaux) { ! 884: n += sym->n_numaux; ! 885: #if !PORTAR && !PORT5AR ! 886: if (symbuf != NULL) ! 887: symbuf++; ! 888: else ! 889: #endif ! 890: if (fseek( fdes, (long) (AUXESZ) * sym->n_numaux, 1 ) != 0) ! 891: lderror( 2, 0, NULL, "fail to skip aux entry of %s", filp->flname); ! 892: } ! 893: break; ! 894: ! 895: case C_STAT: ! 896: #if UNIX ! 897: relsyms++; ! 898: locsyms += 1 + sym->n_numaux; ! 899: if (sym->n_numaux == 1) { ! 900: n++; ! 901: #if !PORTAR && !PORT5AR ! 902: if (symbuf != NULL) ! 903: symbuf++; ! 904: else ! 905: #endif ! 906: if (fseek( fdes, (long) AUXESZ, 1 ) != 0) ! 907: lderror( 2, 0, NULL, "fail to skip the aux entry of %s", filp->flname); ! 908: }; ! 909: continue; ! 910: #endif ! 911: ! 912: case C_HIDDEN: ! 913: relsyms++; ! 914: ! 915: default: ! 916: #if DMERT || XL ! 917: if (!dmertplib) ! 918: #endif ! 919: #if UNIX || XL ! 920: if (!xflag) ! 921: #endif ! 922: locsyms++; ! 923: ! 924: if( sym->n_numaux > 0 ) { ! 925: ! 926: #if DMERT || XL ! 927: if (!dmertplib) ! 928: #endif ! 929: #if UNIX || XL ! 930: if (!xflag) ! 931: #endif ! 932: locsyms += (long) sym->n_numaux; ! 933: n += (long) sym->n_numaux; ! 934: tmp_sclass = sym->n_sclass; ! 935: tmp_numaux = sym->n_numaux; ! 936: #if !PORTAR && !PORT5AR ! 937: if (symbuf != NULL) ! 938: aux = (AUXENT *) symbuf++; ! 939: else ! 940: #endif ! 941: if (fread(aux,AUXESZ,1,fdes) != 1) ! 942: lderror(2,0,NULL,"fail to read aux entries of %s", ! 943: filp->flname); ! 944: ! 945: /* ! 946: * Skip all aux entries after the first ! 947: */ ! 948: if( tmp_numaux > 1 ) ! 949: #if !PORTAR && !PORT5AR ! 950: if (symbuf != NULL) ! 951: symbuf++; ! 952: else ! 953: #endif ! 954: if (fseek(fdes, (long) (AUXESZ * (tmp_numaux-1)), 1) != 0) ! 955: lderror(2,0,NULL,"fail to skip the aux entry of %s", ! 956: filp->flname); ! 957: ! 958: /* ! 959: * Skip all members of structures and ! 960: * unions ! 961: */ ! 962: if( ISTAG(tmp_sclass) ) { ! 963: l = aux->x_sym.x_fcnary.x_fcn.x_endndx - n - 1; ! 964: #if DMERT || XL ! 965: if (!dmertplib) ! 966: #endif ! 967: #if UNIX || XL ! 968: if (!xflag) ! 969: #endif ! 970: locsyms += l; ! 971: n = aux->x_sym.x_fcnary.x_fcn.x_endndx - 1; ! 972: #if !PORTAR && !PORT5AR ! 973: if (symbuf != NULL) ! 974: symbuf += l; ! 975: else ! 976: #endif ! 977: if (fseek(fdes, l * SYMESZ, 1) != 0) ! 978: lderror(2,0,NULL,"fail to skip the mem of struct of %s", ! 979: filp->flname); ! 980: } ! 981: #if TRVEC ! 982: ! 983: /* ! 984: * Increment size of .tv if this ! 985: * symbol needs a slot in the tv. ! 986: */ ! 987: if( aflag && tvflag && (tmp_sclass == C_STAT) && (aux->x_sym.x_tvndx == N_TV) ) ! 988: tvspec.tvosptr->oshdr.s_size += TVENTSZ; ! 989: #endif ! 990: } ! 991: } ! 992: } ! 993: ! 994: if( relsyms > maxrelocsms ) ! 995: maxrelocsms = relsyms; ! 996: ! 997: return( locsyms ); ! 998: } ! 999: /*eject*/ ! 1000: SYMTAB * ! 1001: loopsym(sym, changed) ! 1002: SYMTAB *sym; ! 1003: int changed; ! 1004: { ! 1005: ! 1006: /* ! 1007: * Loop through all symbol table entries ! 1008: */ ! 1009: ! 1010: #if NOSDP ! 1011: static long ndx; ! 1012: if (sym == NULL) ndx = 0; ! 1013: if (ndx < numldsyms) ! 1014: return(getsym(++ndx)); ! 1015: else ! 1016: return(NULL); ! 1017: #else ! 1018: static long offset, /* offset of next symbol in page */ ! 1019: page; /* SDP page number */ ! 1020: register ITEMID acid; ! 1021: /* ! 1022: * WARNING: this implementation of loopsym() is extremely dependent ! 1023: * upon knowing exactly how SDP does things. In particular, it ! 1024: * is dependent upon symbol table entries being in one SDP space, ! 1025: * separate from aux entries. Anyone touching SDP ! 1026: * defines or code should check this function for accuracy. ! 1027: */ ! 1028: ! 1029: #if DEBUG ! 1030: if( dflag > 15 ) ! 1031: fprintf( stderr, "\nloopsym %8s ", sym->sment.n_name ); ! 1032: #endif ! 1033: ! 1034: /* ! 1035: * This routine is used as follows: ! 1036: * ! 1037: * For the first call to this routine, sym is set to NULL. ! 1038: * For all subsequent calls, sym equals the value returned by ! 1039: * the previous call. ! 1040: * When sym again equals NULL, the entire table has been searched. ! 1041: */ ! 1042: ! 1043: if( sym == NULL ) { ! 1044: /* ! 1045: * Build the itemid for first entry in symbol table ! 1046: */ ! 1047: page = 1L; ! 1048: offset = 0L; ! 1049: acid = BUILDPN(page, SYMSPACE) + offset; ! 1050: if ( global_frames[SYMSPACE].maxpage == 0L ) ! 1051: return( NULL ); /* no symbols */ ! 1052: return( (SYMTAB *) lock(acid, MISPARTITION, RNLY) ); ! 1053: } ! 1054: ! 1055: /* ! 1056: * Find the next symbol table entry: ! 1057: * ! 1058: */ ! 1059: ! 1060: unlock(sym->smmyacid, (changed ? WRTN : RNLY)); ! 1061: ! 1062: offset += (long) SYMSIZ; ! 1063: if ( (offset + (long) SYMSIZ) > (long) PAGESIZE ) { ! 1064: offset = 0L; ! 1065: if ( ++page > global_frames[SYMSPACE].maxpage ) ! 1066: return(NULL); ! 1067: } else { ! 1068: /* ! 1069: * are we past the last entry on the last page? ! 1070: */ ! 1071: if ( (page == global_frames[SYMSPACE].curpage) && ! 1072: (offset == global_frames[SYMSPACE].curoffset) ) ! 1073: return(NULL); ! 1074: } ! 1075: acid = BUILDPN(page, SYMSPACE) + offset; ! 1076: return( (SYMTAB *) lock(acid, MISPARTITION, RNLY) ); ! 1077: #endif ! 1078: } ! 1079: /*eject*/ ! 1080: AUXTAB * ! 1081: loopaux(sym, aux, changed) ! 1082: SYMTAB *sym; ! 1083: AUXTAB *aux; ! 1084: int changed; ! 1085: { ! 1086: ! 1087: /* ! 1088: * Loop through all the aux entries for a given ld symbol table entry ! 1089: * ! 1090: * ! 1091: * This routine is used as follows: ! 1092: * ! 1093: * For the first call to this routine, aux is set to NULL. ! 1094: * For all subsequent calls, aux equals the value returned by ! 1095: * the previous call. ! 1096: * When aux again equals NULL, all aux entries have been returned ! 1097: */ ! 1098: ! 1099: #if DEBUG ! 1100: if( dflag > 15 ) ! 1101: fprintf( stderr, "\nloopaux %s ", SYMNAME( sym->sment ) ); ! 1102: #endif ! 1103: ! 1104: if( aux == NULL ) { ! 1105: /* ! 1106: * Get the first aux entry, pointed to by the ld symbol ! 1107: * table entry ! 1108: */ ! 1109: if( sym->smauxid != 0 ) ! 1110: #if NOSDP ! 1111: return(getaux(sym->smauxid)); ! 1112: #else ! 1113: return( (AUXTAB *) lock(sym->smauxid, MISPARTITION, WRTN) ); ! 1114: #endif ! 1115: ! 1116: return( NULL ); ! 1117: } ! 1118: ! 1119: /* ! 1120: * Find the next aux entry ! 1121: */ ! 1122: ! 1123: #if NOSDP ! 1124: if (aux->axchainid != 0) ! 1125: return(getaux(aux->axchainid)); ! 1126: #else ! 1127: unlock(aux->axmyacid, (changed ? WRTN : RNLY)); ! 1128: ! 1129: if( aux->axchainid != 0 ) ! 1130: return( (AUXTAB *) lock(aux->axchainid, MISPARTITION, WRTN) ); ! 1131: #endif ! 1132: ! 1133: return( NULL ); ! 1134: } ! 1135: /*eject*/ ! 1136: INSECT * ! 1137: sectnum(i, fp) ! 1138: int i; ! 1139: INFILE *fp; ! 1140: { ! 1141: ! 1142: /* ! 1143: * Called by psymtab to retrieve a pointer to the i-th section header ! 1144: */ ! 1145: ! 1146: register INSECT *sptr; ! 1147: ! 1148: if (i == 0) ! 1149: return(NULL); ! 1150: ! 1151: ! 1152: for ( sptr = fp->flishead; sptr != NULL; sptr = sptr->isnext ) ! 1153: if ( sptr->isecnum == i) ! 1154: return(sptr); ! 1155: return(NULL); ! 1156: } ! 1157: /*eject*/ ! 1158: ITEMID ! 1159: add_dot(dot_val, dot_sec) ! 1160: long dot_val; ! 1161: INSECT *dot_sec; ! 1162: { ! 1163: register SYMTAB *sym; ! 1164: register ITEMID acid; ! 1165: static int count = 0; ! 1166: ! 1167: /* ! 1168: * This is a special-purpose "makesym()" designed for exclusive use ! 1169: * in assignment expressions. It will create a symbol table entry ! 1170: * having the following characteristics: ! 1171: * ! 1172: * n_name: .dotnnn 001 <= nnn <= 999 ! 1173: * n_value: dot_val ! 1174: * n_scnum: 0 ! 1175: * n_type: T_NULL ! 1176: * n_sclass: C_NULL ! 1177: * n_numaux: 0 ! 1178: * ! 1179: * smscnptr: dot_sec ! 1180: * smlocflg: 1 ! 1181: * ! 1182: * The symbol table entry will NOT appear in the hash table, and hence ! 1183: * will not be accessible except thorugh the stored itemid returned ! 1184: * by this function ! 1185: */ ! 1186: ! 1187: #if NOSDP ! 1188: if (numldsyms >= MYSMTBSZ + (xsymcnt * XSMTBSZ)) { ! 1189: if (xsymcnt >= MAXEXTRA) ! 1190: lderror(2,0,"internal error: ","symbol table overflow"); ! 1191: xsymptr[xsymcnt++] = (SYMTAB *) myalloc(XSMTBSZ * SYMSIZ); ! 1192: } ! 1193: acid = ++numldsyms; ! 1194: sym = getsym(acid); ! 1195: #else ! 1196: acid = allocate(SYMSIZ, SYMSPACE, MISPARTITION); ! 1197: sym = (SYMTAB *) lock(acid, MISPARTITION, WRTN); ! 1198: ! 1199: zero(sym, SYMSIZ); ! 1200: #endif ! 1201: sprintf(sym->sment.n_name, ".dot%03d", ++count); ! 1202: sym->sment.n_value = dot_val; ! 1203: sym->smscnptr = dot_sec; ! 1204: sym->smmyacid = acid; ! 1205: sym->smchainid = acid; ! 1206: sym->smlocflg = 1; ! 1207: ! 1208: #if !NOSDP ! 1209: unlock(acid, WRTN); ! 1210: #endif ! 1211: ! 1212: return( acid ); ! 1213: ! 1214: } ! 1215: ! 1216: #if !NOSDP ! 1217: auxinit() ! 1218: { ! 1219: /* initialize SDP */ ! 1220: ! 1221: if ( aux_called ) ! 1222: lderror(2,0,NULL,"attempt to re-initialize SDP aux space"); ! 1223: ! 1224: sprintf( auxname, "%s/%s", TMPDIR, "ldXXXXXX"); ! 1225: mktemp(auxname); ! 1226: aux_called++; ! 1227: if ( sdpinit(auxname, CREATE, AUXSPACE) != AUXSPACE ) ! 1228: lderror(2,0,NULL,"failure to initialize SDP aux space"); ! 1229: else ! 1230: aux_called++; ! 1231: } ! 1232: ! 1233: auxfini() ! 1234: { ! 1235: ! 1236: char buf[sizeof(auxname)*2+20]; ! 1237: ! 1238: if ( aux_called == 2 ) { ! 1239: aux_called--; ! 1240: if ( sdpterm(AUXSPACE) < 0 ) ! 1241: lderror(2,0,NULL,"failure in closing SDP aux space"); ! 1242: } ! 1243: ! 1244: if ( aux_called != 1) ! 1245: return; ! 1246: aux_called--; ! 1247: ! 1248: #if TS || RT ! 1249: sprintf(buf, "rm -r %s", auxname); ! 1250: #else ! 1251: sprintf(buf, "rm -r %s; rmdir %s", auxname, auxname); ! 1252: #endif ! 1253: ! 1254: if ( fork() == 0 ) { ! 1255: execl("/bin/sh", "sh", "-c", buf, 0); ! 1256: lderror(0,0,NULL, "failure in the execl of %s",buf); ! 1257: _exit(127); ! 1258: } ! 1259: } ! 1260: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.