2006-12-13 Paul Brook <paul@codesourcery.com>
[binutils-gdb.git] / gas / symbols.c
index bd4745083efd881ac392aea074a55cd535e31fe4..41fabc5df0a5987aee1fadbcf2a35fc8c3fec055 100644 (file)
@@ -145,7 +145,6 @@ symbol_create (const char *name, /* It is copied, the caller can destroy/modify.
   symbolP->bsym = bfd_make_empty_symbol (stdoutput);
   if (symbolP->bsym == NULL)
     as_fatal ("bfd_make_empty_symbol: %s", bfd_errmsg (bfd_get_error ()));
-  symbolP->bsym->udata.p = (PTR) symbolP;
   S_SET_NAME (symbolP, preserved_copy_of_name);
 
   S_SET_SEGMENT (symbolP, segment);
@@ -575,7 +574,6 @@ symbol_clone (symbolS *orgsymP, int replace)
   bsymnew->name = bsymorg->name;
   bsymnew->flags =  bsymorg->flags;
   bsymnew->section =  bsymorg->section;
-  bsymnew->udata.p = (PTR) newsymP;
   bfd_copy_private_symbol_data (bfd_asymbol_bfd (bsymorg), bsymorg,
                                bfd_asymbol_bfd (bsymnew), bsymnew);
 
@@ -600,11 +598,13 @@ symbol_clone (symbolS *orgsymP, int replace)
        symbol_lastP = newsymP;
       else if (orgsymP->sy_next)
        orgsymP->sy_next->sy_previous = newsymP;
-      orgsymP->sy_next = NULL;
+      orgsymP->sy_previous = orgsymP->sy_next = orgsymP;
       debug_verify_symchain (symbol_rootP, symbol_lastP);
 
       symbol_table_insert (newsymP);
     }
+  else
+    newsymP->sy_previous = newsymP->sy_next = newsymP;
 
   return newsymP;
 }
@@ -1080,8 +1080,9 @@ resolve_symbol_value (symbolS *symp)
              symp->sy_resolving = 0;
              goto exit_dont_set_value;
            }
-         else if (finalize_syms && final_seg == expr_section
-                  && seg_left != expr_section)
+         else if (finalize_syms
+                  && ((final_seg == expr_section && seg_left != expr_section)
+                      || symbol_shadow_p (symp)))
            {
              /* If the symbol is an expression symbol, do similarly
                 as for undefined and common syms above.  Handles
@@ -2494,6 +2495,17 @@ symbol_constant_p (symbolS *s)
   return s->sy_value.X_op == O_constant;
 }
 
+/* Return whether a symbol was cloned and thus removed from the global
+   symbol list.  */
+
+int
+symbol_shadow_p (symbolS *s)
+{
+  if (LOCAL_SYMBOL_CHECK (s))
+    return 0;
+  return s->sy_next == s;
+}
+
 /* Return the BFD symbol for a symbol.  */
 
 asymbol *