date and time created 83/08/13 16:28:17 by sam
[unix-history] / usr / src / old / as.vax / assyms.c
index b994081..52cd5c7 100644 (file)
@@ -1,9 +1,12 @@
-/* Copyright (c) 1980 Regents of the University of California */
-static char sccsid[] = "@(#)assyms.c 4.1 %G%";
+/*
+ *     Copyright (c) 1982 Regents of the University of California
+ */
+#ifndef lint
+static char sccsid[] = "@(#)assyms.c 4.14 %G%";
+#endif not lint
+
 #include <stdio.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <ctype.h>
-#include <sys/types.h>
-#include <a.out.h>
 #include "as.h"
 #include "asscan.h"
 #include "assyms.h"
 #include "as.h"
 #include "asscan.h"
 #include "assyms.h"
@@ -27,7 +30,7 @@ struct        symtab          **symptrub;
  */
 struct hashdallop      *htab;
 
  */
 struct hashdallop      *htab;
 
-struct instab          *itab[NINST];   /*maps opcodes to instructions*/
+Iptr   *itab[NINST];   /*maps opcodes to instructions*/
 /*
  *     Counts what went into the symbol table, so that the
  *     size of the symbol table can be computed.
 /*
  *     Counts what went into the symbol table, so that the
  *     size of the symbol table can be computed.
@@ -36,20 +39,11 @@ 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    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.
 
 /*
  *     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;
 struct strpool         *strplhead = 0;
-#else
-char                   *namebuffer;
-#endif
 
 symtabinit()
 {
 
 symtabinit()
 {
@@ -57,9 +51,7 @@ symtabinit()
        alloctail = 0;
        nextsym = 0;
        symsleft = 0;
        alloctail = 0;
        nextsym = 0;
        symsleft = 0;
-#ifdef FLEXNAMES
        strpoolalloc();         /* get the first strpool storage area */
        strpoolalloc();         /* get the first strpool storage area */
-#endif FLEXNAMES
        htab = 0;
        htaballoc();            /* get the first part of the hash table */
 }
        htab = 0;
        htaballoc();            /* get the first part of the hash table */
 }
@@ -69,27 +61,42 @@ symtabinit()
  */
 syminstall()
 {
  */
 syminstall()
 {
-       register        struct  instab  *ip;
+       register        Iptr    ip;
        register        struct  symtab  **hp;
        register        char    *p1, *p2;
        register        struct  symtab  **hp;
        register        char    *p1, *p2;
+       register        int     i;
 
 
-       for (ip=instab; ip->name!=0; ip++) {
-               p1 = ip->name;
+       for (i = 0; i < NINST; i++)
+               itab[i] = (Iptr*)BADPOINT;
+
+       for (ip = (Iptr)instab; FETCHNAME(ip)[0]; ip++) {
+               p1 = FETCHNAME(ip);
                p2 = yytext;
                while (*p2++ = *p1++);
                hp = lookup(0);         /* 0 => don't install this*/
                if (*hp==NULL) {
                        *hp = (struct symtab *)ip;
                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 */
                                continue; /* was pseudo-op */
-                       itab[ip->opcode & 0xFF] = ip;
+                       if (itab[ip->i_eopcode] == (Iptr*)BADPOINT){
+                               itab[ip->i_eopcode] =
+                                       (Iptr*)ClearCalloc(256, sizeof(Iptr));
+                               for (i = 0; i < 256; i++)
+                                       itab[ip->i_eopcode][i] =
+                                               (Iptr)BADPOINT;
+                       }
+                       itab[ip->i_eopcode][ip->i_popcode] = ip;
                }
        }
 }      /*end of syminstall*/
 
                }
        }
 }      /*end of syminstall*/
 
