15828Srrh /* 25828Srrh * Copyright (c) 1982 Regents of the University of California 35828Srrh */ 45828Srrh #ifndef lint 5*13447Srrh static char sccsid[] = "@(#)assyms.c 4.9 06/29/83"; 65828Srrh #endif not lint 75828Srrh 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 335828Srrh 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 struct strpool *strplhead = 0; 51600Sbill 52600Sbill symtabinit() 53600Sbill { 54600Sbill allochead = 0; 55600Sbill alloctail = 0; 56600Sbill nextsym = 0; 57600Sbill symsleft = 0; 58600Sbill strpoolalloc(); /* get the first strpool storage area */ 59600Sbill htab = 0; 60600Sbill htaballoc(); /* get the first part of the hash table */ 61600Sbill } 62600Sbill 63600Sbill /* 64600Sbill * Install all known instructions in the symbol table 65600Sbill */ 66600Sbill syminstall() 67600Sbill { 685828Srrh register Iptr ip; 69600Sbill register struct symtab **hp; 70600Sbill register char *p1, *p2; 715828Srrh register int i; 72600Sbill 735828Srrh for (i = 0; i < NINST; i++) 745828Srrh itab[i] = (Iptr*)BADPOINT; 755828Srrh 76634Shenry #ifdef FLEXNAMES 775828Srrh for (ip = (Iptr)instab; ip->s_name != 0; ip++) { 78634Shenry #else not FLEXNAMES 795828Srrh for (ip = (Iptr)instab; ip->s_name[0] != '\0'; ip++){ 80634Shenry #endif not FLEXNAMES 81634Shenry p1 = ip->s_name; 82600Sbill p2 = yytext; 83600Sbill while (*p2++ = *p1++); 84600Sbill hp = lookup(0); /* 0 => don't install this*/ 85600Sbill if (*hp==NULL) { 86600Sbill *hp = (struct symtab *)ip; 87634Shenry if ( (ip->s_tag!=INSTn) 88634Shenry && (ip->s_tag!=INST0) 89634Shenry && (ip->s_tag!=0)) 90600Sbill continue; /* was pseudo-op */ 915828Srrh if (itab[ip->i_eopcode] == (Iptr*)BADPOINT){ 925828Srrh itab[ip->i_eopcode] = 935828Srrh (Iptr*)ClearCalloc(256, sizeof(Iptr)); 945828Srrh for (i = 0; i < 256; i++) 955828Srrh itab[ip->i_eopcode][i] = 965828Srrh (Iptr)BADPOINT; 975828Srrh } 985828Srrh itab[ip->i_eopcode][ip->i_popcode] = ip; 99600Sbill } 100600Sbill } 101600Sbill } /*end of syminstall*/ 102600Sbill 103600Sbill 104600Sbill /* 105600Sbill * Assign final values to symbols, 106600Sbill * and overwrite the index field with its relative position in 107600Sbill * the symbol table we give to the loader. 108600Sbill */ 109600Sbill extern struct exec hdr; 110600Sbill 111600Sbill freezesymtab() 112600Sbill { 113600Sbill register struct symtab *sp; 114600Sbill long bs; 115600Sbill register int relpos = 0; 116600Sbill register struct symtab *ubsp; 117600Sbill register struct allocbox *allocwalk; 118600Sbill 119600Sbill DECLITERATE(allocwalk, sp, ubsp) 120600Sbill { 121634Shenry if (sp->s_tag >= IGNOREBOUND) 122600Sbill continue; /*totally ignore jxxx entries */ 123600Sbill /* 124600Sbill * Ignore stabs, but give them a symbol table index 125600Sbill */ 126634Shenry if (sp->s_type & STABFLAG) 127600Sbill goto assignindex; 128634Shenry if ((sp->s_type&XTYPE)==XUNDEF) 129634Shenry sp->s_type = XXTRN+XUNDEF; 130634Shenry else if ((sp->s_type&XTYPE)==XDATA) 131634Shenry sp->s_value += usedot[sp->s_index].e_xvalue; 132634Shenry else if ((sp->s_type&XTYPE)==XTEXT) 133634Shenry sp->s_value += usedot[sp->s_index].e_xvalue; 134634Shenry else if ((sp->s_type&XTYPE)==XBSS) { 135634Shenry bs = sp->s_value; 136634Shenry sp->s_value = hdr.a_bss + datbase; 137600Sbill hdr.a_bss += bs; 138600Sbill } 139600Sbill assignindex: 140634Shenry if ( (sp->s_name[0] != 'L') 141634Shenry || (sp->s_tag != LABELID) 142600Sbill || savelabels 143600Sbill ) /*then, we will write it later on*/ 144634Shenry sp->s_index = relpos++; 145600Sbill } 146600Sbill } 147600Sbill 148600Sbill 149600Sbill 150600Sbill /* 151600Sbill * For all of the stabs that had their final value undefined during pass 1 152600Sbill * and during pass 2 assign a final value. 153600Sbill * We have already given stab entrys a initial approximation 154600Sbill * when we constsructed the sorted symbol table. 155600Sbill * Iteration order doesn't matter. 156600Sbill */ 15712592Scsvaf 15812592Scsvaf stabfix() 15912592Scsvaf { 160600Sbill register struct symtab *sp, **cosp; 161600Sbill register struct symtab *p; 162600Sbill 163600Sbill SYMITERATE(cosp, sp){ 164634Shenry if(sp->s_ptype && (sp->s_type & STABFLAG)) { 165634Shenry p = sp->s_dest; 16612592Scsvaf /* 16712592Scsvaf * STABFLOATING indicates that the offset has been saved in s_desc, s_other 16812592Scsvaf */ 16912592Scsvaf if(sp->s_tag == STABFLOATING) { 17012592Scsvaf sp->s_value = ( ( ((unsigned char) sp->s_other) << 16) | ( (unsigned short) sp->s_desc ) ); 17112592Scsvaf sp->s_value = sp->s_value + p->s_value; 17212592Scsvaf } 17312592Scsvaf else sp->s_value = p->s_value; 174634Shenry sp->s_index = p->s_index; 175634Shenry sp->s_type = p->s_type; 17612592Scsvaf 17712592Scsvaf 178600Sbill } 179600Sbill } 180600Sbill } 181600Sbill 182600Sbill char *Calloc(number, size) 183600Sbill int number, size; 184600Sbill { 185600Sbill register char *newstuff; 1865828Srrh char *sbrk(); 1875828Srrh newstuff = sbrk(number*size); 188600Sbill if ((int)newstuff == -1){ 189600Sbill yyerror("Ran out of Memory"); 190600Sbill delexit(); 191600Sbill } 192600Sbill return(newstuff); 193600Sbill } 194600Sbill 195600Sbill char *ClearCalloc(number, size) 196600Sbill int number, size; 197600Sbill { 198600Sbill register char *newstuff; /* r11 */ 199600Sbill register int length = number * size; /* r10 */ 2005828Srrh #ifdef lint 2015828Srrh length = length; 2025828Srrh #endif length 203600Sbill newstuff = Calloc(number, size); 204600Sbill asm("movc5 $0, (r0), $0, r10, (r11)"); 205600Sbill return(newstuff); 206600Sbill } 207600Sbill 208600Sbill struct symtab *symalloc() 209600Sbill { 210600Sbill if (symsleft == 0){ 211600Sbill newbox = (struct allocbox *)ClearCalloc(1,ALLOCQTY); 212600Sbill symsleft = SYMDALLOP; 213600Sbill nextsym = &newbox->symslots[0]; 214600Sbill if (alloctail == 0){ 215600Sbill allochead = alloctail = newbox; 216600Sbill } else { 217600Sbill alloctail->nextalloc = newbox; 218600Sbill alloctail = newbox; 219600Sbill } 220600Sbill } 221600Sbill --symsleft; 222600Sbill ++nsyms; 223600Sbill return(nextsym++); 224600Sbill } 225600Sbill 226600Sbill strpoolalloc() 227600Sbill { 228600Sbill register struct strpool *new; 229600Sbill 230600Sbill new = (struct strpool *)Calloc(1, sizeof (struct strpool)); 231600Sbill new->str_nalloc = 0; 232600Sbill new->str_next = strplhead; 233600Sbill strplhead = new; 234600Sbill } 235600Sbill 236600Sbill symcmp(Pptr, Qptr) 237600Sbill struct symtab **Pptr, **Qptr; 238600Sbill { 239600Sbill register struct symtab *p = *Pptr; 240600Sbill register struct symtab *q = *Qptr; 241634Shenry if (p->s_index < q->s_index) 242600Sbill return(-1); 243634Shenry if (p->s_index > q->s_index) 244600Sbill return(1); 245634Shenry if (p->s_value < q->s_value) 246600Sbill return(-1); 247634Shenry if (p->s_value > q->s_value) 248600Sbill return(1); 249600Sbill /* 250600Sbill * Force jxxx entries to virtually preceed labels defined 251600Sbill * to follow the jxxxx instruction, so that bumping the 252600Sbill * jxxx instruction correctly fixes up the following labels 253600Sbill */ 254634Shenry if (p->s_tag >= IGNOREBOUND) /*p points to a jxxx*/ 255600Sbill return(-1); 256634Shenry if (q->s_tag >= IGNOREBOUND) 257600Sbill return(1); 258600Sbill /* 259600Sbill * both are now just plain labels; the relative order doesn't 260600Sbill * matter. Both can't be jxxxes, as they would have different 261600Sbill * values. 262600Sbill */ 263600Sbill return(0); 264600Sbill } /*end of symcmp*/ 265600Sbill 266600Sbill /* 267600Sbill * We construct the auxiliary table of pointers, symptrs and 268600Sbill * symdelim 269600Sbill * We also assign preliminary values to stab entries that did not yet 270600Sbill * have an absolute value (because they initially referred to 271600Sbill * forward references). We don't worry about .stabds, as they 272600Sbill * already have an estimated final value 273600Sbill */ 274600Sbill 275600Sbill sortsymtab() 276600Sbill { 277600Sbill register struct symtab *sp; 278600Sbill register struct symtab **cowalk; 279600Sbill register struct allocbox *allocwalk; 280600Sbill struct symtab *ubsp; 281600Sbill int segno; 282600Sbill int slotno; 283600Sbill int symsin; /*number put into symptrs*/ 284600Sbill 285600Sbill symptrs = (struct symtab **)Calloc(nsyms + 2, sizeof *symptrs); 286600Sbill /* 287600Sbill * Allocate one word at the beginning of the symptr array 288600Sbill * so that backwards scans through the symptr array will 289600Sbill * work correctly while scanning through the zeroth segment 290600Sbill */ 291600Sbill *symptrs++ = 0; 292600Sbill cowalk = symptrs; 293600Sbill symsin = 0; 294600Sbill DECLITERATE(allocwalk, sp, ubsp) { 295634Shenry if (sp->s_ptype && (sp->s_type &STABFLAG)){ 296634Shenry sp->s_value = sp->s_dest->s_value; 297634Shenry sp->s_index = sp->s_dest->s_index; 298600Sbill } 299600Sbill if (symsin >= nsyms) 300600Sbill yyerror("INTERNAL ERROR: overfilled symbol table indirection table"); 301600Sbill *cowalk++ = sp; 302600Sbill symsin++; 303600Sbill } 304600Sbill if (symsin != nsyms) 305600Sbill yyerror("INTERNAL ERROR: installed %d syms, should have installed %d", 306600Sbill symsin, nsyms); 307600Sbill symptrub = &symptrs[nsyms ]; 308600Sbill qsort(symptrs, nsyms, sizeof *symptrs, symcmp); 309600Sbill symdelim[0] = symptrs; 310600Sbill for (cowalk = symptrs, sp = *cowalk, segno = 0, slotno = 1; 311600Sbill segno < NLOC + NLOC; 312600Sbill segno++, slotno++){ 313634Shenry for (; sp && sp->s_index == segno; sp = *++cowalk); 314600Sbill symdelim[slotno] = cowalk; /*forms the ub delimeter*/ 315600Sbill } 316600Sbill } /*end of sortsymtab*/ 317600Sbill 318600Sbill #ifdef DEBUG 319600Sbill dumpsymtab() 320600Sbill { 321600Sbill register int segno; 322600Sbill register struct symtab *sp, **cosp, *ub; 323600Sbill char *tagstring(); 324600Sbill 325600Sbill printf("Symbol Table dump:\n"); 326600Sbill for (segno = 0; segno < NLOC + NLOC; segno++){ 327600Sbill printf("Segment number: %d\n", segno); 328600Sbill SEGITERATE(segno, 0, 0, cosp, sp, ub, ++){ 329600Sbill #ifdef FLEXNAMES 330600Sbill printf("\tSeg: %d \"%s\" value: %d index: %d tag %s\n", 331634Shenry segno, sp->s_name, 332634Shenry sp->s_value, sp->s_index, 333634Shenry tagstring(sp->s_tag)); 334600Sbill #else not FLEXNAMES 335600Sbill printf("\tSeg: %d \"%*.*s\" value: %d index: %d tag %s\n", 336634Shenry segno, NCPS, NCPS, sp->s_name, 337634Shenry sp->s_value, sp->s_index, 338634Shenry tagstring(sp->s_tag)); 339600Sbill #endif not FLEXNAMES 340600Sbill printf("\t\ttype: %d jxbump %d jxfear: %d\n", 341634Shenry sp->s_type, sp->s_jxbump, sp->s_jxfear); 342600Sbill } 343600Sbill printf("\n\n"); 344600Sbill } 345600Sbill } 346600Sbill 347600Sbill static char tagbuff[4]; 348600Sbill 349600Sbill char *tagstring(tag) 350600Sbill unsigned char tag; 351600Sbill { 352600Sbill switch(tag){ 353600Sbill case JXACTIVE: return("active"); 354600Sbill case JXNOTYET: return("notyet"); 355600Sbill case JXALIGN: return("align"); 356600Sbill case JXQUESTIONABLE: return("jxquestionable"); 357600Sbill case JXINACTIVE: return("inactive"); 358600Sbill case JXTUNNEL: return("tunnel"); 359600Sbill case OBSOLETE: return("obsolete"); 360600Sbill case IGNOREBOUND: return("ignorebound"); 361600Sbill case STABFLOATING: return("stabfloating"); 362600Sbill case STABFIXED: return("stabfixed"); 363600Sbill case LABELID: return("labelid"); 364600Sbill case OKTOBUMP: return("oktobump"); 365600Sbill case ISET: return("iset"); 366600Sbill case ILSYM: return("ilsym"); 367600Sbill default: sprintf(tagbuff,"%d", tag); 368600Sbill return(tagbuff); 369600Sbill } 370600Sbill } 371600Sbill #endif DEBUG 372600Sbill 373600Sbill htaballoc() 374600Sbill { 375600Sbill register struct hashdallop *new; 376600Sbill new = (struct hashdallop *)ClearCalloc(1, sizeof (struct hashdallop)); 377600Sbill if (htab == 0) 378600Sbill htab = new; 379600Sbill else { /* add AFTER the 1st slot */ 380600Sbill new->h_next = htab->h_next; 381600Sbill htab->h_next = new; 382600Sbill } 383600Sbill } 384600Sbill 385600Sbill #define HASHCLOGGED (NHASH / 2) 386600Sbill 387600Sbill /* 388600Sbill * Lookup a symbol stored in extern yytext. 389600Sbill * All strings passed in via extern yytext had better have 390600Sbill * a trailing null. Strings are placed in yytext for hashing by 391600Sbill * syminstall() and by yylex(); 392600Sbill * 393600Sbill * We take pains to avoid function calls; this functdion 394600Sbill * is called quite frequently, and the calls overhead 395600Sbill * in the vax contributes significantly to the overall 396600Sbill * execution speed of as. 397600Sbill */ 398600Sbill struct symtab **lookup(instflg) 399600Sbill int instflg; /* 0: don't install */ 400600Sbill { 401600Sbill static int initialprobe; 402600Sbill register struct symtab **hp; 403600Sbill register char *from; 404600Sbill register char *to; 405600Sbill register int len; 406600Sbill register int nprobes; 407600Sbill static struct hashdallop *hdallop; 408600Sbill static struct symtab **emptyslot; 409600Sbill static struct hashdallop *emptyhd; 410600Sbill static struct symtab **hp_ub; 411600Sbill 412600Sbill emptyslot = 0; 413600Sbill for (nprobes = 0, from = yytext; 414600Sbill *from; 415600Sbill nprobes <<= 2, nprobes += *from++) 416600Sbill continue; 417600Sbill nprobes += from[-1] << 5; 418600Sbill nprobes %= NHASH; 419600Sbill if (nprobes < 0) 420600Sbill nprobes += NHASH; 421600Sbill 422600Sbill initialprobe = nprobes; 423600Sbill for (hdallop = htab; hdallop != 0; hdallop = hdallop->h_next){ 424600Sbill for (hp = &(hdallop->h_htab[initialprobe]), 425600Sbill nprobes = 1, 426600Sbill hp_ub = &(hdallop->h_htab[NHASH]); 427600Sbill (*hp) && (nprobes < NHASH); 428600Sbill hp += nprobes, 429600Sbill hp -= (hp >= hp_ub) ? NHASH:0, 430600Sbill nprobes += 2) 431600Sbill { 432600Sbill from = yytext; 433634Shenry to = (*hp)->s_name; 434600Sbill #ifndef FLEXNAMES 435600Sbill for (len = 0; (len<NCPS) && *from; len++) 436600Sbill if (*from++ != *to++) 437600Sbill goto nextprobe; 438600Sbill if (len >= NCPS) /*both are maximal length*/ 439600Sbill return(hp); 440600Sbill if (*to == 0) /*assert *from == 0*/ 441600Sbill return(hp); 442600Sbill #else FLEXNAMES 443600Sbill while (*from && *to) 444600Sbill if (*from++ != *to++) 445600Sbill goto nextprobe; 446600Sbill if (*to == *from) /*assert both are == 0*/ 447600Sbill return(hp); 448600Sbill #endif FLEXNAMES 449600Sbill 450600Sbill nextprobe: ; 451600Sbill } 452600Sbill if (*hp == 0 && emptyslot == 0 && 453600Sbill hdallop->h_nused < HASHCLOGGED) { 454600Sbill emptyslot = hp; 455600Sbill emptyhd = hdallop; 456600Sbill } 457600Sbill } 458600Sbill if (emptyslot == 0) { 459600Sbill htaballoc(); 460600Sbill hdallop = htab->h_next; /* aren't we smart! */ 461600Sbill hp = &hdallop->h_htab[initialprobe]; 462600Sbill } else { 463600Sbill hdallop = emptyhd; 464600Sbill hp = emptyslot; 465600Sbill } 466600Sbill if (instflg) { 467600Sbill *hp = symalloc(); 468600Sbill hdallop->h_nused++; 469600Sbill #ifndef FLEXNAMES 470*13447Srrh strncpy((*hp)->s_name, yytext, NCPS); 471600Sbill #else FLEXNAMES 472*13447Srrh for (from = yytext, len = 0; *from++; len++) 473600Sbill continue; 474*13447Srrh /* 475*13447Srrh * save string and trailing null 476*13447Srrh */ 477*13447Srrh (*hp)->s_name = savestr(yytext, len + 1); 478600Sbill #endif FLEXNAMES 479600Sbill } 480600Sbill return(hp); 481600Sbill } /*end of lookup*/ 482*13447Srrh /* 483*13447Srrh * save a string str, length len in the string pool. 484*13447Srrh * string known just by its length; can have or not have trailing nulls. 485*13447Srrh * 486*13447Srrh * The length of the string occurs as a short just before 487*13447Srrh * the character pointer returned. 488*13447Srrh */ 489*13447Srrh char *savestr(str, len) 490*13447Srrh char *str; 491*13447Srrh int len; 492600Sbill { 493*13447Srrh char *res; 494600Sbill 495*13447Srrh if (len + sizeof(lgtype) >= (STRPOOLDALLOP - strplhead->str_nalloc)) 496600Sbill strpoolalloc(); 497*13447Srrh res = strplhead->str_names + strplhead->str_nalloc; 498*13447Srrh plgtype(res, len); 499*13447Srrh movestr(res, str, len); 500*13447Srrh strplhead->str_nalloc += sizeof(lgtype) + len; 501*13447Srrh return(res); 502600Sbill } 503600Sbill 504600Sbill /* 505600Sbill * The relocation information is saved internally in an array of 506600Sbill * lists of relocation buffers. The relocation buffers are 507600Sbill * exactly the same size as a token buffer; if we use VM for the 508600Sbill * temporary file we reclaim this storage, otherwise we create 509600Sbill * them by mallocing. 510600Sbill */ 511600Sbill #define RELBUFLG TOKBUFLG 512600Sbill #define NRELOC ((TOKBUFLG - \ 513600Sbill (sizeof (int) + sizeof (struct relbufdesc *)) \ 514600Sbill ) / (sizeof (struct relocation_info))) 515600Sbill 516600Sbill struct relbufdesc{ 517600Sbill int rel_count; 518600Sbill struct relbufdesc *rel_next; 519600Sbill struct relocation_info rel_reloc[NRELOC]; 520600Sbill }; 521600Sbill extern struct relbufdesc *tok_free; 522600Sbill #define rel_free tok_free 523600Sbill static struct relbufdesc *rel_temp; 524634Shenry struct relocation_info r_can_1PC; 525634Shenry struct relocation_info r_can_0PC; 526600Sbill 527600Sbill initoutrel() 528600Sbill { 529634Shenry r_can_0PC.r_address = 0; 530634Shenry r_can_0PC.r_symbolnum = 0; 531634Shenry r_can_0PC.r_pcrel = 0; 532634Shenry r_can_0PC.r_length = 0; 533634Shenry r_can_0PC.r_extern = 0; 534634Shenry 535634Shenry r_can_1PC = r_can_0PC; 536600Sbill r_can_1PC.r_pcrel = 1; 537600Sbill } 538600Sbill 539675Shenry outrel(xp, reloc_how) 540675Shenry register struct exp *xp; 5415828Srrh int reloc_how; /* TYPB..TYPH + (possibly)RELOC_PCREL */ 542600Sbill { 543675Shenry struct relocation_info reloc; 544675Shenry register int x_type_mask; 545*13447Srrh int pcrel; 546600Sbill 547675Shenry x_type_mask = xp->e_xtype & ~XFORW; 548675Shenry pcrel = reloc_how & RELOC_PCREL; 549675Shenry reloc_how &= ~RELOC_PCREL; 550675Shenry 551600Sbill if (bitoff&07) 552600Sbill yyerror("Padding error"); 553675Shenry if (x_type_mask == XUNDEF) 554600Sbill yyerror("Undefined reference"); 555600Sbill 556675Shenry if ( (x_type_mask != XABS) || pcrel ) { 557675Shenry if (ty_NORELOC[reloc_how]) 5585828Srrh yyerror("Illegal Relocation of floating or large int number."); 559675Shenry reloc = pcrel ? r_can_1PC : r_can_0PC; 560634Shenry reloc.r_address = dotp->e_xvalue - 561640Sbill ( (dotp < &usedot[NLOC] || readonlydata) ? 0 : datbase ); 562675Shenry reloc.r_length = ty_nlg[reloc_how]; 563675Shenry switch(x_type_mask){ 564600Sbill case XXTRN | XUNDEF: 565675Shenry reloc.r_symbolnum = xp->e_xname->s_index; 566600Sbill reloc.r_extern = 1; 567600Sbill break; 568600Sbill default: 569675Shenry if (readonlydata && (x_type_mask&~XXTRN) == XDATA) 570675Shenry x_type_mask = XTEXT | (x_type_mask&XXTRN); 571675Shenry reloc.r_symbolnum = x_type_mask; 572600Sbill break; 573600Sbill } 574600Sbill if ( (relfil == 0) || (relfil->rel_count >= NRELOC) ){ 575600Sbill if (rel_free){ 576600Sbill rel_temp = rel_free; 577600Sbill rel_free = rel_temp->rel_next; 578600Sbill } else { 579600Sbill rel_temp = (struct relbufdesc *) 580600Sbill Calloc(1,sizeof (struct relbufdesc)); 581600Sbill } 582600Sbill rel_temp->rel_count = 0; 583600Sbill rel_temp->rel_next = relfil; 584600Sbill relfil = rusefile[dotp - &usedot[0]] = rel_temp; 585600Sbill } 586600Sbill relfil->rel_reloc[relfil->rel_count++] = reloc; 587600Sbill } 588600Sbill /* 589600Sbill * write the unrelocated value to the text file 590600Sbill */ 591675Shenry dotp->e_xvalue += ty_nbyte[reloc_how]; 592675Shenry if (pcrel) 593675Shenry xp->e_xvalue -= dotp->e_xvalue; 5945828Srrh switch(reloc_how){ 5955828Srrh case TYPO: 5965828Srrh case TYPQ: 5975828Srrh 5985828Srrh case TYPF: 5995828Srrh case TYPD: 6005828Srrh case TYPG: 6015828Srrh case TYPH: 6025828Srrh bignumwrite(xp->e_number, reloc_how); 6035828Srrh break; 6045828Srrh 6055828Srrh default: 6065828Srrh bwrite((char *)&(xp->e_xvalue), ty_nbyte[reloc_how], txtfil); 6075828Srrh break; 6085828Srrh } 609600Sbill } 610600Sbill /* 611600Sbill * Flush out all of the relocation information. 612600Sbill * Note that the individual lists of buffers are in 613600Sbill * reverse order, so we must reverse them 614600Sbill */ 615600Sbill off_t closeoutrel(relocfile) 616600Sbill BFILE *relocfile; 617600Sbill { 618600Sbill int locindex; 619600Sbill u_long Closeoutrel(); 620600Sbill 621600Sbill trsize = 0; 622600Sbill for (locindex = 0; locindex < NLOC; locindex++){ 623600Sbill trsize += Closeoutrel(rusefile[locindex], relocfile); 624600Sbill } 625600Sbill drsize = 0; 626600Sbill for (locindex = 0; locindex < NLOC; locindex++){ 627600Sbill drsize += Closeoutrel(rusefile[NLOC + locindex], relocfile); 628600Sbill } 629600Sbill return(trsize + drsize); 630600Sbill } 631600Sbill 632600Sbill u_long Closeoutrel(relfil, relocfile) 633600Sbill struct relbufdesc *relfil; 634600Sbill BFILE *relocfile; 635600Sbill { 636600Sbill u_long tail; 637600Sbill if (relfil == 0) 638600Sbill return(0L); 639600Sbill tail = Closeoutrel(relfil->rel_next, relocfile); 640600Sbill bwrite((char *)&relfil->rel_reloc[0], 641600Sbill relfil->rel_count * sizeof (struct relocation_info), 642600Sbill relocfile); 643600Sbill return(tail + relfil->rel_count * sizeof (struct relocation_info)); 644600Sbill } 645600Sbill 646634Shenry #define NOUTSYMS (nsyms - njxxx - nforgotten - (savelabels ? 0 : nlabels)) 647600Sbill int sizesymtab() 648600Sbill { 649634Shenry return (sizeof (struct nlist) * NOUTSYMS); 650600Sbill } 651600Sbill 652600Sbill #ifdef FLEXNAMES 653600Sbill /* 654600Sbill * We write out the flexible length character strings for names 655600Sbill * in two stages. 656*13447Srrh * 1) We always! maintain a fixed sized name list entry; 657600Sbill * the string is indexed by a four byte quantity from the beginning 658600Sbill * of the string pool area. Index 0 is reserved, and indicates 659600Sbill * that there is no associated string. The first valid index is 4. 660600Sbill * 2) We concatenate together and write all of the strings 661600Sbill * in the string pool at the end of the name list. The first 662600Sbill * four bytes in the string pool are indexed only by 0 (see above); 663600Sbill * they contain the total number of bytes in the string pool. 664600Sbill */ 665600Sbill #endif FLEXNAMES 666600Sbill 667600Sbill /* 668600Sbill * Write out n symbols to file f, beginning at p 669600Sbill * ignoring symbols that are obsolete, jxxx instructions, and 670600Sbill * possibly, labels 671600Sbill */ 672600Sbill 673600Sbill int symwrite(symfile) 674600Sbill BFILE *symfile; 675600Sbill { 676600Sbill int symsout; /*those actually written*/ 677600Sbill int symsdesired = NOUTSYMS; 678600Sbill register struct symtab *sp, *ub; 679600Sbill #ifdef FLEXNAMES 680634Shenry char *name; /* temp to save the name */ 681600Sbill long stroff = sizeof (stroff); 682634Shenry /* 683634Shenry * We use sp->s_index to hold the length of the 684634Shenry * name; it isn't used for anything else 685634Shenry */ 686600Sbill #endif FLEXNAMES 687600Sbill 688600Sbill register struct allocbox *allocwalk; 689600Sbill 690600Sbill symsout = 0; 691600Sbill DECLITERATE(allocwalk, sp, ub) 692600Sbill { 693634Shenry if (sp->s_tag >= IGNOREBOUND) 694600Sbill continue; 695634Shenry if ((sp->s_name[0] == 'L') && (sp->s_tag == LABELID) && !savelabels) 696600Sbill continue; 697600Sbill symsout++; 698634Shenry 699634Shenry #ifdef FLEXNAMES 700634Shenry name = sp->s_name; /* save pointer */ 701*13447Srrh /* 702*13447Srrh * the length of the symbol table string 703*13447Srrh * always includes the trailing null 704*13447Srrh */ 705*13447Srrh if (sp->s_name && (sp->s_index = STRLEN(sp->s_name))){ 706634Shenry sp->s_nmx = stroff; /* clobber pointer */ 707*13447Srrh stroff += sp->s_index; 708634Shenry } else { 709*13447Srrh sp->s_nmx = 0; 710634Shenry } 711634Shenry #endif 712634Shenry sp->s_type = (sp->s_ptype != 0) ? sp->s_ptype : (sp->s_type & (~XFORW)); 713640Sbill if (readonlydata && (sp->s_type&~N_EXT) == N_DATA) 714640Sbill sp->s_type = N_TEXT | (sp->s_type & N_EXT); 7155828Srrh bwrite((char *)&sp->s_nm, sizeof (struct nlist), symfile); 716634Shenry #ifdef FLEXNAMES 717634Shenry sp->s_name = name; /* restore pointer */ 718600Sbill #endif FLEXNAMES 719600Sbill } 720600Sbill if (symsout != symsdesired) 721600Sbill yyerror("INTERNAL ERROR: Wrote %d symbols, wanted to write %d symbols\n", 722600Sbill symsout, symsdesired); 723600Sbill #ifdef FLEXNAMES 724600Sbill /* 725600Sbill * Pass 2 through the string pool 726600Sbill */ 727600Sbill symsout = 0; 7285828Srrh bwrite((char *)&stroff, sizeof (stroff), symfile); 729600Sbill stroff = sizeof (stroff); 730600Sbill symsout = 0; 731600Sbill DECLITERATE(allocwalk, sp, ub) 732600Sbill { 733634Shenry if (sp->s_tag >= IGNOREBOUND) 734600Sbill continue; 735634Shenry if ((sp->s_name[0] == 'L') && (sp->s_tag == LABELID) && !savelabels) 736600Sbill continue; 737*13447Srrh if (sp->s_name && (sp->s_index = STRLEN(sp->s_name))){ 738*13447Srrh bwrite(sp->s_name, sp->s_index, symfile); 739*13447Srrh } 740600Sbill } 741600Sbill #endif FLEXNAMES 742600Sbill } 743