Annotation of researchv9/cmd/sun/as/sym.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)sym.c 1.1 86/02/03 Copyr 1984 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1984 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: #include <a.out.h>
                     10: #include "as.h"
                     11: #include "scan.h"
                     12: 
                     13: /* Allocation increments for symbol buckets and character blocks */
                     14: #define        SYM_INCR        50
                     15: #define CBLOCK_INCR    512
                     16: 
                     17: extern struct stab_sym_bkt *stabkt_head;
                     18: 
                     19: struct sym_bkt *last_symbol;                   /* last symbol defined */
                     20: struct sym_bkt *sym_hash_tab[HASH_MAX];                /* Symbol hash table */
                     21: struct sym_bkt *sym_free = NULL;               /* head of free list */
                     22: char *cblock = NULL;                           /* storage for symbol names */
                     23: int ccnt = 0;                                  /* number of chars left in c block */
                     24: int ntlabels = 0;
                     25: 
                     26: /* grab a new symbol bucket off of the free list; allocate space
                     27:  * for a new free list if necessary
                     28:  */
                     29: struct sym_bkt *
                     30: gsbkt()
                     31:   {    register struct sym_bkt *sbp;
                     32:        register int i;
                     33: 
                     34:        if ((sbp = sym_free) != NULL) sym_free = sbp->next_s;
                     35:        else {
                     36:          sbp = (struct sym_bkt *)calloc(SYM_INCR,sizeof(struct sym_bkt));
                     37:          if (sbp == NULL) sys_error("Symbol storage exceeded\n",0);
                     38:          for (i = SYM_INCR-1; i--;) {
                     39:            sbp->next_s = sym_free;
                     40:            sym_free = sbp++;
                     41:          }
                     42:        }
                     43: 
                     44:        return(sbp);
                     45: }
                     46: 
                     47: /* initialize hash table */
                     48: sym_init()
                     49:   {    register int i;
                     50: 
                     51:        for (i=0; i<HASH_MAX; i++) sym_hash_tab[i] = NULL;
                     52: } /* end Sym_Init */
                     53: 
                     54: char *sstring(string)
                     55:   register char *string;
                     56:   {    register char *p,*q;    /* working char string */
                     57:        register int i;
                     58: 
                     59:        i = strlen(string);     /* get length of string */
                     60: 
                     61:        if (++i > ccnt) {       /* if not enough room get more */
                     62:          if ((cblock = (char *)calloc(CBLOCK_INCR,1)) == NULL)
                     63:            sys_error("Symbol storage exceeded\n",0);
                     64:          ccnt = CBLOCK_INCR;
                     65:        }
                     66: 
                     67:        p = q = cblock;         /* copy string into permanent storage */
                     68:        while (*p++ = *string++);
                     69:        cblock = p;
                     70:        ccnt -= i;
                     71:        return(q);
                     72: } /* end sstring */
                     73: 
                     74: /* lookup symbol in symbol table */
                     75: struct sym_bkt *
                     76: lookup(s)
                     77:     register char *s;
                     78:   {    register struct sym_bkt *sbp;   /* general purpose ptr */
                     79:        register int Save;              /* save subscript in sym_hash_tab */
                     80:        register char *p;
                     81:        static char local[250];         /* used for constructing local sym */
                     82:        extern char *ll_format;
                     83: 
                     84:        if (*s>='0' && *s<='9') {       /* local symbol hackery */
                     85:          /* we hope no-one uses really long local symbols */
                     86:          p = local;
                     87:          while ((*p++ = *s++) && (p < &local[sizeof local-1]));/* copy local symbol */
                     88:          p--;
                     89:          s = last_symbol->name_s;      /* add last symbol defined as suffix */
                     90:          while ((*p++ = *s++) && (p < &local[sizeof local-1]));
                     91:          s = local;                    /* this becomes name to deal with */
                     92:        }
                     93: 
                     94:        /* if the symbol is already in here, return a ptr to it */
                     95:        for (sbp = sym_hash_tab[Save=hash(s)]; sbp != NULL ; sbp = sbp->next_s)
                     96:          if (strcmp(sbp->name_s,s) == 0) return(sbp);
                     97: 
                     98:        /* Since it's not, make a bucket for it, and put the bucket in the symbol table */
                     99:        sbp = gsbkt();                          /* get the bucket */
                    100:        sbp->name_s = sstring(s);               /* Store it's name */
                    101:        sbp->value_s = sbp->id_s = sbp->attr_s = 0;
                    102:        sbp->csect_s = C_UNDEF;
                    103:        sbp->next_s = sym_hash_tab[Save];       /* and insert on top of list */
                    104:        if (s == local || *s == *ll_format) sbp->attr_s |= S_LOCAL;
                    105:        return(sym_hash_tab[Save] = sbp);
                    106: }
                    107: 
                    108: /* Sym_Fix - Assigns index numbers to the symbols.  Also performs 
                    109:              relocation of the symbols assuming data segment follows 
                    110:              text and bss follows the data.  If global flag, make all 
                    111:              undefined symbols defined to be externals.
                    112: */
                    113: 
                    114: /* symbol value compare -- for sorting */
                    115: static int
                    116: symvc( a, b )
                    117:     struct sym_bkt **a, **b;
                    118: {
                    119:     return ((*a)->value_s - (*b)->value_s);
                    120: }
                    121: 
                    122: sym_fix()
                    123: {
                    124:   register struct sym_bkt **sbp1, *sbp2;
                    125:   int i = 0;
                    126:   register int t;
                    127:   struct sym_bkt **symlistlist;
                    128:   register struct sym_bkt **syml;
                    129: 
                    130:   symlistlist = syml = (struct sym_bkt **)calloc( ntlabels, sizeof *symlistlist );
                    131:   for (sbp1 = sym_hash_tab; sbp1 < &sym_hash_tab[HASH_MAX]; sbp1++)
                    132:       for (sbp2 = *sbp1; sbp2; sbp2 = sbp2->next_s) {
                    133:            if ((sbp2->attr_s & (S_DEC|S_DEF)) == 0) {
                    134:                 sbp2->attr_s |= S_EXT | S_DEC;
                    135:                 sbp2->csect_s = C_UNDEF;
                    136:           }
                    137:           switch (sbp2->csect_s) {
                    138:           case C_TEXT:
                    139:                   if (sbp2 != dot_bkt && !(sbp2->attr_s & S_PERM))
                    140:                       *syml++ = sbp2;
                    141:                   break;
                    142:           case C_DATA:
                    143:                   sbp2->value_s += tsize; break;
                    144:           case C_DATA1:
                    145:                    sbp2->value_s += tsize + dsize; break;
                    146:           case C_DATA2:
                    147:                   sbp2->value_s += tsize + dsize + d1size; break;
                    148:           case C_BSS:
                    149:                   sbp2->value_s += tsize + dsize + d1size + d2size; break;
                    150:           }
                    151:           if (sbp2==dot_bkt || sbp2->attr_s & (S_REG|S_LOCAL|S_PERM))
                    152:                    sbp2->id_s = -1;
                    153:           else 
                    154:                    sbp2->id_s = i++;
                    155:       }
                    156:   /* consistancy check */
                    157:   if (syml - symlistlist != ntlabels)
                    158:       sys_error("wrong number of text labels: %d found\n", syml-symlistlist);
                    159:   /* sort C_TEXT symbols on value */
                    160:   qsort( symlistlist, ntlabels, sizeof *symlistlist, symvc );
                    161:   /* and go update those labels using the sdi information */
                    162:   sdi_sym_update( symlistlist, ntlabels );
                    163:   free( symlistlist );
                    164: }
                    165: 
                    166: 
                    167: /* sym_write - Write out the symbols to the specified
                    168:                file in b.out format, while computing size
                    169:                of the symbol segment in output file.
                    170:  */
                    171: 
                    172: redosyms()
                    173: {
                    174:        /* Go through the symbol table and get rid of "L" syms if 
                    175:                we are supposed to. */
                    176:        long size = 0;
                    177:        register struct sym_bkt  **sbp1, *sbp2;
                    178: 
                    179:        for (sbp1 = sym_hash_tab; sbp1 < &sym_hash_tab[HASH_MAX]; sbp1++)
                    180:            if (sbp2 = *sbp1)
                    181:                for (; sbp2; sbp2 = sbp2->next_s)
                    182:                {
                    183:                    if (sbp2->id_s != -1 && chkname(sbp2)) {
                    184:                            sbp2->final = size++;
                    185:                    }
                    186:                }
                    187: }
                    188: 
                    189: long sym_write(file)
                    190:   FILE *file;
                    191:   { register struct sym_bkt  **sbp1, *sbp2;
                    192:     long size = 0;
                    193:     struct nlist s;
                    194:     int strcount = 4;
                    195:     struct stab_sym_bkt *t;
                    196:        
                    197:     for (sbp1 = sym_hash_tab; sbp1 < &sym_hash_tab[HASH_MAX]; sbp1++)
                    198:         if (sbp2 = *sbp1) for (; sbp2; sbp2 = sbp2->next_s)
                    199:           if (sbp2->id_s != -1 && chkname(sbp2)) {
                    200:                 /* Write out the symbol table using the VAX a.out format */
                    201:                 if ((sbp2->attr_s&S_DEF)== 0) {
                    202:                    s.n_type = N_UNDF;
                    203:                    if (*(sbp2->name_s) == 'L' ) {
                    204:                        prog_warning( E_UNDEFINED_L ); /* Undefined L-symbol */
                    205:                    }
                    206:                 } else {
                    207:                    switch (sbp2->csect_s){
                    208:                    case C_TEXT:
                    209:                        s.n_type = N_TEXT; break;
                    210:                    case C_UNDEF:
                    211:                        s.n_type = N_ABS; break;
                    212:                    case C_BSS:
                    213:                        s.n_type = N_BSS; break;
                    214:                    default:
                    215:                        s.n_type = (rflag)?N_TEXT:N_DATA; break;
                    216:                    }
                    217:                } 
                    218:                if (sbp2->attr_s & S_EXT) s.n_type |= N_EXT;
                    219:                s.n_value = sbp2->value_s;
                    220:                /* For right now, just stuff these with 0 */
                    221:                s.n_other = s.n_desc = 0;
                    222:                s.n_un.n_strx = strcount;
                    223:                strcount += strlen(sbp2->name_s)+1;
                    224:                size += sizeof(s);
                    225:                fwrite(&s,sizeof(s),1,file);
                    226:            } else if (!(sbp2->attr_s & S_DEF)){
                    227:                    PROG_ERROR( E_UNDEFINED_L );
                    228:            }
                    229: 
                    230:         /* This is to write out the .stabs and .stabd symbols onto the        */
                    231:         /* a.out file.  This is only being written after the regular          */
                    232:         /* symbols have been put out (the prior section of the function).     */
                    233:         t = stabkt_head;           /* obtain head of stabs/stabd symbol table */
                    234:         while (t != NULL)
                    235:               { s.n_type   = t->type;
                    236:                 s.n_other  = t->other;
                    237:                 s.n_desc   = t->desc;       
                    238:                 s.n_value  = t->value;                /* zero for testing now */
                    239:                 if (t->id)
                    240:                    { s.n_un.n_strx = strcount;      /* assign string offset   */
                    241:                      strcount += t->id + 1;        /* increment str location */
                    242:                    }                                /* in string table.       */
                    243:                 else s.n_un.n_strx = 0;             /* else if no string is   */
                    244:                                                     /* present, assign 0.     */
                    245:                 size += sizeof(s);
                    246:                 fwrite(&s, sizeof(s), 1, file);
                    247:                 t = t->next_stab;
                    248:               } /* end while */
                    249:        return(size);
                    250: }
                    251: 
                    252: long 
                    253: str_write(file)
                    254:        FILE *file;
                    255: {
                    256:        long size = 0;
                    257:        long strcount = 4;
                    258:        register struct sym_bkt  **sbp1, *sbp2;
                    259:         struct stab_sym_bkt *t;
                    260: 
                    261: 
                    262:        fwrite(&strcount,sizeof(long),1,file);
                    263:        for (sbp1 = sym_hash_tab; sbp1 < &sym_hash_tab[HASH_MAX]; sbp1++)
                    264:                if (sbp2 = *sbp1) for (; sbp2; sbp2 = sbp2->next_s)
                    265:                if (chkname(sbp2))
                    266:                {
                    267:                        if (sbp2->id_s != -1) {
                    268:                                register i;
                    269:                                strcount +=  i = strlen(sbp2->name_s)+1;
                    270:                                fwrite(sbp2->name_s,i,1,file);
                    271:                        }
                    272:                }
                    273: 
                    274:         /* This is to write out all the symbols (strings) generated by        */
                    275:         /* .stabs and .stabd directives.  They are being written onto the     */
                    276:         /* string table only after all the regular symbol tables have been    */
                    277:         /* written out (by the prior section of this function.                */
                    278:         t = stabkt_head;                     /* head of stabs/stabd link list */
                    279:         while (t != NULL)
                    280:               { register i;
                    281:                 if (t->id)
                    282:                    { strcount += i = t->id + 1;
                    283:                      fwrite(t->ch,i,1,file); 
                    284:                    }
                    285:                 t = t->next_stab;
                    286:               } /* end while */
                    287:        return(strcount);
                    288: }
                    289: 
                    290: chkname(name)
                    291: struct sym_bkt *name;
                    292: {
                    293:     extern char o_lflag;
                    294: 
                    295:     if(o_lflag) return (1);
                    296:     if ( *(name->name_s)!='L') return(1);
                    297:     if ( (name->attr_s&S_DEF) == 0) return(1); /* don't zap undef L's */
                    298:     return(0);
                    299: }
                    300: 
                    301: /*
                    302:  * Perm        Flags all currently defined symbols as permanent (and therefore
                    303:  *     ineligible for redefinition.  Also prevents them from being output
                    304:  *     in the object file).
                    305:  */
                    306: perm()
                    307:   {    register struct sym_bkt **sbp1, *sbp2;
                    308: 
                    309:        for (sbp1 = sym_hash_tab; sbp1 < &sym_hash_tab[HASH_MAX]; sbp1++)
                    310:                for (sbp2 = *sbp1; sbp2; sbp2 = sbp2->next_s)
                    311:                        sbp2->attr_s |= S_PERM;
                    312: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.