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