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