1*5828Srrh /* 2*5828Srrh * Copyright (c) 1982 Regents of the University of California 3*5828Srrh */ 4*5828Srrh #ifndef lint 5*5828Srrh static char sccsid[] = "@(#)assyms.c 4.7 02/14/82"; 6*5828Srrh #endif not lint 7*5828Srrh 8600Sbill #include <stdio.h> 9600Sbill #include <ctype.h> 10600Sbill #include "as.h" 11600Sbill #include "asscan.h" 12600Sbill #include "assyms.h" 13600Sbill 14600Sbill /* 15600Sbill * Managers for chunks of symbols allocated from calloc() 16600Sbill * We maintain a linked list of such chunks. 17600Sbill * 18600Sbill */ 19600Sbill struct allocbox *allochead; /*head of chunk list*/ 20600Sbill struct allocbox *alloctail; /*tail*/ 21600Sbill struct allocbox *newbox; /*for creating a new chunk*/ 22600Sbill struct symtab *nextsym; /*next symbol free*/ 23600Sbill int symsleft; /*slots left in current chunk*/ 24600Sbill 25600Sbill struct symtab **symptrs; 26600Sbill struct symtab **symdelim[NLOC + NLOC +1]; 27600Sbill struct symtab **symptrub; 28600Sbill /* 29600Sbill * Managers for the dynamically extendable hash table 30600Sbill */ 31600Sbill struct hashdallop *htab; 32600Sbill 33*5828Srrh Iptr *itab[NINST]; /*maps opcodes to instructions*/ 34600Sbill /* 35600Sbill * Counts what went into the symbol table, so that the 36600Sbill * size of the symbol table can be computed. 37600Sbill */ 38600Sbill int nsyms; /* total number in the symbol table */ 39600Sbill int njxxx; /* number of jxxx entrys */ 40600Sbill int nforgotten; /* number of symbols erroneously entered */ 41600Sbill int nlabels; /* number of label entries */ 42600Sbill 43600Sbill /* 44600Sbill * Managers of the symbol literal storage. 45600Sbill * If we have flexible names, then we allocate BUFSIZ long 46600Sbill * string, and pack strings into that. Otherwise, we allocate 47600Sbill * symbol storage in fixed hunks NCPS long when we allocate space 48600Sbill * for other symbol attributes. 49600Sbill */ 50600Sbill #ifdef FLEXNAMES 51600Sbill struct strpool *strplhead = 0; 52634Shenry #endif FLEXNAMES 53600Sbill 54600Sbill symtabinit() 55600Sbill { 56600Sbill allochead = 0; 57600Sbill alloctail = 0; 58600Sbill nextsym = 0; 59600Sbill symsleft = 0; 60600Sbill #ifdef FLEXNAMES 61600Sbill strpoolalloc(); /* get the first strpool storage area */ 62600Sbill #endif FLEXNAMES 63600Sbill htab = 0; 64600Sbill htaballoc(); /* get the first part of the hash table */ 65600Sbill } 66600Sbill 67600Sbill /* 68600Sbill * Install all known instructions in the symbol table 69600Sbill */ 70600Sbill syminstall() 71600Sbill { 72*5828Srrh register Iptr ip; 73600Sbill register struct symtab **hp; 74600Sbill register char *p1, *p2; 75*5828Srrh register int i; 76600Sbill 77*5828Srrh for (i = 0; i < NINST; i++) 78*5828Srrh itab[i] = (Iptr*)BADPOINT; 79*5828Srrh 80634Shenry #ifdef FLEXNAMES 81*5828Srrh for (ip = (Iptr)instab; ip->s_name != 0; ip++) { 82634Shenry #else not FLEXNAMES 83*5828Srrh for (ip = (Iptr)instab; ip->s_name[0] != '\0'; ip++){ 84634Shenry #endif not FLEXNAMES 85634Shenry p1 = ip->s_name; 86600Sbill p2 = yytext; 87600Sbill while (*p2++ = *p1++); 88600Sbill hp = lookup(0); /* 0 => don't install this*/ 89600Sbill if (*hp==NULL) { 90600Sbill *hp = (struct symtab *)ip; 91634Shenry if ( (ip->s_tag!=INSTn) 92634Shenry && (ip->s_tag!=INST0) 93634Shenry && (ip->s_tag!=0)) 94600Sbill continue; /* was pseudo-op */ 95*5828Srrh if (itab[ip->i_eopcode] == (Iptr*)BADPOINT){ 96*5828Srrh itab[ip->i_eopcode] = 97*5828Srrh (Iptr*)ClearCalloc(256, sizeof(Iptr)); 98*5828Srrh for (i = 0; i < 256; i++) 99*5828Srrh itab[ip->i_eopcode][i] = 100*5828Srrh (Iptr)BADPOINT; 101*5828Srrh } 102*5828Srrh itab[ip->i_eopcode][ip->i_popcode] = ip; 103600Sbill } 104600Sbill } 105600Sbill } /*end of syminstall*/ 106600Sbill 107600Sbill 108600Sbill /* 109600Sbill * Assign final values to symbols, 110600Sbill * and overwrite the index field with its relative position in 111600Sbill * the symbol table we give to the loader. 112600Sbill */ 113600Sbill extern struct exec hdr; 114600Sbill 115600Sbill freezesymtab() 116600Sbill { 117600Sbill register struct symtab *sp; 118600Sbill long bs; 119600Sbill register int relpos = 0; 120600Sbill register struct symtab *ubsp; 121600Sbill register struct allocbox *allocwalk; 122600Sbill 123600Sbill DECLITERATE(allocwalk, sp, ubsp) 124600Sbill { 125634Shenry if (sp->s_tag >= IGNOREBOUND) 126600Sbill continue; /*totally ignore jxxx entries */ 127600Sbill /* 128600Sbill * Ignore stabs, but give them a symbol table index 129600Sbill */ 130634Shenry if (sp->s_type & STABFLAG) 131600Sbill goto assignindex; 132634Shenry if ((sp->s_type&XTYPE)==XUNDEF) 133634Shenry sp->s_type = XXTRN+XUNDEF; 134634Shenry else if ((sp->s_type&XTYPE)==XDATA) 135634Shenry sp->s_value += usedot[sp->s_index].e_xvalue; 136634Shenry else if ((sp->s_type&XTYPE)==XTEXT) 137634Shenry sp->s_value += usedot[sp->s_index].e_xvalue; 138634Shenry else if ((sp->s_type&XTYPE)==XBSS) { 139634Shenry bs = sp->s_value; 140634Shenry sp->s_value = hdr.a_bss + datbase; 141600Sbill hdr.a_bss += bs; 142600Sbill } 143600Sbill assignindex: 144634Shenry if ( (sp->s_name[0] != 'L') 145634Shenry || (sp->s_tag != LABELID) 146600Sbill || savelabels 147600Sbill ) /*then, we will write it later on*/ 148634Shenry sp->s_index = relpos++; 149600Sbill } 150600Sbill } 151600Sbill 152600Sbill 153600Sbill 154600Sbill /* 155600Sbill * For all of the stabs that had their final value undefined during pass 1 156600Sbill * and during pass 2 assign a final value. 157600Sbill * We have already given stab entrys a initial approximation 158600Sbill * when we constsructed the sorted symbol table. 159600Sbill * Iteration order doesn't matter. 160600Sbill */ 161600Sbill stabfix() { 162600Sbill register struct symtab *sp, **cosp; 163600Sbill register struct symtab *p; 164600Sbill 165600Sbill SYMITERATE(cosp, sp){ 166634Shenry if(sp->s_ptype && (sp->s_type & STABFLAG)) { 167634Shenry p = sp->s_dest; 168634Shenry sp->s_value = p->s_value; 169634Shenry sp->s_index = p->s_index; 170634Shenry sp->s_type = p->s_type; 171600Sbill } 172600Sbill } 173600Sbill } 174600Sbill 175600Sbill char *Calloc(number, size) 176600Sbill int number, size; 177600Sbill { 178600Sbill register char *newstuff; 179*5828Srrh char *sbrk(); 180*5828Srrh newstuff = sbrk(number*size); 181600Sbill if ((int)newstuff == -1){ 182600Sbill yyerror("Ran out of Memory"); 183600Sbill delexit(); 184600Sbill } 185600Sbill return(newstuff); 186600Sbill } 187600Sbill 188600Sbill char *ClearCalloc(number, size) 189600Sbill int number, size; 190600Sbill { 191600Sbill register char *newstuff; /* r11 */ 192600Sbill register int length = number * size; /* r10 */ 193*5828Srrh #ifdef lint 194*5828Srrh length = length; 195*5828Srrh #endif length 196600Sbill newstuff = Calloc(number, size); 197600Sbill asm("movc5 $0, (r0), $0, r10, (r11)"); 198600Sbill return(newstuff); 199600Sbill } 200600Sbill 201600Sbill struct symtab *symalloc() 202600Sbill { 203600Sbill if (symsleft == 0){ 204600Sbill newbox = (struct allocbox *)ClearCalloc(1,ALLOCQTY); 205600Sbill symsleft = SYMDALLOP; 206600Sbill nextsym = &newbox->symslots[0]; 207600Sbill if (alloctail == 0){ 208600Sbill allochead = alloctail = newbox; 209600Sbill } else { 210600Sbill alloctail->nextalloc = newbox; 211600Sbill alloctail = newbox; 212600Sbill } 213600Sbill } 214600Sbill --symsleft; 215600Sbill ++nsyms; 216600Sbill return(nextsym++); 217600Sbill } 218600Sbill 219600Sbill #ifdef FLEXNAMES 220600Sbill strpoolalloc() 221600Sbill { 222600Sbill register struct strpool *new; 223600Sbill 224600Sbill new = (struct strpool *)Calloc(1, sizeof (struct strpool)); 225600Sbill new->str_nalloc = 0; 226600Sbill new->str_next = strplhead; 227600Sbill strplhead = new; 228600Sbill } 229600Sbill #endif FLEXNAMES 230600Sbill 231600Sbill symcmp(Pptr, Qptr) 232600Sbill struct symtab **Pptr, **Qptr; 233600Sbill { 234600Sbill register struct symtab *p = *Pptr; 235600Sbill register struct symtab *q = *Qptr; 236634Shenry if (p->s_index < q->s_index) 237600Sbill return(-1); 238634Shenry if (p->s_index > q->s_index) 239600Sbill return(1); 240634Shenry if (p->s_value < q->s_value) 241600Sbill return(-1); 242634Shenry if (p->s_value > q->s_value) 243600Sbill return(1); 244600Sbill /* 245600Sbill * Force jxxx entries to virtually preceed labels defined 246600Sbill * to follow the jxxxx instruction, so that bumping the 247600Sbill * jxxx instruction correctly fixes up the following labels 248600Sbill */ 249634Shenry if (p->s_tag >= IGNOREBOUND) /*p points to a jxxx*/ 250600Sbill return(-1); 251634Shenry if (q->s_tag >= IGNOREBOUND) 252600Sbill return(1); 253600Sbill /* 254600Sbill * both are now just plain labels; the relative order doesn't 255600Sbill * matter. Both can't be jxxxes, as they would have different 256600Sbill * values. 257600Sbill */ 258600Sbill return(0); 259600Sbill } /*end of symcmp*/ 260600Sbill 261600Sbill /* 262600Sbill * We construct the auxiliary table of pointers, symptrs and 263600Sbill * symdelim 264600Sbill * We also assign preliminary values to stab entries that did not yet 265600Sbill * have an absolute value (because they initially referred to 266600Sbill * forward references). We don't worry about .stabds, as they 267600Sbill * already have an estimated final value 268600Sbill */ 269600Sbill 270600Sbill sortsymtab() 271600Sbill { 272600Sbill register struct symtab *sp; 273600Sbill register struct symtab **cowalk; 274600Sbill register struct allocbox *allocwalk; 275600Sbill struct symtab *ubsp; 276600Sbill int segno; 277600Sbill int slotno; 278600Sbill int symsin; /*number put into symptrs*/ 279600Sbill 280600Sbill symptrs = (struct symtab **)Calloc(nsyms + 2, sizeof *symptrs); 281600Sbill /* 282600Sbill * Allocate one word at the beginning of the symptr array 283600Sbill * so that backwards scans through the symptr array will 284600Sbill * work correctly while scanning through the zeroth segment 285600Sbill */ 286600Sbill *symptrs++ = 0; 287600Sbill cowalk = symptrs; 288600Sbill symsin = 0; 289600Sbill DECLITERATE(allocwalk, sp, ubsp) { 290634Shenry if (sp->s_ptype && (sp->s_type &STABFLAG)){ 291634Shenry sp->s_value = sp->s_dest->s_value; 292634Shenry sp->s_index = sp->s_dest->s_index; 293600Sbill } 294600Sbill if (symsin >= nsyms) 295600Sbill yyerror("INTERNAL ERROR: overfilled symbol table indirection table"); 296600Sbill *cowalk++ = sp; 297600Sbill symsin++; 298600Sbill } 299600Sbill if (symsin != nsyms) 300600Sbill yyerror("INTERNAL ERROR: installed %d syms, should have installed %d", 301600Sbill symsin, nsyms); 302600Sbill symptrub = &symptrs[nsyms ]; 303600Sbill qsort(symptrs, nsyms, sizeof *symptrs, symcmp); 304600Sbill symdelim[0] = symptrs; 305600Sbill for (cowalk = symptrs, sp = *cowalk, segno = 0, slotno = 1; 306600Sbill segno < NLOC + NLOC; 307600Sbill segno++, slotno++){ 308634Shenry for (; sp && sp->s_index == segno; sp = *++cowalk); 309600Sbill symdelim[slotno] = cowalk; /*forms the ub delimeter*/ 310600Sbill } 311600Sbill } /*end of sortsymtab*/ 312600Sbill 313600Sbill #ifdef DEBUG 314600Sbill dumpsymtab() 315600Sbill { 316600Sbill register int segno; 317600Sbill register struct symtab *sp, **cosp, *ub; 318600Sbill char *tagstring(); 319600Sbill 320600Sbill printf("Symbol Table dump:\n"); 321600Sbill for (segno = 0; segno < NLOC + NLOC; segno++){ 322600Sbill printf("Segment number: %d\n", segno); 323600Sbill SEGITERATE(segno, 0, 0, cosp, sp, ub, ++){ 324600Sbill #ifdef FLEXNAMES 325600Sbill printf("\tSeg: %d \"%s\" value: %d index: %d tag %s\n", 326634Shenry segno, sp->s_name, 327634Shenry sp->s_value, sp->s_index, 328634Shenry tagstring(sp->s_tag)); 329600Sbill #else not FLEXNAMES 330600Sbill printf("\tSeg: %d \"%*.*s\" value: %d index: %d tag %s\n", 331634Shenry segno, NCPS, NCPS, sp->s_name, 332634Shenry sp->s_value, sp->s_index, 333634Shenry tagstring(sp->s_tag)); 334600Sbill #endif not FLEXNAMES 335600Sbill printf("\t\ttype: %d jxbump %d jxfear: %d\n", 336634Shenry sp->s_type, sp->s_jxbump, sp->s_jxfear); 337600Sbill } 338600Sbill printf("\n\n"); 339600Sbill } 340600Sbill } 341600Sbill 342600Sbill static char tagbuff[4]; 343600Sbill 344600Sbill char *tagstring(tag) 345600Sbill unsigned char tag; 346600Sbill { 347600Sbill switch(tag){ 348600Sbill case JXACTIVE: return("active"); 349600Sbill case JXNOTYET: return("notyet"); 350600Sbill case JXALIGN: return("align"); 351600Sbill case JXQUESTIONABLE: return("jxquestionable"); 352600Sbill case JXINACTIVE: return("inactive"); 353600Sbill case JXTUNNEL: return("tunnel"); 354600Sbill case OBSOLETE: return("obsolete"); 355600Sbill case IGNOREBOUND: return("ignorebound"); 356600Sbill case STABFLOATING: return("stabfloating"); 357600Sbill case STABFIXED: return("stabfixed"); 358600Sbill case LABELID: return("labelid"); 359600Sbill case OKTOBUMP: return("oktobump"); 360600Sbill case ISET: return("iset"); 361600Sbill case ILSYM: return("ilsym"); 362600Sbill default: sprintf(tagbuff,"%d", tag); 363600Sbill return(tagbuff); 364600Sbill } 365600Sbill } 366600Sbill #endif DEBUG 367600Sbill 368600Sbill htaballoc() 369600Sbill { 370600Sbill register struct hashdallop *new; 371600Sbill new = (struct hashdallop *)ClearCalloc(1, sizeof (struct hashdallop)); 372600Sbill if (htab == 0) 373600Sbill htab = new; 374600Sbill else { /* add AFTER the 1st slot */ 375600Sbill new->h_next = htab->h_next; 376600Sbill htab->h_next = new; 377600Sbill } 378600Sbill } 379600Sbill 380600Sbill #define HASHCLOGGED (NHASH / 2) 381600Sbill 382600Sbill /* 383600Sbill * Lookup a symbol stored in extern yytext. 384600Sbill * All strings passed in via extern yytext had better have 385600Sbill * a trailing null. Strings are placed in yytext for hashing by 386600Sbill * syminstall() and by yylex(); 387600Sbill * 388600Sbill * We take pains to avoid function calls; this functdion 389600Sbill * is called quite frequently, and the calls overhead 390600Sbill * in the vax contributes significantly to the overall 391600Sbill * execution speed of as. 392600Sbill */ 393600Sbill struct symtab **lookup(instflg) 394600Sbill int instflg; /* 0: don't install */ 395600Sbill { 396600Sbill static int initialprobe; 397600Sbill register struct symtab **hp; 398600Sbill register char *from; 399600Sbill register char *to; 400600Sbill register int len; 401600Sbill register int nprobes; 402600Sbill static struct hashdallop *hdallop; 403600Sbill static struct symtab **emptyslot; 404600Sbill static struct hashdallop *emptyhd; 405600Sbill static struct symtab **hp_ub; 406600Sbill 407600Sbill emptyslot = 0; 408600Sbill for (nprobes = 0, from = yytext; 409600Sbill *from; 410600Sbill nprobes <<= 2, nprobes += *from++) 411600Sbill continue; 412600Sbill nprobes += from[-1] << 5; 413600Sbill nprobes %= NHASH; 414600Sbill if (nprobes < 0) 415600Sbill nprobes += NHASH; 416600Sbill 417600Sbill initialprobe = nprobes; 418600Sbill for (hdallop = htab; hdallop != 0; hdallop = hdallop->h_next){ 419600Sbill for (hp = &(hdallop->h_htab[initialprobe]), 420600Sbill nprobes = 1, 421600Sbill hp_ub = &(hdallop->h_htab[NHASH]); 422600Sbill (*hp) && (nprobes < NHASH); 423600Sbill hp += nprobes, 424600Sbill hp -= (hp >= hp_ub) ? NHASH:0, 425600Sbill nprobes += 2) 426600Sbill { 427600Sbill from = yytext; 428634Shenry to = (*hp)->s_name; 429600Sbill #ifndef FLEXNAMES 430600Sbill for (len = 0; (len<NCPS) && *from; len++) 431600Sbill if (*from++ != *to++) 432600Sbill goto nextprobe; 433600Sbill if (len >= NCPS) /*both are maximal length*/ 434600Sbill return(hp); 435600Sbill if (*to == 0) /*assert *from == 0*/ 436600Sbill return(hp); 437600Sbill #else FLEXNAMES 438600Sbill while (*from && *to) 439600Sbill if (*from++ != *to++) 440600Sbill goto nextprobe; 441600Sbill if (*to == *from) /*assert both are == 0*/ 442600Sbill return(hp); 443600Sbill #endif FLEXNAMES 444600Sbill 445600Sbill nextprobe: ; 446600Sbill } 447600Sbill if (*hp == 0 && emptyslot == 0 && 448600Sbill hdallop->h_nused < HASHCLOGGED) { 449600Sbill emptyslot = hp; 450600Sbill emptyhd = hdallop; 451600Sbill } 452600Sbill } 453600Sbill if (emptyslot == 0) { 454600Sbill htaballoc(); 455600Sbill hdallop = htab->h_next; /* aren't we smart! */ 456600Sbill hp = &hdallop->h_htab[initialprobe]; 457600Sbill } else { 458600Sbill hdallop = emptyhd; 459600Sbill hp = emptyslot; 460600Sbill } 461600Sbill if (instflg) { 462600Sbill *hp = symalloc(); 463600Sbill hdallop->h_nused++; 464600Sbill #ifndef FLEXNAMES 465634Shenry for(len = 0, from = yytext, to = (*hp)->s_name; (len<NCPS); len++) 466600Sbill if ((*to++ = *from++) == '\0') 467600Sbill break; 468600Sbill #else FLEXNAMES 469600Sbill for (from = yytext, len = 1; *from++; len++) 470600Sbill continue; 471600Sbill if (len >= (STRPOOLDALLOP - strplhead->str_nalloc)) 472600Sbill strpoolalloc(); 473634Shenry for ( (*hp)->s_name = to = strplhead->str_names + strplhead->str_nalloc, from = yytext; 474600Sbill ( (*to++ = *from++) != '\0'); ) 475600Sbill continue; 476600Sbill strplhead->str_nalloc += len; 477600Sbill #endif FLEXNAMES 478600Sbill } 479600Sbill return(hp); 480600Sbill } /*end of lookup*/ 481600Sbill 4821744Shenry #ifdef FLEXNAMES 483600Sbill char *savestr(str) 484600Sbill char *str; 485600Sbill { 486600Sbill register int len; 487600Sbill register char *from, *to; 488600Sbill char *res; 489600Sbill 490600Sbill for (from = str, len = 1; *from++; len++) 491600Sbill continue; 492600Sbill if (len >= (STRPOOLDALLOP - strplhead->str_nalloc)) 493600Sbill strpoolalloc(); 494600Sbill for ( res = to = strplhead->str_names + strplhead->str_nalloc, from = str; 495600Sbill ( (*to++ = *from++) != '\0'); ) 496600Sbill continue; 497600Sbill strplhead->str_nalloc += len; 498600Sbill return (res); 499600Sbill } 5001744Shenry #endif FLEXNAMES 501600Sbill 502600Sbill /* 503600Sbill * The relocation information is saved internally in an array of 504600Sbill * lists of relocation buffers. The relocation buffers are 505600Sbill * exactly the same size as a token buffer; if we use VM for the 506600Sbill * temporary file we reclaim this storage, otherwise we create 507600Sbill * them by mallocing. 508600Sbill */ 509600Sbill #define RELBUFLG TOKBUFLG 510600Sbill #define NRELOC ((TOKBUFLG - \ 511600Sbill (sizeof (int) + sizeof (struct relbufdesc *)) \ 512600Sbill ) / (sizeof (struct relocation_info))) 513600Sbill 514600Sbill struct relbufdesc{ 515600Sbill int rel_count; 516600Sbill struct relbufdesc *rel_next; 517600Sbill struct relocation_info rel_reloc[NRELOC]; 518600Sbill }; 519600Sbill extern struct relbufdesc *tok_free; 520600Sbill #define rel_free tok_free 521600Sbill static struct relbufdesc *rel_temp; 522634Shenry struct relocation_info r_can_1PC; 523634Shenry struct relocation_info r_can_0PC; 524600Sbill 525600Sbill initoutrel() 526600Sbill { 527634Shenry r_can_0PC.r_address = 0; 528634Shenry r_can_0PC.r_symbolnum = 0; 529634Shenry r_can_0PC.r_pcrel = 0; 530634Shenry r_can_0PC.r_length = 0; 531634Shenry r_can_0PC.r_extern = 0; 532634Shenry 533634Shenry r_can_1PC = r_can_0PC; 534600Sbill r_can_1PC.r_pcrel = 1; 535600Sbill } 536600Sbill 537675Shenry outrel(xp, reloc_how) 538675Shenry register struct exp *xp; 539*5828Srrh int reloc_how; /* TYPB..TYPH + (possibly)RELOC_PCREL */ 540600Sbill { 541675Shenry struct relocation_info reloc; 542675Shenry register int x_type_mask; 543675Shenry int pcrel; 544600Sbill 545675Shenry x_type_mask = xp->e_xtype & ~XFORW; 546675Shenry pcrel = reloc_how & RELOC_PCREL; 547675Shenry reloc_how &= ~RELOC_PCREL; 548675Shenry 549600Sbill if (bitoff&07) 550600Sbill yyerror("Padding error"); 551675Shenry if (x_type_mask == XUNDEF) 552600Sbill yyerror("Undefined reference"); 553600Sbill 554675Shenry if ( (x_type_mask != XABS) || pcrel ) { 555675Shenry if (ty_NORELOC[reloc_how]) 556*5828Srrh yyerror("Illegal Relocation of floating or large int number."); 557675Shenry reloc = pcrel ? r_can_1PC : r_can_0PC; 558634Shenry reloc.r_address = dotp->e_xvalue - 559640Sbill ( (dotp < &usedot[NLOC] || readonlydata) ? 0 : datbase ); 560675Shenry reloc.r_length = ty_nlg[reloc_how]; 561675Shenry switch(x_type_mask){ 562600Sbill case XXTRN | XUNDEF: 563675Shenry reloc.r_symbolnum = xp->e_xname->s_index; 564600Sbill reloc.r_extern = 1; 565600Sbill break; 566600Sbill default: 567675Shenry if (readonlydata && (x_type_mask&~XXTRN) == XDATA) 568675Shenry x_type_mask = XTEXT | (x_type_mask&XXTRN); 569675Shenry reloc.r_symbolnum = x_type_mask; 570600Sbill break; 571600Sbill } 572600Sbill if ( (relfil == 0) || (relfil->rel_count >= NRELOC) ){ 573600Sbill if (rel_free){ 574600Sbill rel_temp = rel_free; 575600Sbill rel_free = rel_temp->rel_next; 576600Sbill } else { 577600Sbill rel_temp = (struct relbufdesc *) 578600Sbill Calloc(1,sizeof (struct relbufdesc)); 579600Sbill } 580600Sbill rel_temp->rel_count = 0; 581600Sbill rel_temp->rel_next = relfil; 582600Sbill relfil = rusefile[dotp - &usedot[0]] = rel_temp; 583600Sbill } 584600Sbill relfil->rel_reloc[relfil->rel_count++] = reloc; 585600Sbill } 586600Sbill /* 587600Sbill * write the unrelocated value to the text file 588600Sbill */ 589675Shenry dotp->e_xvalue += ty_nbyte[reloc_how]; 590675Shenry if (pcrel) 591675Shenry xp->e_xvalue -= dotp->e_xvalue; 592*5828Srrh switch(reloc_how){ 593*5828Srrh case TYPO: 594*5828Srrh case TYPQ: 595*5828Srrh 596*5828Srrh case TYPF: 597*5828Srrh case TYPD: 598*5828Srrh case TYPG: 599*5828Srrh case TYPH: 600*5828Srrh bignumwrite(xp->e_number, reloc_how); 601*5828Srrh break; 602*5828Srrh 603*5828Srrh default: 604*5828Srrh bwrite((char *)&(xp->e_xvalue), ty_nbyte[reloc_how], txtfil); 605*5828Srrh break; 606*5828Srrh } 607600Sbill } 608600Sbill /* 609600Sbill * Flush out all of the relocation information. 610600Sbill * Note that the individual lists of buffers are in 611600Sbill * reverse order, so we must reverse them 612600Sbill */ 613600Sbill off_t closeoutrel(relocfile) 614600Sbill BFILE *relocfile; 615600Sbill { 616600Sbill int locindex; 617600Sbill u_long Closeoutrel(); 618600Sbill 619600Sbill trsize = 0; 620600Sbill for (locindex = 0; locindex < NLOC; locindex++){ 621600Sbill trsize += Closeoutrel(rusefile[locindex], relocfile); 622600Sbill } 623600Sbill drsize = 0; 624600Sbill for (locindex = 0; locindex < NLOC; locindex++){ 625600Sbill drsize += Closeoutrel(rusefile[NLOC + locindex], relocfile); 626600Sbill } 627600Sbill return(trsize + drsize); 628600Sbill } 629600Sbill 630600Sbill u_long Closeoutrel(relfil, relocfile) 631600Sbill struct relbufdesc *relfil; 632600Sbill BFILE *relocfile; 633600Sbill { 634600Sbill u_long tail; 635600Sbill if (relfil == 0) 636600Sbill return(0L); 637600Sbill tail = Closeoutrel(relfil->rel_next, relocfile); 638600Sbill bwrite((char *)&relfil->rel_reloc[0], 639600Sbill relfil->rel_count * sizeof (struct relocation_info), 640600Sbill relocfile); 641600Sbill return(tail + relfil->rel_count * sizeof (struct relocation_info)); 642600Sbill } 643600Sbill 644634Shenry #define NOUTSYMS (nsyms - njxxx - nforgotten - (savelabels ? 0 : nlabels)) 645600Sbill int sizesymtab() 646600Sbill { 647634Shenry return (sizeof (struct nlist) * NOUTSYMS); 648600Sbill } 649600Sbill 650600Sbill #ifdef FLEXNAMES 651600Sbill /* 652600Sbill * We write out the flexible length character strings for names 653600Sbill * in two stages. 654600Sbill * 1) We have always! maintain a fixed sized name list entry; 655600Sbill * the string is indexed by a four byte quantity from the beginning 656600Sbill * of the string pool area. Index 0 is reserved, and indicates 657600Sbill * that there is no associated string. The first valid index is 4. 658600Sbill * 2) We concatenate together and write all of the strings 659600Sbill * in the string pool at the end of the name list. The first 660600Sbill * four bytes in the string pool are indexed only by 0 (see above); 661600Sbill * they contain the total number of bytes in the string pool. 662600Sbill */ 663600Sbill #endif FLEXNAMES 664600Sbill 665600Sbill /* 666600Sbill * Write out n symbols to file f, beginning at p 667600Sbill * ignoring symbols that are obsolete, jxxx instructions, and 668600Sbill * possibly, labels 669600Sbill */ 670600Sbill 671600Sbill int symwrite(symfile) 672600Sbill BFILE *symfile; 673600Sbill { 674600Sbill int symsout; /*those actually written*/ 675600Sbill int symsdesired = NOUTSYMS; 676600Sbill register struct symtab *sp, *ub; 677600Sbill #ifdef FLEXNAMES 678634Shenry char *name; /* temp to save the name */ 679600Sbill long stroff = sizeof (stroff); 680634Shenry /* 681634Shenry * We use sp->s_index to hold the length of the 682634Shenry * name; it isn't used for anything else 683634Shenry */ 684600Sbill #endif FLEXNAMES 685600Sbill 686600Sbill register struct allocbox *allocwalk; 687600Sbill 688600Sbill symsout = 0; 689600Sbill DECLITERATE(allocwalk, sp, ub) 690600Sbill { 691634Shenry if (sp->s_tag >= IGNOREBOUND) 692600Sbill continue; 693634Shenry if ((sp->s_name[0] == 'L') && (sp->s_tag == LABELID) && !savelabels) 694600Sbill continue; 695600Sbill symsout++; 696634Shenry 697634Shenry #ifdef FLEXNAMES 698634Shenry name = sp->s_name; /* save pointer */ 699634Shenry if ( (sp->s_index = strlen(sp->s_name)) != 0){ 700634Shenry sp->s_nmx = stroff; /* clobber pointer */ 701634Shenry stroff += sp->s_index + 1; 702634Shenry } else { 703634Shenry sp->s_nmx = 0; /* clobber pointer */ 704634Shenry } 705634Shenry #endif 706634Shenry sp->s_type = (sp->s_ptype != 0) ? sp->s_ptype : (sp->s_type & (~XFORW)); 707640Sbill if (readonlydata && (sp->s_type&~N_EXT) == N_DATA) 708640Sbill sp->s_type = N_TEXT | (sp->s_type & N_EXT); 709*5828Srrh bwrite((char *)&sp->s_nm, sizeof (struct nlist), symfile); 710634Shenry #ifdef FLEXNAMES 711634Shenry sp->s_name = name; /* restore pointer */ 712600Sbill #endif FLEXNAMES 713600Sbill } 714600Sbill if (symsout != symsdesired) 715600Sbill yyerror("INTERNAL ERROR: Wrote %d symbols, wanted to write %d symbols\n", 716600Sbill symsout, symsdesired); 717600Sbill #ifdef FLEXNAMES 718600Sbill /* 719600Sbill * Pass 2 through the string pool 720600Sbill */ 721600Sbill symsout = 0; 722*5828Srrh bwrite((char *)&stroff, sizeof (stroff), symfile); 723600Sbill stroff = sizeof (stroff); 724600Sbill symsout = 0; 725600Sbill DECLITERATE(allocwalk, sp, ub) 726600Sbill { 727634Shenry if (sp->s_tag >= IGNOREBOUND) 728600Sbill continue; 729634Shenry if ((sp->s_name[0] == 'L') && (sp->s_tag == LABELID) && !savelabels) 730600Sbill continue; 731634Shenry sp->s_index = strlen(sp->s_name); 732634Shenry if (sp->s_index) 733634Shenry bwrite(sp->s_name, sp->s_index + 1, symfile); 734600Sbill } 735600Sbill #endif FLEXNAMES 736600Sbill } 737