2005-05-16 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / gas / write.c
index 6ca35f225f106632644aa6d3f7c7b592b58e281d..7f4e2d57c782cea7637a376596dc476abf3a26d6 100644 (file)
@@ -1,6 +1,6 @@
 /* write.c - emit .o file
    Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003, 2004
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -17,8 +17,8 @@
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to the Free
-   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 /* This thing should be set up to do byteordering correctly.  But...  */
 
 #define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from (FIX)
 #endif
 
+#ifndef TC_FAKE_LABEL
+#define TC_FAKE_LABEL(NAME) (strcmp ((NAME), FAKE_LABEL_NAME) == 0)
+#endif
+
 /* Used to control final evaluation of expressions.  */
 int finalize_syms = 0;
 
@@ -787,12 +791,20 @@ adjust_reloc_syms (bfd *abfd ATTRIBUTE_UNUSED,
        if (fixp->fx_subsy != NULL)
          resolve_symbol_value (fixp->fx_subsy);
 
-       /* If this symbol is equated to an undefined symbol, convert
-           the fixup to being against that symbol.  */
+       /* If this symbol is equated to an undefined or common symbol,
+          convert the fixup to being against that symbol.  */
        if (symbol_equated_reloc_p (sym))
          {
+           symbolS *new_sym
+             = symbol_get_value_expression (sym)->X_add_symbol;
+           const char *name = S_GET_NAME (sym);
+           if (!S_IS_COMMON (new_sym)
+               && !TC_FAKE_LABEL (name)
+               && (!S_IS_EXTERNAL (sym) || S_IS_LOCAL (sym)))
+             as_bad (_("Local symbol `%s' can't be equated to undefined symbol `%s'"),
+                     name, S_GET_NAME (new_sym));
            fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
-           sym = symbol_get_value_expression (sym)->X_add_symbol;
+           sym = new_sym;
            fixp->fx_addsy = sym;
          }
 
@@ -942,12 +954,12 @@ write_relocs (bfd *abfd, asection *sec, PTR xxx ATTRIBUTE_UNUSED)
          continue;
        }
 