-
+#define ISLABEL(sp) \
+       (   (!savelabels) \
+        && (sp->s_tag == LABELID) \
+        && (STRPLACE(sp) & STR_CORE) \
+        && (FETCHNAME(sp)[0] == 'L'))
 /*
  *     Assign final values to symbols,
  *     and overwrite the index field with its relative position in
 /*
  *     Assign final values to symbols,
  *     and overwrite the index field with its relative position in
@@ -107,35 +114,30 @@ freezesymtab()
 
        DECLITERATE(allocwalk, sp, ubsp)
        {
 
        DECLITERATE(allocwalk, sp, ubsp)
        {
-               if (sp->tag >= IGNOREBOUND)
+               if (sp->s_tag >= IGNOREBOUND)
                        continue;               /*totally ignore jxxx entries */
                /*
                 *      Ignore stabs, but give them a symbol table index
                 */
                        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;
                        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.a_bss + datbase;
+               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:
                        hdr.a_bss += bs;
                }
           assignindex:
-               if (    (sp->name[0] != 'L')
-                    || (sp->tag != LABELID)
-                    || savelabels
-                    )                  /*then, we will write it later on*/
-                               sp->index = relpos++;
+               if (!ISLABEL(sp))
+                       sp->s_index = relpos++;
        }
 }
 
        }
 }
 
-
-
 /*
  *     For all of the stabs that had their final value undefined during pass 1
  *     and during pass 2 assign a final value.
 /*
  *     For all of the stabs that had their final value undefined during pass 1
  *     and during pass 2 assign a final value.
@@ -143,16 +145,27 @@ freezesymtab()
  *     when we constsructed the sorted symbol table.
  *     Iteration order doesn't matter.
  */
  *     when we constsructed the sorted symbol table.
  *     Iteration order doesn't matter.
  */
-stabfix() {
+
+stabfix()
+{
        register struct symtab *sp, **cosp;
        register struct symtab *p;
        
        SYMITERATE(cosp, sp){
        register struct symtab *sp, **cosp;
        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;
+               if(sp->s_ptype && (sp->s_type & STABFLAG)) {    
+                       p = sp->s_dest; 
+/* 
+ * STABFLOATING indicates that the offset has been saved in s_desc, s_other
+ */
+                       if(sp->s_tag == STABFLOATING) {
+                         sp->s_value = ( ( ((unsigned char) sp->s_other) << 16)                                        | ( (unsigned short) sp->s_desc )  );
+                         sp->s_value = sp->s_value + p->s_value;
+                       }
+                       else sp->s_value = p->s_value;
+                       sp->s_index = p->s_index;
+                       sp->s_type = p->s_type;
+
+              
                }
        }
 }
                }
        }
 }
