Fix movw/movb operands for 68HC12
[deliverable/binutils-gdb.git] / gas / subsegs.c
index 3280bcd18c070191450dd1eff5d6d8be4f7539cb..1d29bbaf2b38cd8ff6185f3f13e030e523004839 100644 (file)
@@ -1,5 +1,5 @@
 /* subsegs.c - subsegments -
-   Copyright (C) 1987, 1990, 1991, 1992, 1993, 1994
+   Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
    GNU General Public License for more details.
 
    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.  */
+   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.  */
 
-/*
- * Segments & sub-segments.
- */
+/* Segments & sub-segments.  */
 
 #include "as.h"
 
@@ -36,15 +35,17 @@ static struct obstack frchains;
 segment_info_type segment_info[SEG_MAXIMUM_ORDINAL];
 
 #else
-/* Commented in "subsegs.h". */
+/* Commented in "subsegs.h".  */
 frchainS *data0_frchainP, *bss0_frchainP;
 
 #endif /* MANY_SEGMENTS */
-char const *const seg_name[] =
-{
+char const *const seg_name[] = {
   "absolute",
 #ifdef MANY_SEGMENTS
   "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9",
+  "e10", "e11", "e12", "e13", "e14", "e15", "e16", "e17", "e18", "e19",
+  "e20", "e21", "e22", "e23", "e24", "e25", "e26", "e27", "e28", "e29",
+  "e30", "e31", "e32", "e33", "e34", "e35", "e36", "e37", "e38", "e39",
 #else
   "text",
   "data",
@@ -58,7 +59,7 @@ char const *const seg_name[] =
   "transfert vector postload",
   "register",
   "",
-};                             /* Used by error reporters, dumpers etc. */
+};                             /* Used by error reporters, dumpers etc.  */
 #else /* BFD_ASSEMBLER */
 
 /* Gas segment information for bfd_abs_section_ptr and
@@ -99,12 +100,12 @@ subsegs_begin ()
 #endif
 
   frchain_root = NULL;
-  frchain_now = NULL;          /* Warn new_subseg() that we are booting. */
+  frchain_now = NULL;          /* Warn new_subseg() that we are booting.  */
 
   frag_now = &dummy_frag;
 
 #ifndef BFD_ASSEMBLER
-  now_subseg = 42;             /* Lie for 1st call to subseg_new. */
+  now_subseg = 42;             /* Lie for 1st call to subseg_new.  */
 #ifdef MANY_SEGMENTS
   {
     int i;
@@ -126,7 +127,9 @@ subsegs_begin ()
 
   absolute_frchain.frch_seg = absolute_section;
   absolute_frchain.frch_subseg = 0;
+#ifdef BFD_ASSEMBLER
   absolute_frchain.fix_root = absolute_frchain.fix_tail = 0;
+#endif
   absolute_frchain.frch_frag_now = &zero_address_frag;
   absolute_frchain.frch_root = absolute_frchain.frch_last = &zero_address_frag;
 }
@@ -203,12 +206,9 @@ subseg_set_rest (seg, subseg)
      segT seg;
      subsegT subseg;
 {
-  long tmp;                    /* JF for obstack alignment hacking */
   register frchainS *frcP;     /* crawl frchain chain */
   register frchainS **lastPP;  /* address of last pointer */
   frchainS *newP;              /* address of new frchain */
-  register fragS *former_last_fragP;
-  register fragS *new_fragP;
 
   mri_common_symbol = NULL;
 
@@ -272,12 +272,11 @@ subseg_set_rest (seg, subseg)
    */
   if (!frcP
       || (frcP->frch_seg > seg
-         || frcP->frch_subseg > subseg))       /* Kinky logic only works with 2 segments. */
+         || frcP->frch_subseg > subseg))       /* Kinky logic only works with 2 segments.  */
     {
       /*
        * This should be the only code that creates a frchainS.
        */
-      extern fragS *frag_alloc ();
       newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS));
       newP->frch_subseg = subseg;
       newP->frch_seg = seg;
@@ -285,7 +284,7 @@ subseg_set_rest (seg, subseg)
       newP->fix_root = NULL;
       newP->fix_tail = NULL;
 #endif
-      obstack_begin (&newP->frch_obstack, 5000);
+      obstack_begin (&newP->frch_obstack, chunksize);
 #if __GNUC__ >= 2
       obstack_alignment_mask (&newP->frch_obstack) = __alignof__ (fragS) - 1;
 #endif
@@ -296,6 +295,16 @@ subseg_set_rest (seg, subseg)
 
       *lastPP = newP;
       newP->frch_next = frcP;  /* perhaps NULL */
