|
|
1.1 ! root 1: /* Copyright (c) 1980 Regents of the University of California */ ! 2: static char sccsid[] = "@(#)assyms.c 4.6 11/5/80"; ! 3: #include <stdio.h> ! 4: #include <ctype.h> ! 5: #include "as.h" ! 6: #include "asscan.h" ! 7: #include "assyms.h" ! 8: ! 9: /* ! 10: * Managers for chunks of symbols allocated from calloc() ! 11: * We maintain a linked list of such chunks. ! 12: * ! 13: */ ! 14: struct allocbox *allochead; /*head of chunk list*/ ! 15: struct allocbox *alloctail; /*tail*/ ! 16: struct allocbox *newbox; /*for creating a new chunk*/ ! 17: struct symtab *nextsym; /*next symbol free*/ ! 18: int symsleft; /*slots left in current chunk*/ ! 19: ! 20: struct symtab **symptrs; ! 21: struct symtab **symdelim[NLOC + NLOC +1]; ! 22: struct symtab **symptrub; ! 23: /* ! 24: * Managers for the dynamically extendable hash table ! 25: */ ! 26: struct hashdallop *htab; ! 27: ! 28: struct instab *itab[NINST]; /*maps opcodes to instructions*/ ! 29: /* ! 30: * Counts what went into the symbol table, so that the ! 31: * size of the symbol table can be computed. ! 32: */ ! 33: int nsyms; /* total number in the symbol table */ ! 34: int njxxx; /* number of jxxx entrys */ ! 35: int nforgotten; /* number of symbols erroneously entered */ ! 36: int nlabels; /* number of label entries */ ! 37: int hshused; /* number of hash slots used */ ! 38: ! 39: /* ! 40: * Managers of the symbol literal storage. ! 41: * If we have flexible names, then we allocate BUFSIZ long ! 42: * string, and pack strings into that. Otherwise, we allocate ! 43: * symbol storage in fixed hunks NCPS long when we allocate space ! 44: * for other symbol attributes. ! 45: */ ! 46: #ifdef FLEXNAMES ! 47: struct strpool *strplhead = 0; ! 48: #endif FLEXNAMES ! 49: ! 50: symtabinit() ! 51: { ! 52: allochead = 0; ! 53: alloctail = 0; ! 54: nextsym = 0; ! 55: symsleft = 0; ! 56: #ifdef FLEXNAMES ! 57: strpoolalloc(); /* get the first strpool storage area */ ! 58: #endif FLEXNAMES ! 59: htab = 0; ! 60: htaballoc(); /* get the first part of the hash table */ ! 61: } ! 62: ! 63: /* ! 64: * Install all known instructions in the symbol table ! 65: */ ! 66: syminstall() ! 67: { ! 68: register struct instab *ip; ! 69: register struct symtab **hp; ! 70: register char *p1, *p2; ! 71: ! 72: #ifdef FLEXNAMES ! 73: for (ip = (struct instab *)instab; ip->s_name != 0; ip++) { ! 74: #else /*not FLEXNAMES*/ ! 75: for (ip = (struct instab *)instab; ip->s_name[0] != '\0'; ip++){ ! 76: #endif /*not FLEXNAMES*/ ! 77: p1 = ip->s_name; ! 78: p2 = yytext; ! 79: while (*p2++ = *p1++); ! 80: hp = lookup(0); /* 0 => don't install this*/ ! 81: if (*hp==NULL) { ! 82: *hp = (struct symtab *)ip; ! 83: if ( (ip->s_tag!=INSTn) ! 84: && (ip->s_tag!=INST0) ! 85: && (ip->s_tag!=0)) ! 86: continue; /* was pseudo-op */ ! 87: itab[ip->i_opcode & 0xFF] = ip; ! 88: } ! 89: } ! 90: } /*end of syminstall*/ ! 91: ! 92: ! 93: /* ! 94: * Assign final values to symbols, ! 95: * and overwrite the index field with its relative position in ! 96: * the symbol table we give to the loader. ! 97: */ ! 98: extern struct exec hdr; ! 99: ! 100: freezesymtab() ! 101: { ! 102: register struct symtab *sp; ! 103: long bs; ! 104: register int relpos = 0; ! 105: register struct symtab *ubsp; ! 106: register struct allocbox *allocwalk; ! 107: ! 108: DECLITERATE(allocwalk, sp, ubsp) ! 109: { ! 110: if (sp->s_tag >= IGNOREBOUND) ! 111: continue; /*totally ignore jxxx entries */ ! 112: /* ! 113: * Ignore stabs, but give them a symbol table index ! 114: */ ! 115: if (sp->s_type & STABFLAG) ! 116: goto assignindex; ! 117: if ((sp->s_type&XTYPE)==XUNDEF) ! 118: sp->s_type = XXTRN+XUNDEF; ! 119: else if ((sp->s_type&XTYPE)==XDATA) ! 120: sp->s_value += usedot[sp->s_index].e_xvalue; ! 121: else if ((sp->s_type&XTYPE)==XTEXT) ! 122: sp->s_value += usedot[sp->s_index].e_xvalue; ! 123: else if ((sp->s_type&XTYPE)==XBSS) { ! 124: bs = sp->s_value; ! 125: sp->s_value = hdr.a_bss + datbase; ! 126: hdr.a_bss += bs; ! 127: } ! 128: assignindex: ! 129: if ( (sp->s_name[0] != 'L') ! 130: || (sp->s_tag != LABELID) ! 131: || savelabels ! 132: ) /*then, we will write it later on*/ ! 133: sp->s_index = relpos++; ! 134: } ! 135: } ! 136: ! 137: ! 138: ! 139: /* ! 140: * For all of the stabs that had their final value undefined during pass 1 ! 141: * and during pass 2 assign a final value. ! 142: * We have already given stab entrys a initial approximation ! 143: * when we constsructed the sorted symbol table. ! 144: * Iteration order doesn't matter. ! 145: */ ! 146: stabfix() { ! 147: register struct symtab *sp, **cosp; ! 148: register struct symtab *p; ! 149: ! 150: SYMITERATE(cosp, sp){ ! 151: if(sp->s_ptype && (sp->s_type & STABFLAG)) { ! 152: p = sp->s_dest; ! 153: sp->s_value = p->s_value; ! 154: sp->s_index = p->s_index; ! 155: sp->s_type = p->s_type; ! 156: } ! 157: } ! 158: } ! 159: ! 160: char *Calloc(number, size) ! 161: int number, size; ! 162: { ! 163: register char *newstuff; ! 164: newstuff = (char *)sbrk(number*size); ! 165: if ((int)newstuff == -1){ ! 166: yyerror("Ran out of Memory"); ! 167: delexit(); ! 168: } ! 169: return(newstuff); ! 170: } ! 171: ! 172: char *ClearCalloc(number, size) ! 173: int number, size; ! 174: { ! 175: register char *newstuff; /* r11 */ ! 176: register int length = number * size; /* r10 */ ! 177: newstuff = Calloc(number, size); ! 178: asm("movc5 $0, (r0), $0, r10, (r11)"); ! 179: return(newstuff); ! 180: } ! 181: ! 182: struct symtab *symalloc() ! 183: { ! 184: if (symsleft == 0){ ! 185: newbox = (struct allocbox *)ClearCalloc(1,ALLOCQTY); ! 186: symsleft = SYMDALLOP; ! 187: nextsym = &newbox->symslots[0]; ! 188: if (alloctail == 0){ ! 189: allochead = alloctail = newbox; ! 190: } else { ! 191: alloctail->nextalloc = newbox; ! 192: alloctail = newbox; ! 193: } ! 194: } ! 195: --symsleft; ! 196: ++nsyms; ! 197: return(nextsym++); ! 198: } ! 199: ! 200: #ifdef FLEXNAMES ! 201: strpoolalloc() ! 202: { ! 203: register struct strpool *new; ! 204: ! 205: new = (struct strpool *)Calloc(1, sizeof (struct strpool)); ! 206: new->str_nalloc = 0; ! 207: new->str_next = strplhead; ! 208: strplhead = new; ! 209: } ! 210: #endif FLEXNAMES ! 211: ! 212: symcmp(Pptr, Qptr) ! 213: struct symtab **Pptr, **Qptr; ! 214: { ! 215: register struct symtab *p = *Pptr; ! 216: register struct symtab *q = *Qptr; ! 217: if (p->s_index < q->s_index) ! 218: return(-1); ! 219: if (p->s_index > q->s_index) ! 220: return(1); ! 221: if (p->s_value < q->s_value) ! 222: return(-1); ! 223: if (p->s_value > q->s_value) ! 224: return(1); ! 225: /* ! 226: * Force jxxx entries to virtually preceed labels defined ! 227: * to follow the jxxxx instruction, so that bumping the ! 228: * jxxx instruction correctly fixes up the following labels ! 229: */ ! 230: if (p->s_tag >= IGNOREBOUND) /*p points to a jxxx*/ ! 231: return(-1); ! 232: if (q->s_tag >= IGNOREBOUND) ! 233: return(1); ! 234: /* ! 235: * both are now just plain labels; the relative order doesn't ! 236: * matter. Both can't be jxxxes, as they would have different ! 237: * values. ! 238: */ ! 239: return(0); ! 240: } /*end of symcmp*/ ! 241: ! 242: /* ! 243: * We construct the auxiliary table of pointers, symptrs and ! 244: * symdelim ! 245: * We also assign preliminary values to stab entries that did not yet ! 246: * have an absolute value (because they initially referred to ! 247: * forward references). We don't worry about .stabds, as they ! 248: * already have an estimated final value ! 249: */ ! 250: ! 251: sortsymtab() ! 252: { ! 253: register struct symtab *sp; ! 254: register struct symtab **cowalk; ! 255: register struct allocbox *allocwalk; ! 256: struct symtab *ubsp; ! 257: int segno; ! 258: int slotno; ! 259: int symsin; /*number put into symptrs*/ ! 260: ! 261: symptrs = (struct symtab **)Calloc(nsyms + 2, sizeof *symptrs); ! 262: /* ! 263: * Allocate one word at the beginning of the symptr array ! 264: * so that backwards scans through the symptr array will ! 265: * work correctly while scanning through the zeroth segment ! 266: */ ! 267: *symptrs++ = 0; ! 268: cowalk = symptrs; ! 269: symsin = 0; ! 270: DECLITERATE(allocwalk, sp, ubsp) { ! 271: if (sp->s_ptype && (sp->s_type &STABFLAG)){ ! 272: sp->s_value = sp->s_dest->s_value; ! 273: sp->s_index = sp->s_dest->s_index; ! 274: } ! 275: if (symsin >= nsyms) ! 276: yyerror("INTERNAL ERROR: overfilled symbol table indirection table"); ! 277: *cowalk++ = sp; ! 278: symsin++; ! 279: } ! 280: if (symsin != nsyms) ! 281: yyerror("INTERNAL ERROR: installed %d syms, should have installed %d", ! 282: symsin, nsyms); ! 283: symptrub = &symptrs[nsyms ]; ! 284: qsort(symptrs, nsyms, sizeof *symptrs, symcmp); ! 285: symdelim[0] = symptrs; ! 286: for (cowalk = symptrs, sp = *cowalk, segno = 0, slotno = 1; ! 287: segno < NLOC + NLOC; ! 288: segno++, slotno++){ ! 289: for (; sp && sp->s_index == segno; sp = *++cowalk); ! 290: symdelim[slotno] = cowalk; /*forms the ub delimeter*/ ! 291: } ! 292: } /*end of sortsymtab*/ ! 293: ! 294: #ifdef DEBUG ! 295: dumpsymtab() ! 296: { ! 297: register int segno; ! 298: register struct symtab *sp, **cosp, *ub; ! 299: char *tagstring(); ! 300: ! 301: printf("Symbol Table dump:\n"); ! 302: for (segno = 0; segno < NLOC + NLOC; segno++){ ! 303: printf("Segment number: %d\n", segno); ! 304: SEGITERATE(segno, 0, 0, cosp, sp, ub, ++){ ! 305: #ifdef FLEXNAMES ! 306: printf("\tSeg: %d \"%s\" value: %d index: %d tag %s\n", ! 307: segno, sp->s_name, ! 308: sp->s_value, sp->s_index, ! 309: tagstring(sp->s_tag)); ! 310: #else /*not FLEXNAMES*/ ! 311: printf("\tSeg: %d \"%*.*s\" value: %d index: %d tag %s\n", ! 312: segno, NCPS, NCPS, sp->s_name, ! 313: sp->s_value, sp->s_index, ! 314: tagstring(sp->s_tag)); ! 315: #endif /*not FLEXNAMES*/ ! 316: printf("\t\ttype: %d jxbump %d jxfear: %d\n", ! 317: sp->s_type, sp->s_jxbump, sp->s_jxfear); ! 318: } ! 319: printf("\n\n"); ! 320: } ! 321: } ! 322: ! 323: static char tagbuff[4]; ! 324: ! 325: char *tagstring(tag) ! 326: unsigned char tag; ! 327: { ! 328: switch(tag){ ! 329: case JXACTIVE: return("active"); ! 330: case JXNOTYET: return("notyet"); ! 331: case JXALIGN: return("align"); ! 332: case JXQUESTIONABLE: return("jxquestionable"); ! 333: case JXINACTIVE: return("inactive"); ! 334: case JXTUNNEL: return("tunnel"); ! 335: case OBSOLETE: return("obsolete"); ! 336: case IGNOREBOUND: return("ignorebound"); ! 337: case STABFLOATING: return("stabfloating"); ! 338: case STABFIXED: return("stabfixed"); ! 339: case LABELID: return("labelid"); ! 340: case OKTOBUMP: return("oktobump"); ! 341: case ISET: return("iset"); ! 342: case ILSYM: return("ilsym"); ! 343: default: sprintf(tagbuff,"%d", tag); ! 344: return(tagbuff); ! 345: } ! 346: } ! 347: #endif DEBUG ! 348: ! 349: htaballoc() ! 350: { ! 351: register struct hashdallop *new; ! 352: new = (struct hashdallop *)ClearCalloc(1, sizeof (struct hashdallop)); ! 353: if (htab == 0) ! 354: htab = new; ! 355: else { /* add AFTER the 1st slot */ ! 356: new->h_next = htab->h_next; ! 357: htab->h_next = new; ! 358: } ! 359: } ! 360: ! 361: #define HASHCLOGGED (NHASH / 2) ! 362: ! 363: /* ! 364: * Lookup a symbol stored in extern yytext. ! 365: * All strings passed in via extern yytext had better have ! 366: * a trailing null. Strings are placed in yytext for hashing by ! 367: * syminstall() and by yylex(); ! 368: * ! 369: * We take pains to avoid function calls; this functdion ! 370: * is called quite frequently, and the calls overhead ! 371: * in the vax contributes significantly to the overall ! 372: * execution speed of as. ! 373: */ ! 374: struct symtab **lookup(instflg) ! 375: int instflg; /* 0: don't install */ ! 376: { ! 377: static int initialprobe; ! 378: register struct symtab **hp; ! 379: register char *from; ! 380: register char *to; ! 381: register int len; ! 382: register int nprobes; ! 383: static struct hashdallop *hdallop; ! 384: static struct symtab **emptyslot; ! 385: static struct hashdallop *emptyhd; ! 386: static struct symtab **hp_ub; ! 387: ! 388: emptyslot = 0; ! 389: for (nprobes = 0, from = yytext; ! 390: *from; ! 391: nprobes <<= 2, nprobes += *from++) ! 392: continue; ! 393: nprobes += from[-1] << 5; ! 394: nprobes %= NHASH; ! 395: if (nprobes < 0) ! 396: nprobes += NHASH; ! 397: ! 398: initialprobe = nprobes; ! 399: for (hdallop = htab; hdallop != 0; hdallop = hdallop->h_next){ ! 400: for (hp = &(hdallop->h_htab[initialprobe]), ! 401: nprobes = 1, ! 402: hp_ub = &(hdallop->h_htab[NHASH]); ! 403: (*hp) && (nprobes < NHASH); ! 404: hp += nprobes, ! 405: hp -= (hp >= hp_ub) ? NHASH:0, ! 406: nprobes += 2) ! 407: { ! 408: from = yytext; ! 409: to = (*hp)->s_name; ! 410: #ifndef FLEXNAMES ! 411: for (len = 0; (len<NCPS) && *from; len++) ! 412: if (*from++ != *to++) ! 413: goto nextprobe; ! 414: if (len >= NCPS) /*both are maximal length*/ ! 415: return(hp); ! 416: if (*to == 0) /*assert *from == 0*/ ! 417: return(hp); ! 418: #else /*FLEXNAMES*/ ! 419: while (*from && *to) ! 420: if (*from++ != *to++) ! 421: goto nextprobe; ! 422: if (*to == *from) /*assert both are == 0*/ ! 423: return(hp); ! 424: #endif /*FLEXNAMES*/ ! 425: ! 426: nextprobe: ; ! 427: } ! 428: if (*hp == 0 && emptyslot == 0 && ! 429: hdallop->h_nused < HASHCLOGGED) { ! 430: emptyslot = hp; ! 431: emptyhd = hdallop; ! 432: } ! 433: } ! 434: if (emptyslot == 0) { ! 435: htaballoc(); ! 436: hdallop = htab->h_next; /* aren't we smart! */ ! 437: hp = &hdallop->h_htab[initialprobe]; ! 438: } else { ! 439: hdallop = emptyhd; ! 440: hp = emptyslot; ! 441: } ! 442: if (instflg) { ! 443: *hp = symalloc(); ! 444: hdallop->h_nused++; ! 445: #ifndef FLEXNAMES ! 446: for(len = 0, from = yytext, to = (*hp)->s_name; (len<NCPS); len++) ! 447: if ((*to++ = *from++) == '\0') ! 448: break; ! 449: #else /*FLEXNAMES*/ ! 450: for (from = yytext, len = 1; *from++; len++) ! 451: continue; ! 452: if (len >= (STRPOOLDALLOP - strplhead->str_nalloc)) ! 453: strpoolalloc(); ! 454: for ( (*hp)->s_name = to = strplhead->str_names + strplhead->str_nalloc, from = yytext; ! 455: ( (*to++ = *from++) != '\0'); ) ! 456: continue; ! 457: strplhead->str_nalloc += len; ! 458: #endif /*FLEXNAMES*/ ! 459: } ! 460: return(hp); ! 461: } /*end of lookup*/ ! 462: ! 463: #ifdef FLEXNAMES ! 464: char *savestr(str) ! 465: char *str; ! 466: { ! 467: register int len; ! 468: register char *from, *to; ! 469: char *res; ! 470: ! 471: for (from = str, len = 1; *from++; len++) ! 472: continue; ! 473: if (len >= (STRPOOLDALLOP - strplhead->str_nalloc)) ! 474: strpoolalloc(); ! 475: for ( res = to = strplhead->str_names + strplhead->str_nalloc, from = str; ! 476: ( (*to++ = *from++) != '\0'); ) ! 477: continue; ! 478: strplhead->str_nalloc += len; ! 479: return (res); ! 480: } ! 481: #endif FLEXNAMES ! 482: ! 483: /* ! 484: * The relocation information is saved internally in an array of ! 485: * lists of relocation buffers. The relocation buffers are ! 486: * exactly the same size as a token buffer; if we use VM for the ! 487: * temporary file we reclaim this storage, otherwise we create ! 488: * them by mallocing. ! 489: */ ! 490: #define RELBUFLG TOKBUFLG ! 491: #define NRELOC ((TOKBUFLG - \ ! 492: (sizeof (int) + sizeof (struct relbufdesc *)) \ ! 493: ) / (sizeof (struct relocation_info))) ! 494: ! 495: struct relbufdesc{ ! 496: int rel_count; ! 497: struct relbufdesc *rel_next; ! 498: struct relocation_info rel_reloc[NRELOC]; ! 499: }; ! 500: extern struct relbufdesc *tok_free; ! 501: #define rel_free tok_free ! 502: static struct relbufdesc *rel_temp; ! 503: struct relocation_info r_can_1PC; ! 504: struct relocation_info r_can_0PC; ! 505: ! 506: initoutrel() ! 507: { ! 508: r_can_0PC.r_address = 0; ! 509: r_can_0PC.r_symbolnum = 0; ! 510: r_can_0PC.r_pcrel = 0; ! 511: r_can_0PC.r_length = 0; ! 512: r_can_0PC.r_extern = 0; ! 513: ! 514: r_can_1PC = r_can_0PC; ! 515: r_can_1PC.r_pcrel = 1; ! 516: } ! 517: ! 518: outrel(xp, reloc_how, isaddr) ! 519: register struct exp *xp; ! 520: int reloc_how; /* TYPB..TYPD + (possibly)RELOC_PCREL */ ! 521: { ! 522: struct relocation_info reloc; ! 523: register int x_type_mask; ! 524: int pcrel; ! 525: ! 526: x_type_mask = xp->e_xtype & ~XFORW; ! 527: pcrel = reloc_how & RELOC_PCREL; ! 528: reloc_how &= ~RELOC_PCREL; ! 529: ! 530: if (bitoff&07) ! 531: yyerror("Padding error"); ! 532: if (x_type_mask == XUNDEF) ! 533: yyerror("Undefined reference"); ! 534: if ( (x_type_mask != XABS) || pcrel ) { ! 535: if (ty_NORELOC[reloc_how]) ! 536: yyerror("Illegal Relocation of float, double or quad."); ! 537: reloc = pcrel ? r_can_1PC : r_can_0PC; ! 538: reloc.r_address = dotp->e_xvalue - ! 539: ( (dotp < &usedot[NLOC] || readonlydata) ? 0 : datbase ); ! 540: reloc.r_length = ty_nlg[reloc_how]; ! 541: switch(x_type_mask){ ! 542: case XXTRN | XUNDEF: ! 543: reloc.r_symbolnum = xp->e_xname->s_index; ! 544: reloc.r_extern = 1; ! 545: break; ! 546: default: ! 547: if (readonlydata && (x_type_mask&~XXTRN) == XDATA) ! 548: x_type_mask = XTEXT | (x_type_mask&XXTRN); ! 549: reloc.r_symbolnum = x_type_mask; ! 550: break; ! 551: } ! 552: if ( (relfil == 0) || (relfil->rel_count >= NRELOC) ){ ! 553: if (rel_free){ ! 554: rel_temp = rel_free; ! 555: rel_free = rel_temp->rel_next; ! 556: } else { ! 557: rel_temp = (struct relbufdesc *) ! 558: Calloc(1,sizeof (struct relbufdesc)); ! 559: } ! 560: rel_temp->rel_count = 0; ! 561: rel_temp->rel_next = relfil; ! 562: relfil = rusefile[dotp - &usedot[0]] = rel_temp; ! 563: } ! 564: /* reloc.r_addsyl = isaddr!=0;(addsyl is unreferenced)*/ ! 565: relfil->rel_reloc[relfil->rel_count++] = reloc; ! 566: } ! 567: /* ! 568: * write the unrelocated value to the text file ! 569: */ ! 570: dotp->e_xvalue += ty_nbyte[reloc_how]; ! 571: if (pcrel) ! 572: xp->e_xvalue -= dotp->e_xvalue; ! 573: bwrite((char *)&(xp->e_xvalue), ty_nbyte[reloc_how], txtfil); ! 574: } ! 575: /* ! 576: * Flush out all of the relocation information. ! 577: * Note that the individual lists of buffers are in ! 578: * reverse order, so we must reverse them ! 579: */ ! 580: off_t closeoutrel(relocfile) ! 581: BFILE *relocfile; ! 582: { ! 583: int locindex; ! 584: u_long Closeoutrel(); ! 585: ! 586: trsize = 0; ! 587: for (locindex = 0; locindex < NLOC; locindex++){ ! 588: trsize += Closeoutrel(rusefile[locindex], relocfile); ! 589: } ! 590: drsize = 0; ! 591: for (locindex = 0; locindex < NLOC; locindex++){ ! 592: drsize += Closeoutrel(rusefile[NLOC + locindex], relocfile); ! 593: } ! 594: return(trsize + drsize); ! 595: } ! 596: ! 597: u_long Closeoutrel(relfil, relocfile) ! 598: struct relbufdesc *relfil; ! 599: BFILE *relocfile; ! 600: { ! 601: u_long tail; ! 602: if (relfil == 0) ! 603: return(0L); ! 604: tail = Closeoutrel(relfil->rel_next, relocfile); ! 605: bwrite((char *)&relfil->rel_reloc[0], ! 606: relfil->rel_count * sizeof (struct relocation_info), ! 607: relocfile); ! 608: return(tail + relfil->rel_count * sizeof (struct relocation_info)); ! 609: } ! 610: ! 611: #define NOUTSYMS (nsyms - njxxx - nforgotten - (savelabels ? 0 : nlabels)) ! 612: int sizesymtab() ! 613: { ! 614: return (sizeof (struct nlist) * NOUTSYMS); ! 615: } ! 616: ! 617: #ifdef FLEXNAMES ! 618: /* ! 619: * We write out the flexible length character strings for names ! 620: * in two stages. ! 621: * 1) We have always! maintain a fixed sized name list entry; ! 622: * the string is indexed by a four byte quantity from the beginning ! 623: * of the string pool area. Index 0 is reserved, and indicates ! 624: * that there is no associated string. The first valid index is 4. ! 625: * 2) We concatenate together and write all of the strings ! 626: * in the string pool at the end of the name list. The first ! 627: * four bytes in the string pool are indexed only by 0 (see above); ! 628: * they contain the total number of bytes in the string pool. ! 629: */ ! 630: #endif FLEXNAMES ! 631: ! 632: /* ! 633: * Write out n symbols to file f, beginning at p ! 634: * ignoring symbols that are obsolete, jxxx instructions, and ! 635: * possibly, labels ! 636: */ ! 637: ! 638: int symwrite(symfile) ! 639: BFILE *symfile; ! 640: { ! 641: int symsout; /*those actually written*/ ! 642: int symsdesired = NOUTSYMS; ! 643: register struct symtab *sp, *ub; ! 644: #ifdef FLEXNAMES ! 645: char *name; /* temp to save the name */ ! 646: long stroff = sizeof (stroff); ! 647: /* ! 648: * We use sp->s_index to hold the length of the ! 649: * name; it isn't used for anything else ! 650: */ ! 651: #endif FLEXNAMES ! 652: ! 653: register struct allocbox *allocwalk; ! 654: ! 655: symsout = 0; ! 656: DECLITERATE(allocwalk, sp, ub) ! 657: { ! 658: if (sp->s_tag >= IGNOREBOUND) ! 659: continue; ! 660: if ((sp->s_name[0] == 'L') && (sp->s_tag == LABELID) && !savelabels) ! 661: continue; ! 662: symsout++; ! 663: ! 664: #ifdef FLEXNAMES ! 665: name = sp->s_name; /* save pointer */ ! 666: if ( (sp->s_index = strlen(sp->s_name)) != 0){ ! 667: sp->s_nmx = stroff; /* clobber pointer */ ! 668: stroff += sp->s_index + 1; ! 669: } else { ! 670: sp->s_nmx = 0; /* clobber pointer */ ! 671: } ! 672: #endif ! 673: sp->s_type = (sp->s_ptype != 0) ? sp->s_ptype : (sp->s_type & (~XFORW)); ! 674: if (readonlydata && (sp->s_type&~N_EXT) == N_DATA) ! 675: sp->s_type = N_TEXT | (sp->s_type & N_EXT); ! 676: bwrite(&sp->s_nm, sizeof (struct nlist), symfile); ! 677: #ifdef FLEXNAMES ! 678: sp->s_name = name; /* restore pointer */ ! 679: #endif FLEXNAMES ! 680: } ! 681: if (symsout != symsdesired) ! 682: yyerror("INTERNAL ERROR: Wrote %d symbols, wanted to write %d symbols\n", ! 683: symsout, symsdesired); ! 684: #ifdef FLEXNAMES ! 685: /* ! 686: * Pass 2 through the string pool ! 687: */ ! 688: symsout = 0; ! 689: bwrite(&stroff, sizeof (stroff), symfile); ! 690: stroff = sizeof (stroff); ! 691: symsout = 0; ! 692: DECLITERATE(allocwalk, sp, ub) ! 693: { ! 694: if (sp->s_tag >= IGNOREBOUND) ! 695: continue; ! 696: if ((sp->s_name[0] == 'L') && (sp->s_tag == LABELID) && !savelabels) ! 697: continue; ! 698: sp->s_index = strlen(sp->s_name); ! 699: if (sp->s_index) ! 700: bwrite(sp->s_name, sp->s_index + 1, symfile); ! 701: } ! 702: #endif FLEXNAMES ! 703: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.