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