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