Annotation of GNUtools/cctools/as/symbols.c, revision 1.1.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.