home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / cctools / as / symbols.c < prev    next >
C/C++ Source or Header  |  1997-01-24  |  15KB  |  535 lines

  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(¬es,name,name_length);
  170.   p=obstack_finish(¬es);
  171.   /* obstack_1done( ¬es, name, name_length, &p ); */
  172.   preserved_copy_of_name = p;
  173.   p=obstack_alloc(¬es,sizeof(struct symbol));
  174.   /* obstack_1blank( ¬es, 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. /* This is used to work around compiler optimizer bug #50416 */
  214. static volatile unsigned int temp;
  215.  
  216. void
  217. colon(        /* just seen "x:" - rattle symbols & frags */
  218. char *sym_name) /* symbol name, as a cannonical string */
  219.         /* We copy this string: OK to alter later. */
  220. {
  221.   register struct symbol * symbolP; /* symbol we are working with */
  222.  
  223.   if (frchain_now == NULL)
  224.     {
  225.       know(flagseen['n']);
  226.       as_fatal("with -n a section directive must be seen before assembly "
  227.            "can begin");
  228.     }
  229.   if ((symbolP = symbol_table_lookup( sym_name )))
  230.     {
  231.       /*
  232.        *    Now check for undefined symbols
  233.        */
  234.       if ((symbolP -> sy_type & N_TYPE) == N_UNDF)
  235.     {
  236.       temp = symbolP->sy_desc;
  237.       if(   symbolP -> sy_other == 0
  238.          /* bug #50416 -O causes this not to work for:
  239.          && ((symbolP->sy_desc) & (~REFERENCE_TYPE)) == 0
  240.          */
  241.          && (temp & (~REFERENCE_TYPE)) == 0
  242.          && symbolP -> sy_value == 0)
  243.         {
  244.           symbolP -> sy_frag  = frag_now;
  245.           symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal;
  246.           know( N_UNDF == 0 );
  247.           symbolP -> sy_type |= N_SECT; /* keep N_EXT bit */
  248.           symbolP -> sy_other = frchain_now->frch_nsect;
  249.           symbolP -> sy_desc &= ~REFERENCE_TYPE;
  250. #ifdef NeXT    /* generate stabs for debugging assembly code */
  251.           if(flagseen['g'])
  252.           make_stab_for_symbol(symbolP);
  253. #endif
  254.         }
  255.       else
  256.         {
  257.           as_fatal( "Symbol \"%s\" is already defined as \"%s\"/%d.%d.%ld.",
  258.               sym_name,
  259.               seg_name [(int) N_TYPE_seg [symbolP -> sy_type & N_TYPE]],
  260.               symbolP -> sy_other, symbolP -> sy_desc,
  261.               symbolP -> sy_value);
  262.         }
  263.     }
  264.       else
  265.     {
  266.       as_fatal("Symbol %s already defined.",sym_name);
  267.     }
  268.     }
  269.   else
  270.     {
  271.       symbolP = symbol_new (sym_name,
  272.                 N_SECT,
  273.                       frchain_now->frch_nsect,
  274.                 0,
  275.                 (valueT)(obstack_next_free(&frags)-frag_now->fr_literal),
  276.                 frag_now);
  277.       symbol_table_insert (symbolP);
  278. #ifdef NeXT    /* generate stabs for debugging assembly code */
  279.       if(flagseen['g'])
  280.       make_stab_for_symbol(symbolP);
  281. #endif
  282.     }
  283. }
  284.  
  285.  
  286. /*
  287.  *            symbol_table_insert()
  288.  *
  289.  * Die if we can't insert the symbol.
  290.  *
  291.  */
  292. void
  293. symbol_table_insert(
  294. struct symbol *symbolP)
  295. {
  296.   register char *    error_string;
  297.  
  298.   know( symbolP );
  299.   know( symbolP -> sy_name );
  300.   if ( * (error_string = hash_jam (sy_hash, symbolP -> sy_name, (char *)symbolP)))
  301.     {
  302.       as_fatal( "Inserting \"%s\" into symbol table failed: %s",
  303.           symbolP -> sy_name, error_string);
  304.     }
  305. }
  306.  
  307. /*
  308.  *            symbol_find_or_make()
  309.  *
  310.  * If a symbol name does not exist, create it as undefined, and insert
  311.  * it into the symbol table. Return a pointer to it.
  312.  */
  313. symbolS *
  314. symbol_find_or_make(
  315. char *name)
  316. {
  317.   register symbolS *    symbolP;
  318.  
  319.   symbolP = symbol_table_lookup (name);
  320.   if (symbolP == NULL)
  321.     {
  322.       symbolP = symbol_new (name, N_UNDF, 0, 0, 0, & zero_address_frag);
  323.       symbol_table_insert (symbolP);
  324.     }
  325.   return (symbolP);
  326. }
  327.  
  328. /*
  329.  *            symbol_find()
  330.  * 
  331.  * Implement symbol table lookup.
  332.  * In:    A symbol's name as a string: '\0' can't be part of a symbol name.
  333.  * Out:    NULL if the name was not in the symbol table, else the address
  334.  *    of a struct symbol associated with that name.
  335.  */
  336. symbolS *
  337. symbol_find(
  338. char *name)
  339. {
  340.   return ( (symbolS *) hash_find( sy_hash, name ));
  341. }
  342.  
  343. /*
  344.  *            symbol_table_lookup()
  345.  * 
  346.  * Same as symbol_find() except assumes the symbol is being looked up and is
  347.  * a non-lazy symbol reference.
  348.  */
  349. symbolS *
  350. symbol_table_lookup(
  351. char *name)
  352. {
  353.   register symbolS *    symbolP;
  354.  
  355.   symbolP = (symbolS *) hash_find( sy_hash, name );
  356.   if(symbolP != NULL)
  357.     symbolP->sy_desc &= ~REFERENCE_FLAG_UNDEFINED_LAZY;
  358.   return(symbolP);
  359. }
  360.  
  361. #ifdef NeXT    /* generate stabs for debugging assembly code */
  362. /*
  363.  * make_stab_for_symbol() is called when -g is present for a label that is
  364.  * being defined.  If the label is a text label and in the (__TEXT,__text)
  365.  * section and not a local label create a stab for it.
  366.  * 
  367.  * See the detailed comments about stabs in read_a_source_file() for a
  368.  * description of what is going on here.
  369.  */
  370. static
  371. void
  372. make_stab_for_symbol(
  373. symbolS *symbolP)
  374. {
  375.     symbolS *stab;
  376.     int stabnamelen;
  377.     char *stabname;
  378.  
  379.     if(symbolP->sy_name[0] == 'L')
  380.         return;
  381.     if((symbolP->sy_type & N_TYPE) != N_SECT)
  382.         return;
  383.     if(symbolP->sy_other != text_nsect)
  384.         return;
  385.  
  386.     stabnamelen = strlen(symbolP->sy_name) + sizeof(":f3");
  387.     stabname = xmalloc(stabnamelen);
  388.     strcpy(stabname, symbolP->sy_name);
  389.     if(symbolP->sy_type & N_EXT)
  390.         strcat(stabname, ":F3");
  391.     else
  392.         strcat(stabname, ":f3");
  393.     
  394.     stab = symbol_new(
  395.         stabname,
  396.         36, /* N_FUN */
  397.         text_nsect, /* n_sect */
  398.         logical_input_line, /* n_desc, line number */
  399.         symbolP->sy_value,
  400.         symbolP->sy_frag);
  401.     free(stabname);
  402. }
  403. #endif /* NeXT generate stabs for debugging assembly code */
  404.  
  405. /*
  406.  * indirect_symbol_new()
  407.  *
  408.  * Return a pointer to a new indirect_symbol.
  409.  * Die if we can't make a new indirect_symbol.
  410.  * Fill in the indirect_symbol's values.
  411.  * Add symbol to end of section's indirect symbol chain.
  412.  */
  413. isymbolS *
  414. indirect_symbol_new(
  415. char           *name,      /* We copy this: OK to alter your copy. */
  416. struct frag    *frag,      /* For sy_frag. */
  417. unsigned long    offset)      /* Offset from frag address. */
  418. {
  419.     isymbolS *isymbolP;
  420.     char *preserved_copy_of_name;
  421.     unsigned long name_length;
  422.     char *p;
  423.     struct frag *fr_next;
  424.     symbolS *symbolP;
  425. #ifdef CHECK_INDIRECTS
  426.     unsigned long stride, fr_fix;
  427. #endif
  428.  
  429.     /*
  430.      * First see if the last frag recorded for an indirect symbol turned
  431.      * out to be zero sized then changed that recorded frag to the next
  432.      * non-zero frag in the list.  I think this happens because we record
  433.      * the frag before we fill it and if we run out of space that frag gets
  434.      * a zero size and a new one is created.
  435.      */
  436.     if(frchain_now->frch_isym_last != NULL &&
  437.        frchain_now->frch_isym_last->isy_frag->fr_fix == 0){
  438.         if(frchain_now->frch_isym_last->isy_frag->fr_next != NULL){
  439.         fr_next = frchain_now->frch_isym_last->isy_frag->fr_next;
  440.         while(fr_next->fr_fix == 0 &&
  441.               fr_next->fr_type == rs_fill &&
  442.               fr_next->fr_next != NULL)
  443.             fr_next = fr_next->fr_next;
  444.         frchain_now->frch_isym_last->isy_frag = fr_next;
  445.         }
  446.     }
  447.  
  448.     name_length = strlen(name) + 1;
  449.     obstack_grow(¬es, name, name_length);
  450.     p = obstack_finish(¬es);
  451.     preserved_copy_of_name = p;
  452.     p = obstack_alloc(¬es, sizeof(struct indirect_symbol));
  453.     isymbolP = (isymbolS *)p;
  454.     isymbolP->isy_name    = preserved_copy_of_name;
  455.     isymbolP->isy_offset  = offset;
  456.     isymbolP->isy_frag    = frag;
  457.     isymbolP->isy_next    = NULL;    /* End of chain. */
  458.     isymbolP->isy_symbol  = NULL;
  459.  
  460.     /*
  461.      * Link to end of indirect symbol chain and check for missing indirect
  462.      * symbols.
  463.      */
  464.     if(frchain_now->frch_isym_root == NULL){
  465. #ifdef CHECK_INDIRECTS
  466.         if(offset != 0)
  467.         as_warn("missing or bad indirect symbol for section (%s,%s)",
  468.             frchain_now->frch_section.segname,
  469.             frchain_now->frch_section.sectname);
  470. #endif
  471.         frchain_now->frch_isym_root = isymbolP;
  472.         frchain_now->frch_isym_last = isymbolP;
  473.     }
  474.     else{
  475. #ifdef CHECK_INDIRECTS
  476.         if((frchain_now->frch_section.flags & SECTION_TYPE) ==
  477.            S_SYMBOL_STUBS)
  478.         stride = frchain_now->frch_section.reserved2;
  479.         else
  480.         stride = sizeof(unsigned long);
  481.         if(frag == frchain_now->frch_isym_last->isy_frag){
  482.         if(offset - frchain_now->frch_isym_last->isy_offset != stride)
  483.             as_warn("missing or bad indirect symbol for section "
  484.                 "(%s,%s)", frchain_now->frch_section.segname,
  485.                 frchain_now->frch_section.sectname);
  486.         }
  487.         else{
  488.         if(frchain_now->frch_isym_last->isy_frag->fr_fix < stride){
  489.             fr_fix = 0;
  490.             fr_next = frchain_now->frch_isym_last->isy_frag;
  491.             while(fr_fix + fr_next->fr_fix < stride &&
  492.               fr_next->fr_type == rs_fill &&
  493.               fr_next->fr_next != NULL){
  494.             fr_fix += fr_next->fr_fix;
  495.             fr_next = fr_next->fr_next;
  496.             }
  497.             if(frag != fr_next->fr_next ||
  498.                fr_fix + fr_next->fr_fix != stride ||
  499.                offset != 0)
  500.             as_warn("missing or bad indirect symbol for section "
  501.                 "(%s,%s)", frchain_now->frch_section.segname,
  502.                 frchain_now->frch_section.sectname);
  503.         }
  504.         else{
  505.             fr_next = frchain_now->frch_isym_last->isy_frag->fr_next;
  506.             /*
  507.              * Because of section changes there maybe some zero length
  508.              * frags after the last one that passed through here.  So
  509.              * skip them and get to the last real one.
  510.              */
  511.             while(fr_next->fr_fix == 0 &&
  512.               fr_next->fr_type == rs_fill &&
  513.               fr_next->fr_next != NULL)
  514.             fr_next = fr_next->fr_next;
  515.             if(frag != fr_next || offset != 0)
  516.             as_warn("missing or bad indirect symbol for section "
  517.                 "(%s,%s)", frchain_now->frch_section.segname,
  518.                 frchain_now->frch_section.sectname);
  519.         }
  520.         }
  521. #endif
  522.         frchain_now->frch_isym_last->isy_next = isymbolP;
  523.         frchain_now->frch_isym_last = isymbolP;
  524.     }
  525.     if((frchain_now->frch_section.flags & SECTION_TYPE) ==
  526.        S_NON_LAZY_SYMBOL_POINTERS){
  527.         symbolP = (symbolS *)hash_find(sy_hash, name);
  528.         if(symbolP != NULL)
  529.         symbolP->sy_desc &= ~REFERENCE_FLAG_UNDEFINED_LAZY;
  530.     }
  531.     return(isymbolP);
  532. }
  533.  
  534. /* end: symbols.c */
  535.