Logo Search packages:      
Sourcecode: linux86 version File versions  Download package

gensym.c

/* gensym.c - generate symbol table for assembler */

#include "syshead.h"
#include "const.h"
#include "type.h"
#include "flag.h"
#include "file.h"
#include "globvar.h"

FORWARD int printsym P((register struct sym_s *symptr, unsigned column));
FORWARD void sort P((struct sym_s **array, struct sym_s **top,
                 bool_pt nameflag));

/* sort labels in symbol table on name and value */
/* if listing, write human-readable table to list file */
/* if symbol file, write machine-readable tables to it */
/* pointers become relative to start of file */

PUBLIC void gensym()
{
    unsigned column;
    struct sym_s **copyptr;
    struct sym_s **copytop;
    register struct sym_s **hashptr;
    unsigned label_count;     /* number of labels */
    unsigned labels_length;   /* length of all label strings */
    struct sym_s **symlptr;   /* start of symbol output list */
    register struct sym_s *symptr;
#ifdef BINSYM
    unsigned label_stringptr; /* offset of label str from start of file */
#endif
    int symcount = 0;

    labels_length = label_count = 0;

    /* make copy of all relavant symbol ptrs on heap */
    /* original ptrs can now be modified, but need to be an array for sort */

    for (hashptr = spt; hashptr < spt_top;)
      if ((symptr = *hashptr++) != NUL_PTR)
          do
            if (!(symptr->type & (MACBIT | MNREGBIT | VARBIT)))
               symcount++;
          while ((symptr = symptr->next) != NUL_PTR);
    symlptr = copyptr = asalloc( sizeof(struct sym_s *) * symcount);

    for (hashptr = spt; hashptr < spt_top;)
      if ((symptr = *hashptr++) != NUL_PTR)
          do
            if (!(symptr->type & (MACBIT | MNREGBIT | VARBIT)))
            {
                *copyptr++ = symptr;
                ++label_count;
                labels_length += symptr->length + 3; /* 3 for type, value */
            }
          while ((symptr = symptr->next) != NUL_PTR);

    sort(symlptr, copyptr, TRUE);   /* sort on name */
    copytop = copyptr;
    if (list.global)
    {
      outfd = lstfil;
      writenl();
      writesn("Symbols:");
      for (copyptr = symlptr, column = 0; copyptr < copytop;)
          column = printsym(*copyptr++, column);
      if (column != 0)
          writenl();
    }
    if ((outfd = symfil) != 0)
    {
#ifndef BINSYM
      for (copyptr = symlptr; copyptr < copytop;)
      /* for (copyptr = spt; copyptr < spt_top;) */
      {
          int sft;
          if((symptr = *copyptr++) == NUL_PTR ) continue;
          if( globals_only_in_obj &&
             !(symptr->type & EXPBIT)) continue;

            writec(hexdigit[symptr->data & SEGM]);
          writec(' ');

          for(sft=SIZEOF_OFFSET_T*8-4; sft >= 0; sft-=4)
               writec(hexdigit[(symptr->value_reg_or_op.value>>sft) & 0xF]);

          writec(' ');
            writec(symptr->type & EXPBIT ? 'E' : '-');
            writec(symptr->type & ENTBIT ? 'N' : '-');
            writec(symptr->data & IMPBIT ? 'I' : '-');
            writec(symptr->data & RELBIT ? 'R' : 'A');
            writec(symptr->type & COMMBIT ? 'C' : '-');

          writec(' ');
          write(outfd, symptr->name, (unsigned) (symptr->length));

          /* printsym(*copyptr++, 0); */
          writenl();
        }
#else
      writew(mapnum);
      label_count *= 2; /* now length of ptr table (2 bytes per ptr) */
      label_stringptr = label_count + 6;
                        /* offset to current string in symbol file */
                        /* 6 is length of header */
      labels_length += label_stringptr;
      /* offset to ptr table sorted on value */
      writew(labels_length + label_count);
      /* total length of symbol file */
      writew(label_count);
      for (copyptr = symlptr; copyptr < copytop;)
      {
          symptr = *copyptr++;
          writew((unsigned)
               (symptr->next = (struct sym_s *) label_stringptr));
                        /* reuse "next" to record string position */
          label_stringptr += symptr->length + 3;
      }
      for (copyptr = symlptr; copyptr < copytop;)
      {
          symptr = *copyptr++;
          writew((unsigned) symptr->value_reg_or_op.value);
          writec(symptr->type);
          write(outfd, symptr->name, (unsigned) (symptr->length - 1));
          writec(symptr->name[symptr->length - 1] | 0x80);
      }
      sort(symlptr, copyptr, FALSE);
      /* sort on value */
      for (copyptr = symlptr; copyptr < copytop;)
      {
          symptr = *copyptr++;
          writew((unsigned) symptr->next);      /* now has string position */
      }
#endif
    }
}

/* print symbol nicely formatted for given column */

PRIVATE int printsym(symptr, column)
register struct sym_s *symptr;
unsigned column;
{
    unsigned char length;
    register struct sym_listing_s *listptr;
    char *outname;
    char *symname;

    listptr = (struct sym_listing_s *) temp_buf();
    memset((char *) listptr, ' ', SYMLIS_LEN);
    listptr->nullterm = 0;
    if ((length = symptr->length) > SYMLIS_NAMELEN)
    {
      outname = listptr->name;
      outname[length = SYMLIS_NAMELEN] = '+';
    }
    else
      outname = listptr->name; /*(listptr->name + SYMLIS_NAMELEN) - length;*/
    symname = symptr->name;
    do
      *outname++ = *symname++;
    while (--length != 0);
    listptr->ar[0] = symptr->data & RELBIT ? 'R' : 'A';
    listptr->segm[0] = hexdigit[symptr->data & SEGM];
    if (symptr->type & COMMBIT)
      listptr->cein[0] = 'C';
    else if (symptr->type & ENTBIT)
      listptr->cein[0] = 'N';
    else if (symptr->type & EXPBIT)
      listptr->cein[0] = 'E';
    else if (symptr->data & IMPBIT)
      listptr->cein[0] = 'I';
#if SIZEOF_OFFSET_T > 2
    build_2hex_number((unsigned) (symptr->value_reg_or_op.value >> 16),
                  listptr->value);
#endif
    build_2hex_number((unsigned) symptr->value_reg_or_op.value,
                  listptr->value);
    writes((char *) listptr);
    if ((column += SYMLIS_LEN) > (80 - SYMLIS_LEN))
    {
      writenl();
      column = 0;
    }
    return column;
}

/* shell sort symbols */

PRIVATE void sort(array, top, nameflag)
struct sym_s **array;
struct sym_s **top;
bool_pt nameflag;
{
    int gap;
    int i;
    int j;
    register struct sym_s **left;
    register struct sym_s **right;
    int size;
    struct sym_s *swap;

    size = top - array;
    /* choose gaps according to Knuth V3 p95 */
    for (gap = 1, i = 4; (j = 3 * i + 1) < size; gap = i, i = j)
      ;
    do
    {
      for (j = gap; j < size; ++j)
          for (i = j - gap; i >= 0; i -= gap)
          {
            left = &array[i];
            right = &array[i + gap];
            if ((bool_t) nameflag)
            {
                if (strcmp((*left)->name, (*right)->name) <= 0)
                  break;
            }
            else if ((unsigned) (*left)->value_reg_or_op.value <=
                   (*right)->value_reg_or_op.value)
                break;
            swap = *left;
            *left = *right;
            *right = swap;
          }
    }
    while ((gap /= 3) != 0);
}

Generated by  Doxygen 1.6.0   Back to index