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