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