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