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