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