2001-06-18 Philip Blundell <philb@gnu.org>
[external/binutils.git] / gas / symbols.c
index b983ddb..8396dab 100644 (file)
@@ -255,6 +255,10 @@ local_symbol_convert (locsym)
   /* Local symbols are always either defined or used.  */
   ret->sy_used = 1;
 
+#ifdef TC_LOCAL_SYMFIELD_CONVERT
+  TC_LOCAL_SYMFIELD_CONVERT (locsym, ret);
+#endif
+
   symbol_table_insert (ret);
 
   local_symbol_mark_converted (locsym);
@@ -827,9 +831,8 @@ verify_symbol_chain_2 (sym)
    values.  */
 
 valueT
-resolve_symbol_value (symp, finalize)
+resolve_symbol_value (symp)
      symbolS *symp;
-     int finalize;
 {
   int resolved;
   valueT final_val;
@@ -846,7 +849,7 @@ resolve_symbol_value (symp, finalize)
       final_val = (local_symbol_get_frag (locsym)->fr_address
                   + locsym->lsy_offset) / bfd_octets_per_byte (stdoutput);
 
-      if (finalize)
+      if (finalize_syms)
        {
          locsym->lsy_offset = final_val;
          local_symbol_mark_resolved (locsym);
@@ -869,7 +872,7 @@ resolve_symbol_value (symp, finalize)
 
   if (symp->sy_resolving)
     {
-      if (finalize)
+      if (finalize_syms)
        as_bad (_("Symbol definition loop encountered at %s"),
                S_GET_NAME (symp));
       final_val = 0;
@@ -909,7 +912,7 @@ resolve_symbol_value (symp, finalize)
 
        case O_symbol:
        case O_symbol_rva:
-         left = resolve_symbol_value (add_symbol, finalize);
+         left = resolve_symbol_value (add_symbol);
        do_symbol:
 
          if (symp->sy_mri_common)
@@ -921,7 +924,7 @@ resolve_symbol_value (symp, finalize)
              break;
            }
 
-         if (finalize && final_val == 0)
+         if (finalize_syms && final_val == 0)
            {
              if (LOCAL_SYMBOL_CHECK (add_symbol))
                add_symbol = local_symbol_convert ((struct local_symbol *)
@@ -937,15 +940,16 @@ resolve_symbol_value (symp, finalize)
              is equated.  */
          if (! S_IS_DEFINED (add_symbol) || S_IS_COMMON (add_symbol))
            {
-             if (finalize)
+             if (finalize_syms)
                {
-                 S_SET_SEGMENT (symp, S_GET_SEGMENT (add_symbol));
+                 final_seg = S_GET_SEGMENT (add_symbol);
                  symp->sy_value.X_op = O_symbol;
                  symp->sy_value.X_add_symbol = add_symbol;
                  symp->sy_value.X_add_number = final_val;
                }
              final_val = 0;
              resolved = symbol_resolved_p (add_symbol);
+             symp->sy_resolving = 0;
              goto exit_dont_set_value;
            }
          else
@@ -961,7 +965,7 @@ resolve_symbol_value (symp, finalize)
        case O_uminus:
        case O_bit_not:
        case O_logical_not:
-         left = resolve_symbol_value (add_symbol, finalize);
+         left = resolve_symbol_value (add_symbol);
 
          if (op == O_uminus)
            left = -left;
@@ -996,8 +1000,8 @@ resolve_symbol_value (symp, finalize)
        case O_gt:
        case O_logical_and:
        case O_logical_or:
-         left = resolve_symbol_value (add_symbol, finalize);
-         right = resolve_symbol_value (op_symbol, finalize);
+         left = resolve_symbol_value (add_symbol);
+         right = resolve_symbol_value (op_symbol);
          seg_left = S_GET_SEGMENT (add_symbol);
          seg_right = S_GET_SEGMENT (op_symbol);
 
@@ -1039,7 +1043,7 @@ resolve_symbol_value (symp, finalize)
              && (op != O_subtract
                  || seg_left != seg_right
                  || seg_left == undefined_section)
-             && finalize)
+             && finalize_syms)
            {
              char *file;
              unsigned int line;
@@ -1081,7 +1085,7 @@ resolve_symbol_value (symp, finalize)
            {
              /* If seg_right is not absolute_section, then we've
                  already issued a warning about using a bad symbol.  */
-             if (seg_right == absolute_section && finalize)
+             if (seg_right == absolute_section && finalize_syms)
                {
                  char *file;
                  unsigned int line;
@@ -1141,21 +1145,21 @@ resolve_symbol_value (symp, finalize)
       symp->sy_resolving = 0;
     }
 
-  if (finalize)
-    {
-      S_SET_VALUE (symp, final_val);
+  if (finalize_syms)
+    S_SET_VALUE (symp, final_val);
 
+exit_dont_set_value:
+  /* Always set the segment, even if not finalizing the value.
+     The segment is used to determine whether a symbol is defined.  */
 #if defined (OBJ_AOUT) && ! defined (BFD_ASSEMBLER)
-      /* The old a.out backend does not handle S_SET_SEGMENT correctly
-         for a stab symbol, so we use this bad hack.  */
-      if (final_seg != S_GET_SEGMENT (symp))
+  /* The old a.out backend does not handle S_SET_SEGMENT correctly
+     for a stab symbol, so we use this bad hack.  */
+  if (final_seg != S_GET_SEGMENT (symp))
 #endif
-       S_SET_SEGMENT (symp, final_seg);
-    }
+    S_SET_SEGMENT (symp, final_seg);
 
-exit_dont_set_value:
   /* Don't worry if we can't resolve an expr_section symbol.  */
-  if (finalize)
+  if (finalize_syms)
     {
       if (resolved)
        symp->sy_resolved = 1;
@@ -1182,7 +1186,7 @@ resolve_local_symbol (key, value)
      PTR value;
 {
   if (value != NULL)
-    resolve_symbol_value (value, 1);
+    resolve_symbol_value (value);
 }
 
 #endif
@@ -1574,7 +1578,11 @@ S_GET_VALUE (s)
 #endif
 
   if (!s->sy_resolved && s->sy_value.X_op != O_constant)
-    resolve_symbol_value (s, 1);
+    {
+      valueT val = resolve_symbol_value (s);
+      if (!finalize_syms)
+       return val;
+    }
   if (s->sy_value.X_op != O_constant)
     {
       static symbolS *recur;
@@ -1816,6 +1824,17 @@ S_SET_EXTERNAL (s)
       /* Let .weak override .global.  */
       return;
     }
+  if (s->bsym->flags & BSF_SECTION_SYM)
+    {
+      char * file;
+      unsigned int line;
+      
+      /* Do not reassign section symbols.  */
+      as_where (& file, & line);
+      as_warn_where (file, line,
+                    _("Section symbols are already global"));
+      return;
+    }
   s->bsym->flags |= BSF_GLOBAL;
   s->bsym->flags &= ~(BSF_LOCAL | BSF_WEAK);
 }