Annotation of researchv9/cmd/sun/as/sym.c, revision 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.