Annotation of GNUtools/cctools/as/symbols.c, revision 1.1

1.1     ! root        1: /* symbols.c -symbol table-
        !             2:    Copyright (C) 1987 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GAS, the GNU Assembler.
        !             5: 
        !             6: GAS is free software; you can redistribute it and/or modify
        !             7: it under the terms of the GNU General Public License as published by
        !             8: the Free Software Foundation; either version 1, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: GAS is distributed in the hope that it will be useful,
        !            12: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: GNU General Public License for more details.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with GAS; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            19: 
        !            20: #include <stdlib.h>
        !            21: #include <string.h>
        !            22: #include "as.h"
        !            23: #include "hash.h"
        !            24: #include "obstack.h"           /* For "symbols.h" */
        !            25: #include "struc-symbol.h"
        !            26: #include "symbols.h"
        !            27: #include "frags.h"
        !            28: #include "expr.h"
        !            29: #include "sections.h"
        !            30: #include "read.h"
        !            31: #include "xmalloc.h"
        !            32: #include "messages.h"
        !            33: #include "fixes.h"
        !            34: #include "input-scrub.h"
        !            35: 
        !            36: /* symbol-name => struct symbol pointer */
        !            37: struct hash_control *sy_hash = NULL;
        !            38: 
        !            39: /* FixS & symbols live here */
        !            40: struct obstack notes = { 0 };
        !            41: 
        !            42: /* all the symbol nodes */
        !            43: symbolS *symbol_rootP = NULL;
        !            44: /* last struct symbol we made, or NULL */
        !            45: symbolS *symbol_lastP = NULL;
        !            46: 
        !            47: symbolS        abs_symbol = { 0 };
        !            48: 
        !            49: /*
        !            50:  * Un*x idea of local labels. They are made by "n:" where n
        !            51:  * is any decimal digit. Refer to them with
        !            52:  *  "nb" for previous (backward) n:
        !            53:  *  or "nf" for next (forward) n:.
        !            54:  *
        !            55:  * Like Un*x AS, we have one set of local label counters for entire assembly,
        !            56:  * not one set per (sub)segment like in most assemblers. This implies that
        !            57:  * one can refer to a label in another segment, and indeed some crufty
        !            58:  * compilers have done just that.
        !            59:  *
        !            60:  * I document the symbol names here to save duplicating words elsewhere.
        !            61:  * The mth occurence of label n: is turned into the symbol "Ln^Am" where
        !            62:  * n is a digit and m is a decimal number. "L" makes it a label discarded
        !            63:  * unless debugging and "^A"('\1') ensures no ordinary symbol SHOULD get the
        !            64:  * same name as a local label symbol. The first "4:" is "L4^A1" - the m
        !            65:  * numbers begin at 1.
        !            66:  */
        !            67: 
        !            68: typedef short unsigned int local_label_countT;
        !            69: 
        !            70: static local_label_countT local_label_counter[10];
        !            71: 
        !            72: static                         /* Returned to caller, then copied. */
        !            73:   char symbol_name_build[12];  /* used for created names ("4f") */
        !            74: 
        !            75: static void make_stab_for_symbol(
        !            76:     symbolS *symbolP);
        !            77: 
        !            78: 
        !            79: void
        !            80: symbol_begin(
        !            81: void)
        !            82: {
        !            83:   symbol_lastP = NULL;
        !            84:   symbol_rootP = NULL;         /* In case we have 0 symbols (!!) */
        !            85:   sy_hash = hash_new();
        !            86:   memset((char *)(&abs_symbol), '\0', sizeof(abs_symbol));
        !            87:   abs_symbol.sy_type = N_ABS;  /* Can't initialise a union. Sigh. */
        !            88:   memset((char *)(local_label_counter), '\0', sizeof(local_label_counter) );
        !            89: }
        !            90: 
        !            91: /*
        !            92:  *                     local_label_name()
        !            93:  *
        !            94:  * Caller must copy returned name: we re-use the area for the next name.
        !            95:  */
        !            96: char *                         /* Return local label name. */
        !            97: local_label_name(
        !            98: int n,         /* we just saw "n:", "nf" or "nb" : n a digit */
        !            99: int augend)    /* 0 for nb, 1 for n:, nf */
        !           100: {
        !           101:   register char *      p;
        !           102:   register char *      q;
        !           103:   char symbol_name_temporary[10]; /* build up a number, BACKWARDS */
        !           104: 
        !           105:   know( n >= 0 );
        !           106:   know( augend == 0 || augend == 1 );
        !           107:   p = symbol_name_build;
        !           108:   * p ++ = 'L';
        !           109:   * p ++ = n + '0';            /* Make into ASCII */
        !           110:   * p ++ = 1;                  /* ^A */
        !           111:   n = local_label_counter [ n ] + augend;
        !           112:                                /* version number of this local label */
        !           113:   /*
        !           114:    * Next code just does sprintf( {}, "%d", n);
        !           115:    * It is more elegant to do the next part recursively, but a procedure
        !           116:    * call for each digit emitted is considered too costly.
        !           117:    */
        !           118:   q = symbol_name_temporary;
        !           119:   for (*q++=0; n; q++)         /* emits NOTHING if n starts as 0 */
        !           120:     {
        !           121:       know(n>0);               /* We expect n > 0 always */
        !           122:       *q = n % 10 + '0';
        !           123:       n /= 10;
        !           124:     }
        !           125:   while (( * p ++ = * -- q ))
        !           126:     {
        !           127:     }
        !           128:   /* The label, as a '\0' ended string, starts at symbol_name_build. */
        !           129:   return (symbol_name_build);
        !           130: }
        !           131: 
        !           132: void
        !           133: local_colon(
        !           134: int n) /* just saw "n:" */
        !           135: {
        !           136:   local_label_counter [n] ++;
        !           137:   colon (local_label_name (n, 0));
        !           138: }
        !           139: 
        !           140: /*
        !           141:  *                     symbol_new()
        !           142:  *
        !           143:  * Return a pointer to a new symbol.
        !           144:  * Die if we can't make a new symbol.
        !           145:  * Fill in the symbol's values.
        !           146:  * Add symbol to end of symbol chain.
        !           147:  *
        !           148:  *
        !           149:  * Please always call this to create a new symbol.
        !           150:  *
        !           151:  * Changes since 1985: Symbol names may not contain '\0'. Sigh.
        !           152:  */
        !           153: symbolS *
        !           154: symbol_new(
        !           155: char          *name,   /* We copy this: OK to alter your copy. */
        !           156: unsigned char  type,   /* As in <nlist.h>. */
        !           157: char           other,  /* As in <nlist.h>. */
        !           158: short          desc,   /* As in <nlist.h>. */
        !           159: valueT         value,  /* As in <nlist.h>, often an address. */
        !           160:                        /* Often used as offset from frag address. */
        !           161: struct frag    *frag)  /* For sy_frag. */
        !           162: {
        !           163:   register symbolS *           symbolP;
        !           164:   register char *              preserved_copy_of_name;
        !           165:   register unsigned int                name_length;
        !           166:            char *              p;
        !           167: 
        !           168:   name_length = strlen(name) + 1;
        !           169:   obstack_grow(&notes,name,name_length);
        !           170:   p=obstack_finish(&notes);
        !           171:   /* obstack_1done( &notes, name, name_length, &p ); */
        !           172:   preserved_copy_of_name = p;
        !           173:   p=obstack_alloc(&notes,sizeof(struct symbol));
        !           174:   /* obstack_1blank( &notes, sizeof(struct symbol), &p ); */
        !           175:   symbolP                      = (symbolS *) p;
        !           176:   symbolP -> sy_name           = preserved_copy_of_name;
        !           177:   symbolP -> sy_type           = type;
        !           178:   symbolP -> sy_other          = other;
        !           179:   symbolP -> sy_desc           = desc;
        !           180:   symbolP -> sy_value          = value;
        !           181:   symbolP -> sy_frag           = frag;
        !           182:   symbolP -> sy_next           = NULL; /* End of chain. */
        !           183:   symbolP -> sy_forward                = NULL; /* JF */
        !           184: #ifdef SUSPECT
        !           185:   symbolP -> sy_name_offset    = ~ 0; /* Impossible offset catches errors. */
        !           186:   symbolP -> sy_number         = ~ 0; /* Ditto. */
        !           187: #endif
        !           188:   /*
        !           189:    * Link to end of symbol chain.
        !           190:    */
        !           191:   if (symbol_lastP)
        !           192:     {
        !           193:       symbol_lastP -> sy_next = symbolP;
        !           194:     }
        !           195:   else
        !           196:     {
        !           197:       symbol_rootP = symbolP;
        !           198:     }
        !           199:   symbol_lastP = symbolP;
        !           200: 
        !           201:   return (symbolP);
        !           202: }
        !           203: 
        !           204: /*
        !           205:  *                     colon()
        !           206:  *
        !           207:  * We have just seen "<name>:".
        !           208:  * Creates a struct symbol unless it already exists.
        !           209:  *
        !           210:  * Gripes if we are redefining a symbol incompatibly (and ignores it).
        !           211:  *
        !           212:  */
        !           213: void
        !           214: colon(         /* just seen "x:" - rattle symbols & frags */
        !           215: char *sym_name) /* symbol name, as a cannonical string */
        !           216:                /* We copy this string: OK to alter later. */
        !           217: {
        !           218:   register struct symbol * symbolP; /* symbol we are working with */
        !           219: 
        !           220:   if (frchain_now == NULL)
        !           221:     {
        !           222:       know(flagseen['n']);
        !           223:       as_fatal("with -n a section directive must be seen before assembly "
        !           224:               "can begin");
        !           225:     }
        !           226:   if ((symbolP = symbol_table_lookup( sym_name )))
        !           227:     {
        !           228:       /*
        !           229:        *       Now check for undefined symbols
        !           230:        */
        !           231:       if ((symbolP -> sy_type & N_TYPE) == N_UNDF)
        !           232:        {
        !           233:          if(   symbolP -> sy_other == 0
        !           234: /* -O causes this not to work */
        !           235:             && ((symbolP->sy_desc) & (~REFERENCE_TYPE)) == 0
        !           236:             && symbolP -> sy_value == 0)
        !           237:            {
        !           238:              symbolP -> sy_frag  = frag_now;
        !           239:              symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal;
        !           240:              know( N_UNDF == 0 );
        !           241:              symbolP -> sy_type |= N_SECT; /* keep N_EXT bit */
        !           242:              symbolP -> sy_other = frchain_now->frch_nsect;
        !           243:              symbolP -> sy_desc &= ~REFERENCE_TYPE;
        !           244: #ifdef NeXT    /* generate stabs for debugging assembly code */
        !           245:              if(flagseen['g'])
        !           246:                  make_stab_for_symbol(symbolP);
        !           247: #endif
        !           248:            }
        !           249:          else
        !           250:            {
        !           251:              as_fatal( "Symbol \"%s\" is already defined as \"%s\"/%d.%d.%ld.",
        !           252:                      sym_name,
        !           253:                      seg_name [(int) N_TYPE_seg [symbolP -> sy_type & N_TYPE]],
        !           254:                      symbolP -> sy_other, symbolP -> sy_desc,
        !           255:                      symbolP -> sy_value);
        !           256:            }
        !           257:        }
        !           258:       else
        !           259:        {
        !           260:          as_fatal("Symbol %s already defined.",sym_name);
        !           261:        }
        !           262:     }
        !           263:   else
        !           264:     {
        !           265:       symbolP = symbol_new (sym_name,
        !           266:                            N_SECT,
        !           267:                            frchain_now->frch_nsect,
        !           268:                            0,
        !           269:                            (valueT)(obstack_next_free(&frags)-frag_now->fr_literal),
        !           270:                            frag_now);
        !           271:       symbol_table_insert (symbolP);
        !           272: #ifdef NeXT    /* generate stabs for debugging assembly code */
        !           273:       if(flagseen['g'])
        !           274:          make_stab_for_symbol(symbolP);
        !           275: #endif
        !           276:     }
        !           277: }
        !           278: 
        !           279: 
        !           280: /*
        !           281:  *                     symbol_table_insert()
        !           282:  *
        !           283:  * Die if we can't insert the symbol.
        !           284:  *
        !           285:  */
        !           286: void
        !           287: symbol_table_insert(
        !           288: struct symbol *symbolP)
        !           289: {
        !           290:   register char *      error_string;
        !           291: 
        !           292:   know( symbolP );
        !           293:   know( symbolP -> sy_name );
        !           294:   if ( * (error_string = hash_jam (sy_hash, symbolP -> sy_name, (char *)symbolP)))
        !           295:     {
        !           296:       as_fatal( "Inserting \"%s\" into symbol table failed: %s",
        !           297:              symbolP -> sy_name, error_string);
        !           298:     }
        !           299: }
        !           300: 
        !           301: /*
        !           302:  *                     symbol_find_or_make()
        !           303:  *
        !           304:  * If a symbol name does not exist, create it as undefined, and insert
        !           305:  * it into the symbol table. Return a pointer to it.
        !           306:  */
        !           307: symbolS *
        !           308: symbol_find_or_make(
        !           309: char *name)
        !           310: {
        !           311:   register symbolS *   symbolP;
        !           312: 
        !           313:   symbolP = symbol_table_lookup (name);
        !           314:   if (symbolP == NULL)
        !           315:     {
        !           316:       symbolP = symbol_new (name, N_UNDF, 0, 0, 0, & zero_address_frag);
        !           317:       symbol_table_insert (symbolP);
        !           318:     }
        !           319:   return (symbolP);
        !           320: }
        !           321: 
        !           322: /*
        !           323:  *                     symbol_find()
        !           324:  * 
        !           325:  * Implement symbol table lookup.
        !           326:  * In: A symbol's name as a string: '\0' can't be part of a symbol name.
        !           327:  * Out:        NULL if the name was not in the symbol table, else the address
        !           328:  *     of a struct symbol associated with that name.
        !           329:  */
        !           330: symbolS *
        !           331: symbol_find(
        !           332: char *name)
        !           333: {
        !           334:   return ( (symbolS *) hash_find( sy_hash, name ));
        !           335: }
        !           336: 
        !           337: #ifdef NeXT    /* generate stabs for debugging assembly code */
        !           338: /*
        !           339:  * make_stab_for_symbol() is called when -g is present for a label that is
        !           340:  * being defined.  If the label is a text label and in the (__TEXT,__text)
        !           341:  * section and not a local label create a stab for it.
        !           342:  * 
        !           343:  * See the detailed comments about stabs in read_a_source_file() for a
        !           344:  * description of what is going on here.
        !           345:  */
        !           346: static
        !           347: void
        !           348: make_stab_for_symbol(
        !           349: symbolS *symbolP)
        !           350: {
        !           351:     symbolS *stab;
        !           352:     int stabnamelen;
        !           353:     char *stabname;
        !           354: 
        !           355:        if(symbolP->sy_name[0] == 'L')
        !           356:            return;
        !           357:        if((symbolP->sy_type & N_TYPE) != N_SECT)
        !           358:            return;
        !           359:        if(symbolP->sy_other != text_nsect)
        !           360:            return;
        !           361: 
        !           362:        stabnamelen = strlen(symbolP->sy_name) + sizeof(":f3");
        !           363:        stabname = xmalloc(stabnamelen);
        !           364:        strcpy(stabname, symbolP->sy_name);
        !           365:        if(symbolP->sy_type & N_EXT)
        !           366:            strcat(stabname, ":F3");
        !           367:        else
        !           368:            strcat(stabname, ":f3");
        !           369:        
        !           370:        stab = symbol_new(
        !           371:                stabname,
        !           372:                36, /* N_FUN */
        !           373:                text_nsect, /* n_sect */
        !           374:                logical_input_line, /* n_desc, line number */
        !           375:                symbolP->sy_value,
        !           376:                symbolP->sy_frag);
        !           377:        free(stabname);
        !           378: }
        !           379: #endif /* NeXT generate stabs for debugging assembly code */
        !           380: 
        !           381: /*
        !           382:  * indirect_symbol_new()
        !           383:  *
        !           384:  * Return a pointer to a new indirect_symbol.
        !           385:  * Die if we can't make a new indirect_symbol.
        !           386:  * Fill in the indirect_symbol's values.
        !           387:  * Add symbol to end of section's indirect symbol chain.
        !           388:  */
        !           389: isymbolS *
        !           390: indirect_symbol_new(
        !           391: char          *name,     /* We copy this: OK to alter your copy. */
        !           392: struct frag    *frag,    /* For sy_frag. */
        !           393: unsigned long  offset)   /* Offset from frag address. */
        !           394: {
        !           395:     isymbolS *isymbolP;
        !           396:     char *preserved_copy_of_name;
        !           397:     unsigned long name_length;
        !           398:     char *p;
        !           399:     struct frag *fr_next;
        !           400: #ifdef CHECK_INDIRECTS
        !           401:     unsigned long stride, fr_fix;
        !           402: #endif
        !           403: 
        !           404:        /*
        !           405:         * First see if the last frag recorded for an indirect symbol turned
        !           406:         * out to be zero sized then changed that recorded frag to the next
        !           407:         * non-zero frag in the list.  I think this happens because we record
        !           408:         * the frag before we fill it and if we run out of space that frag gets
        !           409:         * a zero size and a new one is created.
        !           410:         */
        !           411:        if(frchain_now->frch_isym_last != NULL &&
        !           412:           frchain_now->frch_isym_last->isy_frag->fr_fix == 0){
        !           413:            if(frchain_now->frch_isym_last->isy_frag->fr_next != NULL){
        !           414:                fr_next = frchain_now->frch_isym_last->isy_frag->fr_next;
        !           415:                while(fr_next->fr_fix == 0 &&
        !           416:                      fr_next->fr_type == rs_fill &&
        !           417:                      fr_next->fr_next != NULL)
        !           418:                        fr_next = fr_next->fr_next;
        !           419:                frchain_now->frch_isym_last->isy_frag = fr_next;
        !           420:            }
        !           421:        }
        !           422: 
        !           423:        name_length = strlen(name) + 1;
        !           424:        obstack_grow(&notes, name, name_length);
        !           425:        p = obstack_finish(&notes);
        !           426:        preserved_copy_of_name = p;
        !           427:        p = obstack_alloc(&notes, sizeof(struct indirect_symbol));
        !           428:        isymbolP = (isymbolS *)p;
        !           429:        isymbolP->isy_name    = preserved_copy_of_name;
        !           430:        isymbolP->isy_offset  = offset;
        !           431:        isymbolP->isy_frag    = frag;
        !           432:        isymbolP->isy_next    = NULL;   /* End of chain. */
        !           433:        isymbolP->isy_symbol  = NULL;
        !           434: 
        !           435:        /*
        !           436:         * Link to end of indirect symbol chain and check for missing indirect
        !           437:         * symbols.
        !           438:         */
        !           439:        if(frchain_now->frch_isym_root == NULL){
        !           440: #ifdef CHECK_INDIRECTS
        !           441:            if(offset != 0)
        !           442:                as_warn("missing or bad indirect symbol for section (%s,%s)",
        !           443:                        frchain_now->frch_section.segname,
        !           444:                        frchain_now->frch_section.sectname);
        !           445: #endif
        !           446:            frchain_now->frch_isym_root = isymbolP;
        !           447:            frchain_now->frch_isym_last = isymbolP;
        !           448:        }
        !           449:        else{
        !           450: #ifdef CHECK_INDIRECTS
        !           451:            if((frchain_now->frch_section.flags & SECTION_TYPE) ==
        !           452:               S_SYMBOL_STUBS)
        !           453:                stride = frchain_now->frch_section.reserved2;
        !           454:            else
        !           455:                stride = sizeof(unsigned long);
        !           456:            if(frag == frchain_now->frch_isym_last->isy_frag){
        !           457:                if(offset - frchain_now->frch_isym_last->isy_offset != stride)
        !           458:                    as_warn("missing or bad indirect symbol for section "
        !           459:                            "(%s,%s)", frchain_now->frch_section.segname,
        !           460:                            frchain_now->frch_section.sectname);
        !           461:            }
        !           462:            else{
        !           463:                if(frchain_now->frch_isym_last->isy_frag->fr_fix < stride){
        !           464:                    fr_fix = 0;
        !           465:                    fr_next = frchain_now->frch_isym_last->isy_frag;
        !           466:                    while(fr_fix + fr_next->fr_fix < stride &&
        !           467:                          fr_next->fr_type == rs_fill &&
        !           468:                          fr_next->fr_next != NULL){
        !           469:                        fr_fix += fr_next->fr_fix;
        !           470:                        fr_next = fr_next->fr_next;
        !           471:                    }
        !           472:                    if(frag != fr_next->fr_next ||
        !           473:                       fr_fix + fr_next->fr_fix != stride ||
        !           474:                       offset != 0)
        !           475:                        as_warn("missing or bad indirect symbol for section "
        !           476:                                "(%s,%s)", frchain_now->frch_section.segname,
        !           477:                                frchain_now->frch_section.sectname);
        !           478:                }
        !           479:                else{
        !           480:                    fr_next = frchain_now->frch_isym_last->isy_frag->fr_next;
        !           481:                    /*
        !           482:                     * Because of section changes there maybe some zero length
        !           483:                     * frags after the last one that passed through here.  So
        !           484:                     * skip them and get to the last real one.
        !           485:                     */
        !           486:                    while(fr_next->fr_fix == 0 &&
        !           487:                          fr_next->fr_type == rs_fill &&
        !           488:                          fr_next->fr_next != NULL)
        !           489:                        fr_next = fr_next->fr_next;
        !           490:                    if(frag != fr_next || offset != 0)
        !           491:                        as_warn("missing or bad indirect symbol for section "
        !           492:                                "(%s,%s)", frchain_now->frch_section.segname,
        !           493:                                frchain_now->frch_section.sectname);
        !           494:                }
        !           495:            }
        !           496: #endif
        !           497:            frchain_now->frch_isym_last->isy_next = isymbolP;
        !           498:            frchain_now->frch_isym_last = isymbolP;
        !           499:        }
        !           500:        return(isymbolP);
        !           501: }
        !           502: 
        !           503: /* end: symbols.c */

unix.superglobalmegacorp.com

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