@@ -161,7 +174,8 @@ char *Calloc(number, size)
        int     number, size;
 {
        register        char *newstuff;
        int     number, size;
 {
        register        char *newstuff;
-       newstuff = (char *)sbrk(number*size);
+       char    *sbrk();
+       newstuff = sbrk(number*size);
        if ((int)newstuff == -1){
                yyerror("Ran out of Memory");
                delexit();
        if ((int)newstuff == -1){
                yyerror("Ran out of Memory");
                delexit();
@@ -174,6 +188,9 @@ char *ClearCalloc(number, size)
 {
        register        char    *newstuff;              /* r11 */
        register        int     length = number * size; /* r10 */
 {
        register        char    *newstuff;              /* r11 */
        register        int     length = number * size; /* r10 */
+#ifdef lint
+       length = length;
+#endif length
        newstuff = Calloc(number, size);
        asm("movc5 $0, (r0), $0, r10, (r11)");
        return(newstuff);
        newstuff = Calloc(number, size);
        asm("movc5 $0, (r0), $0, r10, (r11)");
        return(newstuff);
@@ -185,9 +202,6 @@ struct symtab *symalloc()
                newbox = (struct allocbox *)ClearCalloc(1,ALLOCQTY);
                symsleft = SYMDALLOP;
                nextsym = &newbox->symslots[0];
                newbox = (struct allocbox *)ClearCalloc(1,ALLOCQTY);
                symsleft = SYMDALLOP;
                nextsym = &newbox->symslots[0];
-#ifndef FLEXNAMES
-               namebuffer = &newbox->symnames[0];
-#endif not FLEXNAMES
                if (alloctail == 0){
                        allochead = alloctail = newbox;
                } else {
                if (alloctail == 0){
                        allochead = alloctail = newbox;
                } else {
@@ -197,14 +211,9 @@ struct symtab *symalloc()
        }
        --symsleft;
        ++nsyms;
        }
        --symsleft;
        ++nsyms;
-#ifndef FLEXNAMES
-       nextsym->name = namebuffer;
-       namebuffer += NCPS;
-#endif not FLEXNAMES
        return(nextsym++);
 }
 
        return(nextsym++);
 }
 
-#ifdef FLEXNAMES
 strpoolalloc()
 {
        register        struct  strpool *new;
 strpoolalloc()
 {
        register        struct  strpool *new;
@@ -214,29 +223,28 @@ strpoolalloc()
        new->str_next = strplhead;
        strplhead = new;
 }
        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;
 
 symcmp(Pptr, Qptr)
        struct symtab **Pptr, **Qptr;
 {
        register struct symtab *p = *Pptr;
        register struct symtab *q = *Qptr;
-       if (p->index < q->index)
+       if (p->s_index < q->s_index)
                return(-1);
                return(-1);
-       if (p->index > q->index)
+       if (p->s_index > q->s_index)
                return(1);
                return(1);
-       if (p->value < q->value)
+       if (p->s_value < q->s_value)
                return(-1);
                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
         */
                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);             
                return(-1);             
-       if (q->tag >= IGNOREBOUND)
+       if (q->s_tag >= IGNOREBOUND)
                return(1);
        /*
         *      both are now just plain labels; the relative order doesn't
                return(1);
        /*
         *      both are now just plain labels; the relative order doesn't
@@ -275,9 +283,9 @@ sortsymtab()
        cowalk = symptrs;
        symsin = 0;
        DECLITERATE(allocwalk, sp, ubsp) {
        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");
                }
                if (symsin >= nsyms)
                        yyerror("INTERNAL ERROR: overfilled symbol table indirection table");
@@ -293,7 +301,7 @@ sortsymtab()
        for (cowalk = symptrs, sp = *cowalk, segno = 0, slotno = 1;
             segno < NLOC + NLOC;
             segno++, slotno++){
        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*/
                symdelim[slotno] = cowalk;      /*forms the ub delimeter*/
        }
 }      /*end of sortsymtab*/
@@ -309,19 +317,12 @@ dumpsymtab()
        for (segno = 0; segno < NLOC + NLOC; segno++){
                printf("Segment number: %d\n", segno);
                SEGITERATE(segno, 0, 0, cosp, sp, ub, ++){
        for (segno = 0; segno < NLOC + NLOC; segno++){
                printf("Segment number: %d\n", segno);
                SEGITERATE(segno, 0, 0, cosp, sp, ub, ++){
-#ifdef FLEXNAMES
                        printf("\tSeg: %d \"%s\" value: %d index: %d tag %s\n",
                        printf("\tSeg: %d \"%s\" value: %d index: %d tag %s\n",
-                               segno, sp->name,
-                               sp->value, sp->index,
-                               tagstring(sp->tag));
-#else not FLEXNAMES
-                       printf("\tSeg: %d \"%*.*s\" value: %d index: %d tag %s\n",
-                               segno, NCPS, NCPS, sp->name,
-                               sp->value, sp->index,
-                               tagstring(sp->tag));
-#endif not FLEXNAMES
+                               segno, FETCHNAME(sp),
+                               sp->s_value, sp->s_index,
+                               tagstring(sp->s_tag));
                        printf("\t\ttype: %d jxbump %d jxfear: %d\n",
                        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");
        }
                }
                printf("\n\n");
        }
@@ -387,10 +388,10 @@ struct symtab **lookup(instflg)
        register char           *to;
        register        int     len;
        register        int     nprobes;
        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;
+       static  struct  hashdallop *hdallop;
+       static  struct  symtab  **emptyslot;
+       static  struct  hashdallop *emptyhd;
+       static  struct  symtab  **hp_ub;
 
        emptyslot = 0;
        for (nprobes = 0, from = yytext;
 
        emptyslot = 0;
        for (nprobes = 0, from = yytext;
@@ -413,24 +414,13 @@ struct symtab **lookup(instflg)
                                nprobes += 2)
                {
                        from = yytext;
                                nprobes += 2)
                {
                        from = yytext;
-                       to = (*hp)->name;
-#ifndef FLEXNAMES
-                       for (len = 0; (len<NCPS) && *from; len++)
-                               if (*from++ != *to++)
-                                       goto nextprobe;
-                       if (len >= NCPS)        /*both are maximal length*/
-                               return(hp);
-                       if (*to == 0)           /*assert *from == 0*/
-                               return(hp);
-#else FLEXNAMES
+                       to = FETCHNAME(*hp);
                        while (*from && *to)
                                if (*from++ != *to++)
                                        goto nextprobe;
                        if (*to == *from)       /*assert both are == 0*/
                                return(hp);
                        while (*from && *to)
                                if (*from++ != *to++)
                                        goto nextprobe;
                        if (*to == *from)       /*assert both are == 0*/
                                return(hp);
-#endif FLEXNAMES
-
-       nextprobe: ;
+               nextprobe: ;
                }
                if (*hp == 0 && emptyslot == 0 &&
                    hdallop->h_nused < HASHCLOGGED) {
                }
                if (*hp == 0 && emptyslot == 0 &&
                    hdallop->h_nused < HASHCLOGGED) {
@@ -449,50 +439,59 @@ struct symtab **lookup(instflg)
        if (instflg) {
                *hp = symalloc();
                hdallop->h_nused++;
        if (instflg) {
                *hp = symalloc();
                hdallop->h_nused++;
-#ifndef FLEXNAMES
-               for(len = 0, from = yytext, to = (*hp)->name; (len<NCPS); len++)
-                       if ((*to++ = *from++) == '\0')
-                               break;
-#else FLEXNAMES
-               for (from = yytext, len = 1; *from++; len++)
-                       continue;
-               if (len >= (STRPOOLDALLOP - strplhead->str_nalloc))
-                       strpoolalloc();
-               for ( (*hp)->name = to = strplhead->str_names + strplhead->str_nalloc, from = yytext;
-                    ( (*to++ = *from++) != '\0'); )
+               for (from = yytext, len = 0; *from++; len++)
                        continue;
                        continue;
-               strplhead->str_nalloc += len;
-#endif FLEXNAMES
+               (*hp)->s_name = (char *)savestr(yytext, len + 1, STR_BOTH);
        }
        return(hp);
 }      /*end of lookup*/
        }
        return(hp);
 }      /*end of lookup*/
-
-char *savestr(str)
-       char *str;
+/*
+ *     save a string str with len in the places indicated by place
+ */
+struct strdesc *savestr(str, len, place)
+       char    *str;
+       int     len;
+       int     place;
 {
 {
-       register int len;
-       register char *from, *to;
-       char *res;
-
-       for (from = str, len = 1; *from++; len++)
-               continue;
-       if (len >= (STRPOOLDALLOP - strplhead->str_nalloc))
+       reg     struct  strdesc *res;
+               int     tlen;
+       /*
+        *      Compute the total length of the record to live in core
+        */
+       tlen = sizeof(struct strdesc) - sizeof(res->sd_string);
+       if (place & STR_CORE)
+               tlen += len;
+       /*
+        *      See if there is enough space for the record,
+        *      and allocate the record.
+        */
+       if (tlen >= (STRPOOLDALLOP - strplhead->str_nalloc))
                strpoolalloc();
                strpoolalloc();
-       for ( res = to = strplhead->str_names + strplhead->str_nalloc, from = str;
-                    ( (*to++ = *from++) != '\0'); )
-                       continue;
-       strplhead->str_nalloc += len;
-       return (res);
+       res = (struct strdesc *)(strplhead->str_names + strplhead->str_nalloc);
+       /*
+        *      Save the string information that is always present
+        */
+       res->sd_stroff = strfilepos;
+       res->sd_strlen = len;
+       res->sd_place = place;
+       /*
+        *      Now, save the string itself.  If str is null, then
+        *      the characters have already been dumped to the file
+        */
+       if ((place & STR_CORE) && str)
+               movestr(res[0].sd_string, str, len);
+       if (place & STR_FILE){
+               if (str){
+                       fwrite(str, 1, len, strfile);
+               }
+               strfilepos += len;
+       }
+       /*
+        *      Adjust the in core string pool size
+        */
+       strplhead->str_nalloc += tlen;
+       return(res);
 }
 }
-
-/*
- *     The following two tables are indexed by
- *             {LEN1,LEN2,LEN4,LEN8} | {PCREL,0}
- *     Note that PCREL = 1
- */
-int    reflen[] =      {0,   0, 1, 1, 2, 2, 4, 4, 8, 8};       
-int    lgreflen[] =    {-1, -1, 0, 0, 1, 1, 2, 2, 3, 3};
-
 /*
  *     The relocation information is saved internally in an array of
  *     lists of relocation buffers.  The relocation buffers are
 /*
  *     The relocation information is saved internally in an array of
  *     lists of relocation buffers.  The relocation buffers are
@@ -513,46 +512,54 @@ struct    relbufdesc{
 extern struct  relbufdesc      *tok_free;
 #define        rel_free tok_free
 static struct  relbufdesc      *rel_temp;
 extern struct  relbufdesc      *tok_free;
 #define        rel_free tok_free
 static struct  relbufdesc      *rel_temp;
-struct relocation_info r_can_1PC = {0,0,0,0,0,0};
-struct relocation_info r_can_0PC = {0,0,0,0,0,0};
+struct relocation_info r_can_1PC;
+struct relocation_info r_can_0PC;
 
 initoutrel()
 {
 
 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;
 }
 
        r_can_1PC.r_pcrel = 1;
 }
 
-outrel(pval,reftype,reltype,xsym)
-       long            *pval;
-       register int    reftype,reltype;
-       struct symtab   *xsym;
+outrel(xp, reloc_how)
+       register        struct  exp     *xp;
+       int             reloc_how;      /* TYPB..TYPH + (possibly)RELOC_PCREL */
 {
 {
-/*
- *     reftype: PCREL or not, plus length LEN1, LEN2, LEN4, LEN8
- *     reltype: csect ("segment") number (XTEXT, XDATA, ...) associated with 'val'
- *     xsym: symbol table pointer
- */
-       short   this_reflen;
-       struct  relocation_info reloc;
+       struct          relocation_info reloc;
+       register        int     x_type_mask;    
+                       int     pcrel;
 
 
-       this_reflen = reflen[reftype];
+       x_type_mask = xp->e_xtype & ~XFORW;
+       pcrel = reloc_how & RELOC_PCREL;
+       reloc_how &= ~RELOC_PCREL;
+       
        if (bitoff&07)
                yyerror("Padding error");
        if (bitoff&07)
                yyerror("Padding error");
-       reltype &= ~XFORW;
-       if (reltype == XUNDEF)
+       if (x_type_mask == XUNDEF)
                yyerror("Undefined reference");
 
                yyerror("Undefined reference");
 
-       if (reltype != XABS || reftype & PCREL) {
-               reloc = (reftype & PCREL)? r_can_1PC : r_can_0PC;
-               reloc.r_address = dotp->xvalue -
-                       ( (dotp < &usedot[NLOC]) ? 0 : datbase );
-               reloc.r_length = lgreflen[reftype];
-               switch(reltype){
+       if ( (x_type_mask != XABS) || pcrel ) {
+               if (ty_NORELOC[reloc_how])
+                       yyerror("Illegal Relocation of floating or large int number.");
+               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:
                        case XXTRN | XUNDEF:
-                               reloc.r_symbolnum = xsym->index;
+                               reloc.r_symbolnum = xp->e_xname->s_index;
                                reloc.r_extern = 1;
                                break;
                        default:
                                reloc.r_extern = 1;
                                break;
                        default:
-                               reloc.r_symbolnum = reltype;
+                               if (readonlydata && (x_type_mask&~XXTRN) == XDATA)
+                                       x_type_mask = XTEXT | (x_type_mask&XXTRN);
+                               reloc.r_symbolnum = x_type_mask;
                                break;
                }
                if ( (relfil == 0) || (relfil->rel_count >= NRELOC) ){
                                break;
                }
                if ( (relfil == 0) || (relfil->rel_count >= NRELOC) ){
@@ -572,10 +579,24 @@ outrel(pval,reftype,reltype,xsym)
        /*
         *      write the unrelocated value to the text file
         */
        /*
         *      write the unrelocated value to the text file
         */
-       dotp->xvalue += this_reflen;
-       if (reftype & PCREL)
-               *pval -= dotp->xvalue;
-       bwrite((char *)pval, this_reflen, txtfil);
+       dotp->e_xvalue += ty_nbyte[reloc_how];
+       if (pcrel)
+               xp->e_xvalue -= dotp->e_xvalue;
+       switch(reloc_how){
+       case TYPO:
+       case TYPQ:
+
+       case TYPF:
+       case TYPD:
+       case TYPG:
+       case TYPH:
+               bignumwrite(xp->e_number, reloc_how);
+               break;
+
+       default:
+               bwrite((char *)&(xp->e_xvalue), ty_nbyte[reloc_how], txtfil);
+               break;
+       }
 }
 /*
  *     Flush out all of the relocation information.
 }
 /*
  *     Flush out all of the relocation information.
@@ -613,115 +634,93 @@ u_long Closeoutrel(relfil, relocfile)
        return(tail + relfil->rel_count * sizeof (struct relocation_info));
 }
 
        return(tail + relfil->rel_count * sizeof (struct relocation_info));
 }
 
+#define NOUTSYMS (nsyms - njxxx - nforgotten - (savelabels ? 0 : nlabels))
 int sizesymtab()
 {
 int sizesymtab()
 {
-       struct symtab *sp;
-
-#define NOUTSYMS (nsyms - njxxx - nforgotten - (savelabels ? 0 : nlabels))
-
-       return (
-               (
-#ifndef FLEXNAMES
-                NCPS
-#else FLEXNAMES
-                sizeof (long)
-#endif FLEXNAMES
-                + sizeof (sp->ptype)
-                + sizeof (sp->other)
-                + sizeof (sp->desc)
-                + sizeof (sp->value)
-               ) 
-               *       NOUTSYMS
-       );
+       return (sizeof (struct nlist) * NOUTSYMS);
 }
 }
-
-#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
  */
 /*
  *     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 symwrite(symfile)
        BFILE *symfile;
 {
-       int     symsout;                        /*those actually written*/
-       int     symsdesired = NOUTSYMS;
-       register        struct  symtab *sp, *ub;
-#ifdef FLEXNAMES
-       register        int     len;
-       long            stroff  = sizeof (stroff);
-#endif FLEXNAMES
-
+               int     symsout;                /*those actually written*/
+               int     symsdesired = NOUTSYMS;
+       reg     struct  symtab *sp, *ub;
+               char    *name;                  /* temp to save the name */
+               int     totalstr;
+       /*
+        *      We use sp->s_index to hold the length of the
+        *      name; it isn't used for anything else
+        */
        register        struct  allocbox        *allocwalk;
 
        symsout = 0;
        register        struct  allocbox        *allocwalk;
 
        symsout = 0;
-       DECLITERATE(allocwalk, sp, ub)
-       {
-               if (sp->tag >= IGNOREBOUND) 
+       totalstr = sizeof(totalstr);
+       DECLITERATE(allocwalk, sp, ub) {
+               if (sp->s_tag >= IGNOREBOUND) 
                        continue;
                        continue;
-               if ((sp->name[0] == 'L') && (sp->tag == LABELID) && !savelabels)
+               if (ISLABEL(sp))
                        continue;
                symsout++;
                        continue;
                symsout++;
-#ifndef FLEXNAMES
-               bwrite(sp->name, NCPS, symfile);
-#else FLEXNAMES
-               len = strlen(sp->name);
-               if (len != 0) {
-                       bwrite(&stroff, sizeof (stroff), symfile);
-                       stroff += len + 1;
-               } else
-                       bwrite("\0\0\0\0", sizeof (stroff), symfile);
-#endif FLEXNAMES
-               sp->type &= ~XFORW;
-               bputc( ( (sp->ptype != 0) ? sp->ptype : sp->type ),
-                       symfile);
-       /*
-        *      WATCH OUT.  THIS DEPENDS THAT THE ALLOCATION OF
-        *      the four fields ptype, other, desc and value are
-        *      contiguous, which is compiler dependent.
-        */
-               bwrite((char *)&(sp->other),
-                         sizeof (sp->other)
-                       + sizeof (sp->desc)
-                       + sizeof (sp->value),
-                      symfile
-               );
+               name = sp->s_name;              /* save pointer */
+               /*
+                *      the length of the symbol table string
+                *      always includes the trailing null;
+                *      blast the pointer to its a.out value.
+                */
+               if (sp->s_name && (sp->s_index = STRLEN(sp))){
+                       sp->s_nmx = totalstr;
+                       totalstr += sp->s_index;
+               } else {
+                       sp->s_nmx = 0;
+               }
+               if (sp->s_ptype != 0)
+                       sp->s_type = sp->s_ptype;
+               else
+                       sp->s_type = (sp->s_type & (~XFORW));
+               if (readonlydata && (sp->s_type&~N_EXT) == N_DATA)
+                       sp->s_type = N_TEXT | (sp->s_type & N_EXT);
+               bwrite((char *)&sp->s_nm, sizeof (struct nlist), symfile);
+               sp->s_name = name;              /* restore pointer */
        }
        if (symsout != symsdesired)
                yyerror("INTERNAL ERROR: Wrote %d symbols, wanted to write %d symbols\n",
                        symsout, symsdesired);
        }
        if (symsout != symsdesired)
                yyerror("INTERNAL ERROR: Wrote %d symbols, wanted to write %d symbols\n",
                        symsout, symsdesired);
-#ifdef FLEXNAMES
        /*
        /*
-        *      Pass 2 through the string pool
+        *      Construct the string pool from the symbols that were written,
+        *      possibly fetching from the string file if the string
+        *      is not core resident.
         */
         */
+       bwrite(&totalstr, sizeof(totalstr), symfile);
        symsout = 0;
        symsout = 0;
-       bwrite(&stroff, sizeof (stroff), symfile);
-       stroff = sizeof (stroff);
-       symsout = 0;
-       DECLITERATE(allocwalk, sp, ub)
-       {
-               if (sp->tag >= IGNOREBOUND) 
+       DECLITERATE(allocwalk, sp, ub) {
+               if (sp->s_tag >= IGNOREBOUND) 
                        continue;
                        continue;
-               if ((sp->name[0] == 'L') && (sp->tag == LABELID) && !savelabels)
+               if (ISLABEL(sp))
                        continue;
                        continue;
-               len = strlen(sp->name);
-               if (len)
-                       bwrite(sp->name, len + 1, symfile);
+               symsout++;
+               if (STRLEN(sp) > 0){
+                if (STRPLACE(sp) & STR_CORE){
+                       bwrite(FETCHNAME(sp), STRLEN(sp), symfile);
+                } else if (STRPLACE(sp) & STR_FILE){
+                       char    rbuf[2048];
+                       int     left, nread;
+                       fseek(strfile, STROFF(sp), 0);
+                       for (left = STRLEN(sp); left > 0; left -= nread){
+                               nread = fread(rbuf, sizeof(char),
+                                       min(sizeof(rbuf), left), strfile);
+                               if (nread == 0)
+                                       break;
+                               bwrite(rbuf, nread, symfile);
+                       }
+                }
+               }
        }
        }
-#endif FLEXNAMES
+       if (symsout != symsdesired)
+               yyerror("INTERNAL ERROR: Wrote %d strings, wanted %d\n",
+                       symsout, symsdesired);
 }
 }