X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/2b84abb596f52ab2068d52108adc96838ad4340a..31cef89cb428866f787983e68246030321893df4:/usr/src/cmd/as/assyms.c diff --git a/usr/src/cmd/as/assyms.c b/usr/src/cmd/as/assyms.c index fe262044f8..c445471a63 100644 --- a/usr/src/cmd/as/assyms.c +++ b/usr/src/cmd/as/assyms.c @@ -1,14 +1,51 @@ -/* Copyright (c) 1979 Regents of the University of California */ +/* Copyright (c) 1980 Regents of the University of California */ +static char sccsid[] = "@(#)assyms.c 4.6 11/5/80"; #include +#include #include "as.h" +#include "asscan.h" #include "assyms.h" -struct allocbox *allochead; -struct allocbox *alloctail; -struct symtab *nextsym; -struct allocbox *newbox; -char *namebuffer; -int symsleft; +/* + * Managers for chunks of symbols allocated from calloc() + * We maintain a linked list of such chunks. + * + */ +struct allocbox *allochead; /*head of chunk list*/ +struct allocbox *alloctail; /*tail*/ +struct allocbox *newbox; /*for creating a new chunk*/ +struct symtab *nextsym; /*next symbol free*/ +int symsleft; /*slots left in current chunk*/ + +struct symtab **symptrs; +struct symtab **symdelim[NLOC + NLOC +1]; +struct symtab **symptrub; +/* + * Managers for the dynamically extendable hash table + */ +struct hashdallop *htab; + +struct instab *itab[NINST]; /*maps opcodes to instructions*/ +/* + * Counts what went into the symbol table, so that the + * size of the symbol table can be computed. + */ +int nsyms; /* total number in the symbol table */ +int njxxx; /* number of jxxx entrys */ +int nforgotten; /* number of symbols erroneously entered */ +int nlabels; /* number of label entries */ +int hshused; /* number of hash slots used */ + +/* + * Managers of the symbol literal storage. + * If we have flexible names, then we allocate BUFSIZ long + * string, and pack strings into that. Otherwise, we allocate + * symbol storage in fixed hunks NCPS long when we allocate space + * for other symbol attributes. + */ +#ifdef FLEXNAMES +struct strpool *strplhead = 0; +#endif FLEXNAMES symtabinit() { @@ -16,6 +53,11 @@ symtabinit() alloctail = 0; nextsym = 0; symsleft = 0; +#ifdef FLEXNAMES + strpoolalloc(); /* get the first strpool storage area */ +#endif FLEXNAMES + htab = 0; + htaballoc(); /* get the first part of the hash table */ } /* @@ -27,18 +69,22 @@ syminstall() register struct symtab **hp; register char *p1, *p2; - for (ip=instab; ip->name[0]!=0; ip++) { - p1 = ip->name; +#ifdef FLEXNAMES + for (ip = (struct instab *)instab; ip->s_name != 0; ip++) { +#else not FLEXNAMES + for (ip = (struct instab *)instab; ip->s_name[0] != '\0'; ip++){ +#endif not FLEXNAMES + p1 = ip->s_name; p2 = yytext; while (*p2++ = *p1++); hp = lookup(0); /* 0 => don't install this*/ if (*hp==NULL) { *hp = (struct symtab *)ip; - if ( (ip->tag!=INSTn) - && (ip->tag!=INST0) - && (ip->tag!=0)) + if ( (ip->s_tag!=INSTn) + && (ip->s_tag!=INST0) + && (ip->s_tag!=0)) continue; /* was pseudo-op */ - itab[ip->opcode & 0xFF] = ip; + itab[ip->i_opcode & 0xFF] = ip; } } } /*end of syminstall*/ @@ -49,50 +95,42 @@ syminstall() * and overwrite the index field with its relative position in * the symbol table we give to the loader. */ -extern struct hdr hdr; +extern struct exec hdr; freezesymtab() { register struct symtab *sp; long bs; register int relpos = 0; -#ifdef SORTEDOUTPUT - register struct symtab **cosp; -#else register struct symtab *ubsp; register struct allocbox *allocwalk; -#endif -#ifdef SORTEDOUTPUT - SYMITERATE(cosp, sp) -#else DECLITERATE(allocwalk, sp, ubsp) -#endif { - if (sp->tag >= IGNOREBOUND) + if (sp->s_tag >= IGNOREBOUND) continue; /*totally ignore jxxx entries */ /* * Ignore stabs, but give them a symbol table index */ - if (sp->type & STABFLAG) + if (sp->s_type & STABFLAG) goto assignindex; - if ((sp->type&XTYPE)==XUNDEF) - sp->type = XXTRN+XUNDEF; - else if ((sp->type&XTYPE)==XDATA) - sp->value += usedot[sp->index].xvalue; - else if ((sp->type&XTYPE)==XTEXT) - sp->value += usedot[sp->index].xvalue; - else if ((sp->type&XTYPE)==XBSS) { - bs = sp->value; - sp->value = hdr.bsize + datbase; - hdr.bsize += bs; + if ((sp->s_type&XTYPE)==XUNDEF) + sp->s_type = XXTRN+XUNDEF; + else if ((sp->s_type&XTYPE)==XDATA) + sp->s_value += usedot[sp->s_index].e_xvalue; + else if ((sp->s_type&XTYPE)==XTEXT) + sp->s_value += usedot[sp->s_index].e_xvalue; + else if ((sp->s_type&XTYPE)==XBSS) { + bs = sp->s_value; + sp->s_value = hdr.a_bss + datbase; + hdr.a_bss += bs; } assignindex: - if ( (sp->name[0] != 'L') - || (sp->tag != LABELID) + if ( (sp->s_name[0] != 'L') + || (sp->s_tag != LABELID) || savelabels ) /*then, we will write it later on*/ - sp->index = relpos++; + sp->s_index = relpos++; } } @@ -110,15 +148,11 @@ stabfix() { register struct symtab *p; SYMITERATE(cosp, sp){ - if(sp->ptype && (sp->type & STABFLAG)) { - p = sp->dest; - sp->value = p->value; - sp->index = p->index; - sp->type = p->type; -#ifdef DSTAB - printf("STABFIX: %s (old %s) to %d offsets %d %d\n", - sp->name, p->name, sp->value, sp, p); -#endif + if(sp->s_ptype && (sp->s_type & STABFLAG)) { + p = sp->s_dest; + sp->s_value = p->s_value; + sp->s_index = p->s_index; + sp->s_type = p->s_type; } } } @@ -135,19 +169,22 @@ char *Calloc(number, size) return(newstuff); } -struct symtab * symalloc() +char *ClearCalloc(number, size) + int number, size; { - if (symsleft == 0){ - register int *p; + register char *newstuff; /* r11 */ + register int length = number * size; /* r10 */ + newstuff = Calloc(number, size); + asm("movc5 $0, (r0), $0, r10, (r11)"); + return(newstuff); +} - newbox = (struct allocbox *)Calloc(1,ALLOCQTY); +struct symtab *symalloc() +{ + if (symsleft == 0){ + newbox = (struct allocbox *)ClearCalloc(1,ALLOCQTY); symsleft = SYMDALLOP; nextsym = &newbox->symslots[0]; - namebuffer = &newbox->symnames[0]; - p = (int *)(&newbox->symnames[SYMDALLOP * NCPS]); - while ( p > (int *)newbox){ - *--p = 0; - } if (alloctail == 0){ allochead = alloctail = newbox; } else { @@ -157,32 +194,42 @@ struct symtab * symalloc() } --symsleft; ++nsyms; - nextsym->name = namebuffer; - namebuffer += NCPS; return(nextsym++); } -symcmp(pptr, qptr) - struct symtab **pptr, **qptr; +#ifdef FLEXNAMES +strpoolalloc() { - register struct symtab *p = *pptr; - register struct symtab *q = *qptr; - if (p->index < q->index) + register struct strpool *new; + + new = (struct strpool *)Calloc(1, sizeof (struct strpool)); + new->str_nalloc = 0; + new->str_next = strplhead; + strplhead = new; +} +#endif FLEXNAMES + +symcmp(Pptr, Qptr) + struct symtab **Pptr, **Qptr; +{ + register struct symtab *p = *Pptr; + register struct symtab *q = *Qptr; + if (p->s_index < q->s_index) return(-1); - if (p->index > q->index) + if (p->s_index > q->s_index) return(1); - if (p->value < q->value) + if (p->s_value < q->s_value) return(-1); - if (p->value > q->value) + if (p->s_value > q->s_value) return(1); /* * Force jxxx entries to virtually preceed labels defined * to follow the jxxxx instruction, so that bumping the * jxxx instruction correctly fixes up the following labels */ - if (p->tag >= IGNOREBOUND) /*p points to a jxxx*/ + if (p->s_tag >= IGNOREBOUND) /*p points to a jxxx*/ return(-1); - if (q->tag >= IGNOREBOUND) + if (q->s_tag >= IGNOREBOUND) return(1); /* * both are now just plain labels; the relative order doesn't @@ -221,9 +268,9 @@ sortsymtab() cowalk = symptrs; symsin = 0; DECLITERATE(allocwalk, sp, ubsp) { - if (sp->ptype && (sp->type &STABFLAG)){ - sp->value = sp->dest->value; - sp->index = sp->dest->index; + if (sp->s_ptype && (sp->s_type &STABFLAG)){ + sp->s_value = sp->s_dest->s_value; + sp->s_index = sp->s_dest->s_index; } if (symsin >= nsyms) yyerror("INTERNAL ERROR: overfilled symbol table indirection table"); @@ -239,7 +286,7 @@ sortsymtab() for (cowalk = symptrs, sp = *cowalk, segno = 0, slotno = 1; segno < NLOC + NLOC; segno++, slotno++){ - for (; sp && sp->index == segno; sp = *++cowalk); + for (; sp && sp->s_index == segno; sp = *++cowalk); symdelim[slotno] = cowalk; /*forms the ub delimeter*/ } } /*end of sortsymtab*/ @@ -255,10 +302,19 @@ dumpsymtab() for (segno = 0; segno < NLOC + NLOC; segno++){ printf("Segment number: %d\n", segno); SEGITERATE(segno, 0, 0, cosp, sp, ub, ++){ - printf("\tSeg: %d \"%8.8s\" value: %d index: %d tag %s\n", - segno, sp->name, sp->value, sp->index, tagstring(sp->tag)); +#ifdef FLEXNAMES + printf("\tSeg: %d \"%s\" value: %d index: %d tag %s\n", + segno, sp->s_name, + sp->s_value, sp->s_index, + tagstring(sp->s_tag)); +#else not FLEXNAMES + printf("\tSeg: %d \"%*.*s\" value: %d index: %d tag %s\n", + segno, NCPS, NCPS, sp->s_name, + sp->s_value, sp->s_index, + tagstring(sp->s_tag)); +#endif not FLEXNAMES printf("\t\ttype: %d jxbump %d jxfear: %d\n", - sp->type, sp->jxbump, sp->jxfear); + sp->s_type, sp->s_jxbump, sp->s_jxfear); } printf("\n\n"); } @@ -288,242 +344,360 @@ char *tagstring(tag) return(tagbuff); } } -#endif +#endif DEBUG + +htaballoc() +{ + register struct hashdallop *new; + new = (struct hashdallop *)ClearCalloc(1, sizeof (struct hashdallop)); + if (htab == 0) + htab = new; + else { /* add AFTER the 1st slot */ + new->h_next = htab->h_next; + htab->h_next = new; + } +} -#define HASHCLOGGED (NHASH * 3 ) / 4 +#define HASHCLOGGED (NHASH / 2) +/* + * Lookup a symbol stored in extern yytext. + * All strings passed in via extern yytext had better have + * a trailing null. Strings are placed in yytext for hashing by + * syminstall() and by yylex(); + * + * We take pains to avoid function calls; this functdion + * is called quite frequently, and the calls overhead + * in the vax contributes significantly to the overall + * execution speed of as. + */ struct symtab **lookup(instflg) int instflg; /* 0: don't install */ { - register int ihash; + static int initialprobe; register struct symtab **hp; - register char *p1, *p2; - register int i; - -#ifdef METRIC - nhashed++; -#endif - - /* - * All strings passed in in yytext had better have - * a trailing null. Strings are placed in yytext for - * hashing by syminstall() and yylex() - */ - for (ihash = 0, p1 = yytext ; *p1; ihash <<= 2, ihash += *p1++); - ihash += p1[-1] << 5; - ihash %= NHASH; - if (ihash < 0) ihash += NHASH; - hp = &hshtab[ihash]; - ihash = 1; /*now, it counts the number of times we rehash*/ - while (*hp) { - p1 = yytext; - p2 = (*hp)->name; - for (i = 0; (i= NCPS) /*both symbols are maximal length*/ - return(hp); - if (*p2 == 0) /*assert *p1 == 0*/ - return(hp); - no: -#ifdef METRIC - nhcollisions++; -#endif - hp += ihash; - ihash += 2; - if (hp >= &hshtab[NHASH]) - hp -= NHASH; + register char *from; + register char *to; + register int len; + register int nprobes; + static struct hashdallop *hdallop; + static struct symtab **emptyslot; + static struct hashdallop *emptyhd; + static struct symtab **hp_ub; + + emptyslot = 0; + for (nprobes = 0, from = yytext; + *from; + nprobes <<= 2, nprobes += *from++) + continue; + nprobes += from[-1] << 5; + nprobes %= NHASH; + if (nprobes < 0) + nprobes += NHASH; + + initialprobe = nprobes; + for (hdallop = htab; hdallop != 0; hdallop = hdallop->h_next){ + for (hp = &(hdallop->h_htab[initialprobe]), + nprobes = 1, + hp_ub = &(hdallop->h_htab[NHASH]); + (*hp) && (nprobes < NHASH); + hp += nprobes, + hp -= (hp >= hp_ub) ? NHASH:0, + nprobes += 2) + { + from = yytext; + to = (*hp)->s_name; +#ifndef FLEXNAMES + for (len = 0; (len= NCPS) /*both are maximal length*/ + return(hp); + if (*to == 0) /*assert *from == 0*/ + return(hp); +#else FLEXNAMES + while (*from && *to) + if (*from++ != *to++) + goto nextprobe; + if (*to == *from) /*assert both are == 0*/ + return(hp); +#endif FLEXNAMES + + nextprobe: ; + } + if (*hp == 0 && emptyslot == 0 && + hdallop->h_nused < HASHCLOGGED) { + emptyslot = hp; + emptyhd = hdallop; + } } - if(++hshused >= HASHCLOGGED) { - yyerror("Symbol table overflow"); - delexit(); + if (emptyslot == 0) { + htaballoc(); + hdallop = htab->h_next; /* aren't we smart! */ + hp = &hdallop->h_htab[initialprobe]; + } else { + hdallop = emptyhd; + hp = emptyslot; } if (instflg) { -#ifdef METRIC - nentered++; -#endif *hp = symalloc(); - p1 = yytext; - p2 = (*hp)->name; - while (*p2++ = *p1++); + hdallop->h_nused++; +#ifndef FLEXNAMES + for(len = 0, from = yytext, to = (*hp)->s_name; (len= (STRPOOLDALLOP - strplhead->str_nalloc)) + strpoolalloc(); + for ( (*hp)->s_name = to = strplhead->str_names + strplhead->str_nalloc, from = yytext; + ( (*to++ = *from++) != '\0'); ) + continue; + strplhead->str_nalloc += len; +#endif FLEXNAMES } return(hp); -} /*end of symlook*/ - -#ifdef vax -#define writel(p,n,f) fwrite((long)p, sizeof (long), n, f) -#else -writel(p,n,f) - long *p; - FILE *f; +} /*end of lookup*/ + +#ifdef FLEXNAMES +char *savestr(str) + char *str; { - while (n--) { - fwrite(&(*p).loword,2,1,f); - fwrite(&(*p).hiword,2,1,f); - p++; - } + register int len; + register char *from, *to; + char *res; + + for (from = str, len = 1; *from++; len++) + continue; + if (len >= (STRPOOLDALLOP - strplhead->str_nalloc)) + strpoolalloc(); + for ( res = to = strplhead->str_names + strplhead->str_nalloc, from = str; + ( (*to++ = *from++) != '\0'); ) + continue; + strplhead->str_nalloc += len; + return (res); } -#endif - -int reflen[] = {0,0,1,1,2,2,4,4,8,8}; +#endif FLEXNAMES /* - * Save the relocation information + * The relocation information is saved internally in an array of + * lists of relocation buffers. The relocation buffers are + * exactly the same size as a token buffer; if we use VM for the + * temporary file we reclaim this storage, otherwise we create + * them by mallocing. */ -outrel(pval,reftype,reltype,xsym) - long *pval; - register int reftype,reltype; - struct symtab *xsym; +#define RELBUFLG TOKBUFLG +#define NRELOC ((TOKBUFLG - \ + (sizeof (int) + sizeof (struct relbufdesc *)) \ + ) / (sizeof (struct relocation_info))) + +struct relbufdesc{ + int rel_count; + struct relbufdesc *rel_next; + struct relocation_info rel_reloc[NRELOC]; +}; +extern struct relbufdesc *tok_free; +#define rel_free tok_free +static struct relbufdesc *rel_temp; +struct relocation_info r_can_1PC; +struct relocation_info r_can_0PC; + +initoutrel() { + r_can_0PC.r_address = 0; + r_can_0PC.r_symbolnum = 0; + r_can_0PC.r_pcrel = 0; + r_can_0PC.r_length = 0; + r_can_0PC.r_extern = 0; + + r_can_1PC = r_can_0PC; + r_can_1PC.r_pcrel = 1; +} -/* - * reftype: PCREL or not, plus length LEN1, LEN2, LEN4, LEN8 - * reltype: csect ("segment") number (XTEXT, XDATA, ...) associated with 'val' - * xsym: symbol table pointer - */ - long ts; - char tc; - long tl; - short t; - if (passno!=2) { - dotp->xvalue += reflen[reftype]; - return; - } +outrel(xp, reloc_how) + register struct exp *xp; + int reloc_how; /* TYPB..TYPD + (possibly)RELOC_PCREL */ +{ + struct relocation_info reloc; + register int x_type_mask; + int pcrel; + + x_type_mask = xp->e_xtype & ~XFORW; + pcrel = reloc_how & RELOC_PCREL; + reloc_how &= ~RELOC_PCREL; + if (bitoff&07) yyerror("Padding error"); - reltype &= ~XFORW; - if (reltype == XUNDEF) + if (x_type_mask == XUNDEF) yyerror("Undefined reference"); - if (reltype != XABS || reftype & PCREL) { - /* write the address portion of a relocation datum */ - if (dotp >= &usedot[NLOC]) { - hdr.drsize += sizeof(dotp->xvalue) + 3 + sizeof tc; - tl = dotp->xvalue-datbase; - writel(&tl,1,relfil); - } else { - hdr.trsize += sizeof(dotp->xvalue) + 3 + sizeof tc; - writel(&dotp->xvalue,1,relfil); + + if ( (x_type_mask != XABS) || pcrel ) { + if (ty_NORELOC[reloc_how]) + yyerror("Illegal Relocation of float, double or quad."); + reloc = pcrel ? r_can_1PC : r_can_0PC; + reloc.r_address = dotp->e_xvalue - + ( (dotp < &usedot[NLOC] || readonlydata) ? 0 : datbase ); + reloc.r_length = ty_nlg[reloc_how]; + switch(x_type_mask){ + case XXTRN | XUNDEF: + reloc.r_symbolnum = xp->e_xname->s_index; + reloc.r_extern = 1; + break; + default: + if (readonlydata && (x_type_mask&~XXTRN) == XDATA) + x_type_mask = XTEXT | (x_type_mask&XXTRN); + reloc.r_symbolnum = x_type_mask; + break; } - /* write the properties portion of a relocation datum */ - if (reltype == XXTRN+XUNDEF) { - ts = (xsym->index); - tc = (XXTRN<<3) | (reftype-LEN1); - } else if ((reltype&XTYPE) == XUNDEFO) { - ts = (xsym->index); - tc = ((XXTRN+2)<<3) | (reftype-LEN1); - } else { - ts = (reltype); - tc = (reftype-LEN1); + if ( (relfil == 0) || (relfil->rel_count >= NRELOC) ){ + if (rel_free){ + rel_temp = rel_free; + rel_free = rel_temp->rel_next; + } else { + rel_temp = (struct relbufdesc *) + Calloc(1,sizeof (struct relbufdesc)); + } + rel_temp->rel_count = 0; + rel_temp->rel_next = relfil; + relfil = rusefile[dotp - &usedot[0]] = rel_temp; } - fwrite((char *)&ts, 3, 1, relfil); - fwrite(&tc, sizeof(tc), 1, relfil); + relfil->rel_reloc[relfil->rel_count++] = reloc; } - /* write the raw ("unrelocated") value to the text file */ - t = reflen[reftype]; - dotp->xvalue += t; - if (reftype & PCREL) - *pval -= dotp->xvalue; -#ifdef vax - fwrite(pval,1,t,txtfil); -#else - if (t>2) { - fwrite(&((*pval).loword),1,2,txtfil); - fwrite(&((*pval).hiword),1,t-2,txtfil); - } else fwrite(&((*pval).loword),1,t,txtfil); -#endif + /* + * write the unrelocated value to the text file + */ + dotp->e_xvalue += ty_nbyte[reloc_how]; + if (pcrel) + xp->e_xvalue -= dotp->e_xvalue; + bwrite((char *)&(xp->e_xvalue), ty_nbyte[reloc_how], txtfil); } - - /* - * Write out n symbols to file f, beginning at p - * ignoring symbols that are obsolete, jxxx instructions, and - * possibly, labels + * Flush out all of the relocation information. + * Note that the individual lists of buffers are in + * reverse order, so we must reverse them */ +off_t closeoutrel(relocfile) + BFILE *relocfile; +{ + int locindex; + u_long Closeoutrel(); -int sizesymtab() + trsize = 0; + for (locindex = 0; locindex < NLOC; locindex++){ + trsize += Closeoutrel(rusefile[locindex], relocfile); + } + drsize = 0; + for (locindex = 0; locindex < NLOC; locindex++){ + drsize += Closeoutrel(rusefile[NLOC + locindex], relocfile); + } + return(trsize + drsize); +} + +u_long Closeoutrel(relfil, relocfile) + struct relbufdesc *relfil; + BFILE *relocfile; { - struct symtab *sp; + u_long tail; + if (relfil == 0) + return(0L); + tail = Closeoutrel(relfil->rel_next, relocfile); + bwrite((char *)&relfil->rel_reloc[0], + relfil->rel_count * sizeof (struct relocation_info), + relocfile); + return(tail + relfil->rel_count * sizeof (struct relocation_info)); +} #define NOUTSYMS (nsyms - njxxx - nforgotten - (savelabels ? 0 : nlabels)) - - return ( - ( NCPS - + sizeof (sp->ptype) - + sizeof (sp->other) - + sizeof (sp->desc) - + sizeof (sp->value) - ) - * NOUTSYMS - ); +int sizesymtab() +{ + return (sizeof (struct nlist) * NOUTSYMS); } -symwrite(f) - FILE *f; +#ifdef FLEXNAMES +/* + * We write out the flexible length character strings for names + * in two stages. + * 1) We have always! maintain a fixed sized name list entry; + * the string is indexed by a four byte quantity from the beginning + * of the string pool area. Index 0 is reserved, and indicates + * that there is no associated string. The first valid index is 4. + * 2) We concatenate together and write all of the strings + * in the string pool at the end of the name list. The first + * four bytes in the string pool are indexed only by 0 (see above); + * they contain the total number of bytes in the string pool. + */ +#endif FLEXNAMES + +/* + * Write out n symbols to file f, beginning at p + * ignoring symbols that are obsolete, jxxx instructions, and + * possibly, labels + */ + +int symwrite(symfile) + BFILE *symfile; { int symsout; /*those actually written*/ int symsdesired = NOUTSYMS; register struct symtab *sp, *ub; -#ifdef SORTEDOUTPUT - int segno; - register struct symtab **copointer; -#else +#ifdef FLEXNAMES + char *name; /* temp to save the name */ + long stroff = sizeof (stroff); + /* + * We use sp->s_index to hold the length of the + * name; it isn't used for anything else + */ +#endif FLEXNAMES + register struct allocbox *allocwalk; -#endif -#ifdef SORTEDOUTPUT - for (segno = 0, symsout = 0; segno < NLOC + NLOC; segno++) - SEGITERATE(segno, 0, 0, copointer, sp, ub, ++) -#else symsout = 0; DECLITERATE(allocwalk, sp, ub) -#endif { - if (sp->tag >= IGNOREBOUND) + if (sp->s_tag >= IGNOREBOUND) continue; - if ((sp->name[0] == 'L') && (sp->tag == LABELID) && !savelabels) + if ((sp->s_name[0] == 'L') && (sp->s_tag == LABELID) && !savelabels) continue; symsout++; - fwrite(sp->name, NCPS, 1, f); - sp->type &= ~XFORW; - fwrite((sp->ptype) ? (char *)(&(sp->ptype)) : (char *)(&(sp->type)), - sizeof(char), 1, f); - /* - * WATCH OUT. THIS DEPENDS THAT THE ALLOCATION OF - * the four fields ptype, other, desc and value are - * contiguous. This may have to be changed! - * This is safe (as of 2-Nov-79). - */ - fwrite(&(sp->other), - sizeof (sp->other) - + sizeof (sp->desc) - + sizeof (sp->value), 1, f - ); -#ifdef fooie -#ifdef vax - fwrite(&(sp->name[0]), sizeof(symtab[0].name), 1, f); - fwrite(sp->ptype ? &(sp->ptype) : &(sp->type), - sizeof(symtab[0].type), 1, f); - fwrite(&(sp->other), sizeof(symtab[0].other), 1, f); - fwrite(&(sp->desc), sizeof(symtab[0].desc), 1, f); - fwrite(&(sp->value), sizeof(symtab[0].value), 1, f); -#else - writel(&(p->value), 1, f); -#endif + +#ifdef FLEXNAMES + name = sp->s_name; /* save pointer */ + if ( (sp->s_index = strlen(sp->s_name)) != 0){ + sp->s_nmx = stroff; /* clobber pointer */ + stroff += sp->s_index + 1; + } else { + sp->s_nmx = 0; /* clobber pointer */ + } #endif + sp->s_type = (sp->s_ptype != 0) ? sp->s_ptype : (sp->s_type & (~XFORW)); + if (readonlydata && (sp->s_type&~N_EXT) == N_DATA) + sp->s_type = N_TEXT | (sp->s_type & N_EXT); + bwrite(&sp->s_nm, sizeof (struct nlist), symfile); +#ifdef FLEXNAMES + sp->s_name = name; /* restore pointer */ +#endif FLEXNAMES } if (symsout != symsdesired) yyerror("INTERNAL ERROR: Wrote %d symbols, wanted to write %d symbols\n", symsout, symsdesired); -} - -Flushfield(n) - register int n; -{ - while (n>0) { - outb(bitfield); - bitfield >>= 8; - n -= 8; +#ifdef FLEXNAMES + /* + * Pass 2 through the string pool + */ + symsout = 0; + bwrite(&stroff, sizeof (stroff), symfile); + stroff = sizeof (stroff); + symsout = 0; + DECLITERATE(allocwalk, sp, ub) + { + if (sp->s_tag >= IGNOREBOUND) + continue; + if ((sp->s_name[0] == 'L') && (sp->s_tag == LABELID) && !savelabels) + continue; + sp->s_index = strlen(sp->s_name); + if (sp->s_index) + bwrite(sp->s_name, sp->s_index + 1, symfile); } - bitoff=0; - bitfield=0; +#endif FLEXNAMES }