+
+#ifdef BFD_ASSEMBLER
+      {
+       segment_info_type *seginfo;
+       seginfo = seg_info (seg);
+       if (seginfo && seginfo->frchainP == frcP)
+         seginfo->frchainP = newP;
+      }
+#endif
+
       frcP = newP;
     }
   /*
@@ -364,7 +373,7 @@ subseg_new (segname, subseg)
     return new_seg;
   }
 #else
-  as_bad ("Attempt to switch to nonexistent segment \"%s\"", segname);
+  as_bad (_("Attempt to switch to nonexistent segment \"%s\""), segname);
   return now_seg;
 #endif
 }
@@ -511,32 +520,140 @@ section_symbol (sec)
     abort ();
   if (seginfo->sym)
     return seginfo->sym;
-  s = symbol_find (sec->name);
-  if (!s)
-    {
+
 #ifndef EMIT_SECTION_SYMBOLS
 #define EMIT_SECTION_SYMBOLS 1
 #endif
 
-      if (! EMIT_SECTION_SYMBOLS
+  if (! EMIT_SECTION_SYMBOLS
 #ifdef BFD_ASSEMBLER
-         && symbol_table_frozen
+      || symbol_table_frozen
 #endif
-         )
-       /* Here we know it won't be going into the symbol table.  */
-       s = symbol_create (sec->name, sec, 0, &zero_address_frag);
-      else
+      )
+    {
+      /* Here we know it won't be going into the symbol table.  */
+      s = symbol_create (sec->name, sec, 0, &zero_address_frag);
+    }
+  else
+    {
+      s = symbol_find_base (sec->name, 0);
+      if (s == NULL)
        s = symbol_new (sec->name, sec, 0, &zero_address_frag);
-      S_CLEAR_EXTERNAL (s);
-
-      /* Use the BFD section symbol, if possible.  */
-      if (obj_sec_sym_ok_for_reloc (sec))
-       s->bsym = sec->symbol;
+      else
+       {
+         if (S_GET_SEGMENT (s) == undefined_section)
+           {
+             S_SET_SEGMENT (s, sec);
+             symbol_set_frag (s, &zero_address_frag);
+           }
+       }
     }
+
+  S_CLEAR_EXTERNAL (s);
+
+  /* Use the BFD section symbol, if possible.  */
+  if (obj_sec_sym_ok_for_reloc (sec))
+    symbol_set_bfdsym (s, sec->symbol);
+
   seginfo->sym = s;
   return s;
 }
 
 #endif /* BFD_ASSEMBLER */
 
+/* Return whether the specified segment is thought to hold text.  */
+
+#ifndef BFD_ASSEMBLER
+const char * const nontext_section_names[] = {
+  ".eh_frame",
+  ".gcc_except_table",
+#ifdef OBJ_COFF
+#ifndef COFF_LONG_SECTION_NAMES
+  ".eh_fram",
+  ".gcc_exc",
+#endif
+#endif
+  NULL
+};
+#endif /* ! BFD_ASSEMBLER */
+
+int
+subseg_text_p (sec)
+     segT sec;
+{
+#ifdef BFD_ASSEMBLER
+  return (bfd_get_section_flags (stdoutput, sec) & SEC_CODE) != 0;
+#else /* ! BFD_ASSEMBLER */
+  const char * const *p;
+
+  if (sec == data_section || sec == bss_section)
+    return 0;
+
+  for (p = nontext_section_names; *p != NULL; ++p)
+    {
+      if (strcmp (segment_name (sec), *p) == 0)
+       return 0;
+
+#ifdef obj_segment_name
+      if (strcmp (obj_segment_name (sec), *p) == 0)
+       return 0;
+#endif
+    }
+
+  return 1;
+
+#endif /* ! BFD_ASSEMBLER */
+}
+
+void
+subsegs_print_statistics (file)
+     FILE *file;
+{
+  frchainS *frchp;
+  fprintf (file, "frag chains:\n");
+  for (frchp = frchain_root; frchp; frchp = frchp->frch_next)
+    {
+      int count = 0;
+      fragS *fragp;
+
+      /* If frch_subseg is non-zero, it's probably been chained onto
+        the end of a previous subsection.  Don't count it again.  */
+      if (frchp->frch_subseg != 0)
+       continue;
+
+      /* Skip gas-internal sections.  */
+      if (segment_name (frchp->frch_seg)[0] == '*')
+       continue;
+
+      for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
+       {
+#if 0
+         switch (fragp->fr_type)
+           {
+           case rs_fill:
+             fprintf (file, "f"); break;
+           case rs_align:
+             fprintf (file, "a"); break;
+           case rs_align_code:
+             fprintf (file, "c"); break;
+           case rs_org:
+             fprintf (file, "o"); break;
+           case rs_machine_dependent:
+             fprintf (file, "m"); break;
+           case rs_space:
+             fprintf (file, "s"); break;
+           case 0:
+             fprintf (file, "0"); break;
+           default:
+             fprintf (file, "?"); break;
+           }
+#endif
+         count++;
+       }
+      fprintf (file, "\n");
+      fprintf (file, "\t%p %-10s\t%10d frags\n", frchp,
+              segment_name (frchp->frch_seg), count);
+    }
+}
+
 /* end of subsegs.c */
This page took 0.026328 seconds and 4 git commands to generate.