-#if 0
-      /* This test is triggered inappropriately for the SH.  */
-      if (fixp->fx_where + fixp->fx_size
-         > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
-       abort ();
-#endif
+      /*
+       This test is triggered inappropriately for the SH:
+         if (fixp->fx_where + fixp->fx_size
+            > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
+            abort ();
+      */
 
       s = bfd_install_relocation (stdoutput, reloc,
                                  fixp->fx_frag->fr_literal,
@@ -1463,20 +1475,11 @@ write_object_file (void)
 #ifdef BFD_ASSEMBLER
   /* Remove the sections created by gas for its own purposes.  */
   {
-    asection **seclist;
     int i;
 
-    seclist = &stdoutput->sections;
-    while (*seclist)
-      {
-       if (*seclist == reg_section || *seclist == expr_section)
-         {
-           bfd_section_list_remove (stdoutput, seclist);
-           stdoutput->section_count--;
-         }
-       else
-         seclist = &(*seclist)->next;
-      }
+    bfd_section_list_remove (stdoutput, reg_section);
+    bfd_section_list_remove (stdoutput, expr_section);
+    stdoutput->section_count -= 2;
     i = 0;
     bfd_map_over_sections (stdoutput, renumber_sections, &i);
   }
@@ -1569,11 +1572,11 @@ write_object_file (void)
      Count the number of string-table chars we will emit.
      Put this info into the headers as appropriate.  */
   know (zero_address_frag.fr_address == 0);
-  string_byte_count = sizeof (string_byte_count);
+  string_byte_count = 4;
 
   obj_crawl_symbol_chain (&headers);
 
-  if (string_byte_count == sizeof (string_byte_count))
+  if (string_byte_count == 4)
     string_byte_count = 0;
 
   H_SET_STRING_SIZE (&headers, string_byte_count);
@@ -1882,12 +1885,22 @@ write_object_file (void)
   if (symbol_rootP)
     {
       symbolS *symp;
+      bfd_boolean skip_next_symbol = FALSE;
 
       for (symp = symbol_rootP; symp; symp = symbol_next (symp))
        {
          int punt = 0;
          const char *name;
 
+         if (skip_next_symbol)
+           {
+             /* Don't do anything besides moving the value of the
+                symbol from the GAS value-field to the BFD value-field.  */
+             symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp);
+             skip_next_symbol = FALSE;
+             continue;
+           }
+
          if (symbol_mri_common_p (symp))
            {
              if (S_IS_EXTERNAL (symp))
@@ -1917,6 +1930,15 @@ write_object_file (void)
              symbols.  */
          if (symbol_equated_reloc_p (symp))
            {
+             const char *name = S_GET_NAME (symp);
+             if (S_IS_COMMON (symp)
+                 && !TC_FAKE_LABEL (name)
+                 && (!S_IS_EXTERNAL (symp) || S_IS_LOCAL (symp)))
+               {
+                 expressionS *e = symbol_get_value_expression (symp);
+                 as_bad (_("Local symbol `%s' can't be equated to common symbol `%s'"),
+                         name, S_GET_NAME (e->X_add_symbol));
+               }
              symbol_remove (symp, &symbol_rootP, &symbol_lastP);
              continue;
            }
@@ -1926,13 +1948,6 @@ write_object_file (void)
          if (S_IS_DEFINED (symp) == 0
              && S_GET_VALUE (symp) != 0)
            S_SET_SEGMENT (symp, bfd_com_section_ptr);
-#if 0
-         printf ("symbol `%s'\n\t@%x: value=%d flags=%x seg=%s\n",
-                 S_GET_NAME (symp), symp,
-                 S_GET_VALUE (symp),
-                 symbol_get_bfdsym (symp)->flags,
-                 segment_name (S_GET_SEGMENT (symp)));
-#endif
 
 #ifdef obj_frob_symbol
          obj_frob_symbol (symp, punt);
@@ -1950,10 +1965,10 @@ write_object_file (void)
          if (symp == abs_section_sym
              || (! EMIT_SECTION_SYMBOLS
                  && symbol_section_p (symp))
-             /* Note that S_IS_EXTERN and S_IS_LOCAL are not always
+             /* Note that S_IS_EXTERNAL and S_IS_LOCAL are not always
                 opposites.  Sometimes the former checks flags and the
                 latter examines the name...  */
-             || (!S_IS_EXTERN (symp)
+             || (!S_IS_EXTERNAL (symp)
                  && (punt || S_IS_LOCAL (symp))
                  && ! symbol_used_in_reloc_p (symp)))
            {
@@ -1976,6 +1991,12 @@ write_object_file (void)
          /* Set the value into the BFD symbol.  Up til now the value
             has only been kept in the gas symbolS struct.  */
          symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp);
+
+         /* A warning construct is a warning symbol followed by the
+            symbol warned about.  Don't let anything object-format or
+            target-specific muck with it; it's ready for output.  */
+         if (symbol_get_bfdsym (symp)->flags & BSF_WARNING)
+           skip_next_symbol = TRUE;
        }
     }
 
@@ -2080,14 +2101,10 @@ relax_frag (segT segment, fragS *fragP, long stretch)
 #ifdef TC_PCREL_ADJUST
   /* Currently only the ns32k family needs this.  */
   aim += TC_PCREL_ADJUST (fragP);
-/* #else */
-  /* This machine doesn't want to use pcrel_adjust.
-     In that case, pcrel_adjust should be zero.  */
-#if 0
-  assert (fragP->fr_targ.ns32k.pcrel_adjust == 0);
-#endif
 #endif
-#ifdef md_prepare_relax_scan /* formerly called M68K_AIM_KLUDGE  */
+
+#ifdef md_prepare_relax_scan
+  /* Formerly called M68K_AIM_KLUDGE.  */
   md_prepare_relax_scan (fragP, address, aim, this_state, this_type);
 #endif
 
@@ -2387,7 +2404,9 @@ relax_segment (struct frag *segment_frag_root, segT segment)
                          into the section.  Here it is assumed that the
                          section's VMA is zero, and can omit subtracting it
                          from the symbol's value to get the address offset.  */
-                      know (S_GET_SECTION (symbolP)->vma == 0);
+#ifdef BFD_ASSEMBLER
+                      know (S_GET_SEGMENT (symbolP)->vma == 0);
+#endif
                      target += S_GET_VALUE (symbolP) * OCTETS_PER_BYTE;
                    }
 
@@ -2575,7 +2594,6 @@ fixup_segment (fixS *fixP, segT this_segment)
       if (fixP->fx_addsy != NULL
          && symbol_mri_common_p (fixP->fx_addsy))
        {
-         know (fixP->fx_addsy->sy_value.X_op == O_symbol);
          add_number += S_GET_VALUE (fixP->fx_addsy);
          fixP->fx_offset = add_number;
          fixP->fx_addsy
This page took 0.030829 seconds and 4 git commands to generate.