|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: #include <stdio.h> ! 3: #include "as.h" ! 4: #include "assyms.h" ! 5: ! 6: struct allocbox *allochead; ! 7: struct allocbox *alloctail; ! 8: struct symtab *nextsym; ! 9: struct allocbox *newbox; ! 10: char *namebuffer; ! 11: int symsleft; ! 12: ! 13: symtabinit() ! 14: { ! 15: allochead = 0; ! 16: alloctail = 0; ! 17: nextsym = 0; ! 18: symsleft = 0; ! 19: } ! 20: ! 21: /* ! 22: * Install all known instructions in the symbol table ! 23: */ ! 24: syminstall() ! 25: { ! 26: register struct instab *ip; ! 27: register struct symtab **hp; ! 28: register char *p1, *p2; ! 29: ! 30: for (ip=instab; ip->name[0]!=0; ip++) { ! 31: p1 = ip->name; ! 32: p2 = yytext; ! 33: while (*p2++ = *p1++); ! 34: hp = lookup(0); /* 0 => don't install this*/ ! 35: if (*hp==NULL) { ! 36: *hp = (struct symtab *)ip; ! 37: if ( (ip->tag!=INSTn) ! 38: && (ip->tag!=INST0) ! 39: && (ip->tag!=0)) ! 40: continue; /* was pseudo-op */ ! 41: itab[ip->opcode & 0xFF] = ip; ! 42: } ! 43: } ! 44: } /*end of syminstall*/ ! 45: ! 46: ! 47: /* ! 48: * Assign final values to symbols, ! 49: * and overwrite the index field with its relative position in ! 50: * the symbol table we give to the loader. ! 51: */ ! 52: extern struct hdr hdr; ! 53: ! 54: freezesymtab() ! 55: { ! 56: register struct symtab *sp; ! 57: long bs; ! 58: register int relpos = 0; ! 59: #ifdef SORTEDOUTPUT ! 60: register struct symtab **cosp; ! 61: #else ! 62: register struct symtab *ubsp; ! 63: register struct allocbox *allocwalk; ! 64: #endif ! 65: ! 66: #ifdef SORTEDOUTPUT ! 67: SYMITERATE(cosp, sp) ! 68: #else ! 69: DECLITERATE(allocwalk, sp, ubsp) ! 70: #endif ! 71: { ! 72: if (sp->tag >= IGNOREBOUND) ! 73: continue; /*totally ignore jxxx entries */ ! 74: /* ! 75: * Ignore stabs, but give them a symbol table index ! 76: */ ! 77: if (sp->type & STABFLAG) ! 78: goto assignindex; ! 79: if ((sp->type&XTYPE)==XUNDEF) ! 80: sp->type = XXTRN+XUNDEF; ! 81: else if ((sp->type&XTYPE)==XDATA) ! 82: sp->value += usedot[sp->index].xvalue; ! 83: else if ((sp->type&XTYPE)==XTEXT) ! 84: sp->value += usedot[sp->index].xvalue; ! 85: else if ((sp->type&XTYPE)==XBSS) { ! 86: bs = sp->value; ! 87: sp->value = hdr.bsize + datbase; ! 88: hdr.bsize += bs; ! 89: } ! 90: assignindex: ! 91: if ( (sp->name[0] != 'L') ! 92: || (sp->tag != LABELID) ! 93: || savelabels ! 94: ) /*then, we will write it later on*/ ! 95: sp->index = relpos++; ! 96: } ! 97: } ! 98: ! 99: ! 100: ! 101: /* ! 102: * For all of the stabs that had their final value undefined during pass 1 ! 103: * and during pass 2 assign a final value. ! 104: * We have already given stab entrys a initial approximation ! 105: * when we constsructed the sorted symbol table. ! 106: * Iteration order doesn't matter. ! 107: */ ! 108: stabfix() { ! 109: register struct symtab *sp, **cosp; ! 110: register struct symtab *p; ! 111: ! 112: SYMITERATE(cosp, sp){ ! 113: if(sp->ptype && (sp->type & STABFLAG)) { ! 114: p = sp->dest; ! 115: sp->value = p->value; ! 116: sp->index = p->index; ! 117: sp->type = p->type; ! 118: #ifdef DSTAB ! 119: printf("STABFIX: %s (old %s) to %d offsets %d %d\n", ! 120: sp->name, p->name, sp->value, sp, p); ! 121: #endif ! 122: } ! 123: } ! 124: } ! 125: ! 126: char *Calloc(number, size) ! 127: int number, size; ! 128: { ! 129: register char *newstuff; ! 130: newstuff = (char *)sbrk(number*size); ! 131: if ((int)newstuff == -1){ ! 132: yyerror("Ran out of Memory"); ! 133: delexit(); ! 134: } ! 135: return(newstuff); ! 136: } ! 137: ! 138: struct symtab * symalloc() ! 139: { ! 140: if (symsleft == 0){ ! 141: register int *p; ! 142: ! 143: newbox = (struct allocbox *)Calloc(1,ALLOCQTY); ! 144: symsleft = SYMDALLOP; ! 145: nextsym = &newbox->symslots[0]; ! 146: namebuffer = &newbox->symnames[0]; ! 147: p = (int *)(&newbox->symnames[SYMDALLOP * NCPS]); ! 148: while ( p > (int *)newbox){ ! 149: *--p = 0; ! 150: } ! 151: if (alloctail == 0){ ! 152: allochead = alloctail = newbox; ! 153: } else { ! 154: alloctail->nextalloc = newbox; ! 155: alloctail = newbox; ! 156: } ! 157: } ! 158: --symsleft; ! 159: ++nsyms; ! 160: nextsym->name = namebuffer; ! 161: namebuffer += NCPS; ! 162: return(nextsym++); ! 163: } ! 164: ! 165: symcmp(pptr, qptr) ! 166: struct symtab **pptr, **qptr; ! 167: { ! 168: register struct symtab *p = *pptr; ! 169: register struct symtab *q = *qptr; ! 170: if (p->index < q->index) ! 171: return(-1); ! 172: if (p->index > q->index) ! 173: return(1); ! 174: if (p->value < q->value) ! 175: return(-1); ! 176: if (p->value > q->value) ! 177: return(1); ! 178: /* ! 179: * Force jxxx entries to virtually preceed labels defined ! 180: * to follow the jxxxx instruction, so that bumping the ! 181: * jxxx instruction correctly fixes up the following labels ! 182: */ ! 183: if (p->tag >= IGNOREBOUND) /*p points to a jxxx*/ ! 184: return(-1); ! 185: if (q->tag >= IGNOREBOUND) ! 186: return(1); ! 187: /* ! 188: * both are now just plain labels; the relative order doesn't ! 189: * matter. Both can't be jxxxes, as they would have different ! 190: * values. ! 191: */ ! 192: return(0); ! 193: } /*end of symcmp*/ ! 194: ! 195: /* ! 196: * We construct the auxiliary table of pointers, symptrs and ! 197: * symdelim ! 198: * We also assign preliminary values to stab entries that did not yet ! 199: * have an absolute value (because they initially referred to ! 200: * forward references). We don't worry about .stabds, as they ! 201: * already have an estimated final value ! 202: */ ! 203: ! 204: sortsymtab() ! 205: { ! 206: register struct symtab *sp; ! 207: register struct symtab **cowalk; ! 208: register struct allocbox *allocwalk; ! 209: struct symtab *ubsp; ! 210: int segno; ! 211: int slotno; ! 212: int symsin; /*number put into symptrs*/ ! 213: ! 214: symptrs = (struct symtab **)Calloc(nsyms + 2, sizeof *symptrs); ! 215: /* ! 216: * Allocate one word at the beginning of the symptr array ! 217: * so that backwards scans through the symptr array will ! 218: * work correctly while scanning through the zeroth segment ! 219: */ ! 220: *symptrs++ = 0; ! 221: cowalk = symptrs; ! 222: symsin = 0; ! 223: DECLITERATE(allocwalk, sp, ubsp) { ! 224: if (sp->ptype && (sp->type &STABFLAG)){ ! 225: sp->value = sp->dest->value; ! 226: sp->index = sp->dest->index; ! 227: } ! 228: if (symsin >= nsyms) ! 229: yyerror("INTERNAL ERROR: overfilled symbol table indirection table"); ! 230: *cowalk++ = sp; ! 231: symsin++; ! 232: } ! 233: if (symsin != nsyms) ! 234: yyerror("INTERNAL ERROR: installed %d syms, should have installed %d", ! 235: symsin, nsyms); ! 236: symptrub = &symptrs[nsyms ]; ! 237: qsort(symptrs, nsyms, sizeof *symptrs, symcmp); ! 238: symdelim[0] = symptrs; ! 239: for (cowalk = symptrs, sp = *cowalk, segno = 0, slotno = 1; ! 240: segno < NLOC + NLOC; ! 241: segno++, slotno++){ ! 242: for (; sp && sp->index == segno; sp = *++cowalk); ! 243: symdelim[slotno] = cowalk; /*forms the ub delimeter*/ ! 244: } ! 245: } /*end of sortsymtab*/ ! 246: ! 247: #ifdef DEBUG ! 248: dumpsymtab() ! 249: { ! 250: register int segno; ! 251: register struct symtab *sp, **cosp, *ub; ! 252: char *tagstring(); ! 253: ! 254: printf("Symbol Table dump:\n"); ! 255: for (segno = 0; segno < NLOC + NLOC; segno++){ ! 256: printf("Segment number: %d\n", segno); ! 257: SEGITERATE(segno, 0, 0, cosp, sp, ub, ++){ ! 258: printf("\tSeg: %d \"%8.8s\" value: %d index: %d tag %s\n", ! 259: segno, sp->name, sp->value, sp->index, tagstring(sp->tag)); ! 260: printf("\t\ttype: %d jxbump %d jxfear: %d\n", ! 261: sp->type, sp->jxbump, sp->jxfear); ! 262: } ! 263: printf("\n\n"); ! 264: } ! 265: } ! 266: ! 267: static char tagbuff[4]; ! 268: ! 269: char *tagstring(tag) ! 270: unsigned char tag; ! 271: { ! 272: switch(tag){ ! 273: case JXACTIVE: return("active"); ! 274: case JXNOTYET: return("notyet"); ! 275: case JXALIGN: return("align"); ! 276: case JXQUESTIONABLE: return("jxquestionable"); ! 277: case JXINACTIVE: return("inactive"); ! 278: case JXTUNNEL: return("tunnel"); ! 279: case OBSOLETE: return("obsolete"); ! 280: case IGNOREBOUND: return("ignorebound"); ! 281: case STABFLOATING: return("stabfloating"); ! 282: case STABFIXED: return("stabfixed"); ! 283: case LABELID: return("labelid"); ! 284: case OKTOBUMP: return("oktobump"); ! 285: case ISET: return("iset"); ! 286: case ILSYM: return("ilsym"); ! 287: default: sprintf(tagbuff,"%d", tag); ! 288: return(tagbuff); ! 289: } ! 290: } ! 291: #endif ! 292: ! 293: #define HASHCLOGGED (NHASH * 3 ) / 4 ! 294: ! 295: struct symtab **lookup(instflg) ! 296: int instflg; /* 0: don't install */ ! 297: { ! 298: register int ihash; ! 299: register struct symtab **hp; ! 300: register char *p1, *p2; ! 301: register int i; ! 302: ! 303: #ifdef METRIC ! 304: nhashed++; ! 305: #endif ! 306: ! 307: /* ! 308: * All strings passed in in yytext had better have ! 309: * a trailing null. Strings are placed in yytext for ! 310: * hashing by syminstall() and yylex() ! 311: */ ! 312: for (ihash = 0, p1 = yytext ; *p1; ihash <<= 2, ihash += *p1++); ! 313: ihash += p1[-1] << 5; ! 314: ihash %= NHASH; ! 315: if (ihash < 0) ihash += NHASH; ! 316: hp = &hshtab[ihash]; ! 317: ihash = 1; /*now, it counts the number of times we rehash*/ ! 318: while (*hp) { ! 319: p1 = yytext; ! 320: p2 = (*hp)->name; ! 321: for (i = 0; (i<NCPS) && *p1; i++) ! 322: if (*p1++ != *p2++) ! 323: goto no; ! 324: if (i >= NCPS) /*both symbols are maximal length*/ ! 325: return(hp); ! 326: if (*p2 == 0) /*assert *p1 == 0*/ ! 327: return(hp); ! 328: no: ! 329: #ifdef METRIC ! 330: nhcollisions++; ! 331: #endif ! 332: hp += ihash; ! 333: ihash += 2; ! 334: if (hp >= &hshtab[NHASH]) ! 335: hp -= NHASH; ! 336: } ! 337: if(++hshused >= HASHCLOGGED) { ! 338: yyerror("Symbol table overflow"); ! 339: delexit(); ! 340: } ! 341: if (instflg) { ! 342: #ifdef METRIC ! 343: nentered++; ! 344: #endif ! 345: *hp = symalloc(); ! 346: p1 = yytext; ! 347: p2 = (*hp)->name; ! 348: while (*p2++ = *p1++); ! 349: } ! 350: return(hp); ! 351: } /*end of symlook*/ ! 352: ! 353: #ifdef vax ! 354: #define writel(p,n,f) fwrite((long)p, sizeof (long), n, f) ! 355: #else ! 356: writel(p,n,f) ! 357: long *p; ! 358: FILE *f; ! 359: { ! 360: while (n--) { ! 361: fwrite(&(*p).loword,2,1,f); ! 362: fwrite(&(*p).hiword,2,1,f); ! 363: p++; ! 364: } ! 365: } ! 366: #endif ! 367: ! 368: int reflen[] = {0,0,1,1,2,2,4,4,8,8}; ! 369: ! 370: /* ! 371: * Save the relocation information ! 372: */ ! 373: outrel(pval,reftype,reltype,xsym) ! 374: long *pval; ! 375: register int reftype,reltype; ! 376: struct symtab *xsym; ! 377: { ! 378: ! 379: /* ! 380: * reftype: PCREL or not, plus length LEN1, LEN2, LEN4, LEN8 ! 381: * reltype: csect ("segment") number (XTEXT, XDATA, ...) associated with 'val' ! 382: * xsym: symbol table pointer ! 383: */ ! 384: long ts; ! 385: char tc; ! 386: long tl; ! 387: short t; ! 388: if (passno!=2) { ! 389: dotp->xvalue += reflen[reftype]; ! 390: return; ! 391: } ! 392: if (bitoff&07) ! 393: yyerror("Padding error"); ! 394: reltype &= ~XFORW; ! 395: if (reltype == XUNDEF) ! 396: yyerror("Undefined reference"); ! 397: if (reltype != XABS || reftype & PCREL) { ! 398: /* write the address portion of a relocation datum */ ! 399: if (dotp >= &usedot[NLOC]) { ! 400: hdr.drsize += sizeof(dotp->xvalue) + 3 + sizeof tc; ! 401: tl = dotp->xvalue-datbase; ! 402: writel(&tl,1,relfil); ! 403: } else { ! 404: hdr.trsize += sizeof(dotp->xvalue) + 3 + sizeof tc; ! 405: writel(&dotp->xvalue,1,relfil); ! 406: } ! 407: /* write the properties portion of a relocation datum */ ! 408: if (reltype == XXTRN+XUNDEF) { ! 409: ts = (xsym->index); ! 410: tc = (XXTRN<<3) | (reftype-LEN1); ! 411: } else if ((reltype&XTYPE) == XUNDEFO) { ! 412: ts = (xsym->index); ! 413: tc = ((XXTRN+2)<<3) | (reftype-LEN1); ! 414: } else { ! 415: ts = (reltype); ! 416: tc = (reftype-LEN1); ! 417: } ! 418: fwrite((char *)&ts, 3, 1, relfil); ! 419: fwrite(&tc, sizeof(tc), 1, relfil); ! 420: } ! 421: /* write the raw ("unrelocated") value to the text file */ ! 422: t = reflen[reftype]; ! 423: dotp->xvalue += t; ! 424: if (reftype & PCREL) ! 425: *pval -= dotp->xvalue; ! 426: #ifdef vax ! 427: fwrite(pval,1,t,txtfil); ! 428: #else ! 429: if (t>2) { ! 430: fwrite(&((*pval).loword),1,2,txtfil); ! 431: fwrite(&((*pval).hiword),1,t-2,txtfil); ! 432: } else fwrite(&((*pval).loword),1,t,txtfil); ! 433: #endif ! 434: } ! 435: ! 436: ! 437: /* ! 438: * Write out n symbols to file f, beginning at p ! 439: * ignoring symbols that are obsolete, jxxx instructions, and ! 440: * possibly, labels ! 441: */ ! 442: ! 443: int sizesymtab() ! 444: { ! 445: struct symtab *sp; ! 446: ! 447: #define NOUTSYMS (nsyms - njxxx - nforgotten - (savelabels ? 0 : nlabels)) ! 448: ! 449: return ( ! 450: ( NCPS ! 451: + sizeof (sp->ptype) ! 452: + sizeof (sp->other) ! 453: + sizeof (sp->desc) ! 454: + sizeof (sp->value) ! 455: ) ! 456: * NOUTSYMS ! 457: ); ! 458: } ! 459: ! 460: symwrite(f) ! 461: FILE *f; ! 462: { ! 463: int symsout; /*those actually written*/ ! 464: int symsdesired = NOUTSYMS; ! 465: register struct symtab *sp, *ub; ! 466: #ifdef SORTEDOUTPUT ! 467: int segno; ! 468: register struct symtab **copointer; ! 469: #else ! 470: register struct allocbox *allocwalk; ! 471: #endif ! 472: ! 473: #ifdef SORTEDOUTPUT ! 474: for (segno = 0, symsout = 0; segno < NLOC + NLOC; segno++) ! 475: SEGITERATE(segno, 0, 0, copointer, sp, ub, ++) ! 476: #else ! 477: symsout = 0; ! 478: DECLITERATE(allocwalk, sp, ub) ! 479: #endif ! 480: { ! 481: if (sp->tag >= IGNOREBOUND) ! 482: continue; ! 483: if ((sp->name[0] == 'L') && (sp->tag == LABELID) && !savelabels) ! 484: continue; ! 485: symsout++; ! 486: fwrite(sp->name, NCPS, 1, f); ! 487: sp->type &= ~XFORW; ! 488: fwrite((sp->ptype) ? (char *)(&(sp->ptype)) : (char *)(&(sp->type)), ! 489: sizeof(char), 1, f); ! 490: /* ! 491: * WATCH OUT. THIS DEPENDS THAT THE ALLOCATION OF ! 492: * the four fields ptype, other, desc and value are ! 493: * contiguous. This may have to be changed! ! 494: * This is safe (as of 2-Nov-79). ! 495: */ ! 496: fwrite(&(sp->other), ! 497: sizeof (sp->other) ! 498: + sizeof (sp->desc) ! 499: + sizeof (sp->value), 1, f ! 500: ); ! 501: #ifdef fooie ! 502: #ifdef vax ! 503: fwrite(&(sp->name[0]), sizeof(symtab[0].name), 1, f); ! 504: fwrite(sp->ptype ? &(sp->ptype) : &(sp->type), ! 505: sizeof(symtab[0].type), 1, f); ! 506: fwrite(&(sp->other), sizeof(symtab[0].other), 1, f); ! 507: fwrite(&(sp->desc), sizeof(symtab[0].desc), 1, f); ! 508: fwrite(&(sp->value), sizeof(symtab[0].value), 1, f); ! 509: #else ! 510: writel(&(p->value), 1, f); ! 511: #endif ! 512: #endif ! 513: } ! 514: if (symsout != symsdesired) ! 515: yyerror("INTERNAL ERROR: Wrote %d symbols, wanted to write %d symbols\n", ! 516: symsout, symsdesired); ! 517: } ! 518: ! 519: Flushfield(n) ! 520: register int n; ! 521: { ! 522: while (n>0) { ! 523: outb(bitfield); ! 524: bitfield >>= 8; ! 525: n -= 8; ! 526: } ! 527: bitoff=0; ! 528: bitfield=0; ! 529: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.