* config/tc-mips.c (md_pseudo_table): If OBJ_ELF, handle .section.
[deliverable/binutils-gdb.git] / gas / subsegs.c
index 3b4581c4bcf535fdac49ccbe8b1fa778b9cb5f6d..5ce2e9e33dba800edf130043527344d3df18b116 100644 (file)
@@ -57,6 +57,13 @@ char *const seg_name[] =
   "register",
   "",
 };                             /* Used by error reporters, dumpers etc. */
+#else /* BFD_ASSEMBLER */
+
+/* Gas segment information for bfd_abs_section_ptr and
+   bfd_und_section_ptr.  */
+static segment_info_type *abs_seg_info;
+static segment_info_type *und_seg_info;
+
 #endif /* BFD_ASSEMBLER */
 
 static void subseg_set_rest PARAMS ((segT, subsegT));
@@ -138,12 +145,17 @@ subseg_change (seg, subseg)
     if (! seginfo)
       {
        seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
-       if (! seginfo)
-         abort ();
-       seginfo->fix_root = 0;
+       memset ((PTR) seginfo, 0, sizeof (*seginfo));
+       seginfo->fix_root = NULL;
+       seginfo->fix_tail = NULL;
        seginfo->bfd_section = seg;
        seginfo->sym = 0;
-       bfd_set_section_userdata (stdoutput, seg, (char *) seginfo);
+       if (seg == bfd_abs_section_ptr)
+         abs_seg_info = seginfo;
+       else if (seg == bfd_und_section_ptr)
+         und_seg_info = seginfo;
+       else
+         bfd_set_section_userdata (stdoutput, seg, (PTR) seginfo);
       }
   }
 #else
@@ -211,10 +223,10 @@ subseg_set_rest (seg, subseg)
    * position of chain rooted in frchain_root.
    */
   for (frcP = *(lastPP = &frchain_root);
-       frcP && (int) (frcP->frch_seg) <= (int) seg;
+       frcP && frcP->frch_seg <= seg;
        frcP = *(lastPP = &frcP->frch_next))
     {
-      if ((int) (frcP->frch_seg) == (int) seg
+      if (frcP->frch_seg == seg
          && frcP->frch_subseg >= subseg)
        {
          break;
@@ -242,7 +254,7 @@ subseg_set_rest (seg, subseg)
    *
    */
   if (!frcP
-      || ((int) (frcP->frch_seg) > (int) seg
+      || (frcP->frch_seg > seg
          || frcP->frch_subseg > subseg))       /* Kinky logic only works with 2 segments. */
     {
       /*
@@ -402,12 +414,21 @@ subseg_get (segname, force_new)
   seginfo = seg_info (secptr);
   if (! seginfo)
     {
-      secptr->output_section = secptr;
+      /* Check whether output_section is set first because secptr may
+         be bfd_abs_section_ptr.  */
+      if (secptr->output_section != secptr)
+       secptr->output_section = secptr;
       seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
-      memset ((char *) seginfo, 0, sizeof(seginfo));
+      memset ((PTR) seginfo, 0, sizeof (*seginfo));
       seginfo->fix_root = NULL;
+      seginfo->fix_tail = NULL;
       seginfo->bfd_section = secptr;
-      bfd_set_section_userdata (stdoutput, secptr, (char *) seginfo);
+      if (secptr == bfd_abs_section_ptr)
+       abs_seg_info = seginfo;
+      else if (secptr == bfd_und_section_ptr)
+       und_seg_info = seginfo;
+      else
+       bfd_set_section_userdata (stdoutput, secptr, (PTR) seginfo);
       seginfo->frchainP = NULL;
       seginfo->lineno_list_head = seginfo->lineno_list_tail = NULL;
       seginfo->sym = NULL;
@@ -463,6 +484,20 @@ subseg_set (secptr, subseg)
 #define obj_sec_sym_ok_for_reloc(SEC)  0
 #endif
 
+/* Get the gas information we are storing for a section.  */
+
+segment_info_type *
+seg_info (sec)
+     segT sec;
+{
+  if (sec == bfd_abs_section_ptr)
+    return abs_seg_info;
+  else if (sec == bfd_und_section_ptr)
+    return und_seg_info;
+  else
+    return (segment_info_type *) bfd_get_section_userdata (stdoutput, sec);
+}
+
 symbolS *
 section_symbol (sec)
      segT sec;
@@ -477,7 +512,18 @@ section_symbol (sec)
   s = symbol_find (sec->name);
   if (!s)
     {
-      s = symbol_new (sec->name, sec, 0, &zero_address_frag);
+#ifndef EMIT_SECTION_SYMBOLS
+#define EMIT_SECTION_SYMBOLS 1
+#endif
+
+      if (EMIT_SECTION_SYMBOLS
+#ifdef BFD_ASSEMBLER
+         && symbol_table_frozen
+#endif
+         )
+       s = symbol_new (sec->name, sec, 0, &zero_address_frag);
+      else
+       s = symbol_create (sec->name, sec, 0, &zero_address_frag);
       S_CLEAR_EXTERNAL (s);
 
       /* Use the BFD section symbol, if possible.  */
This page took 0.026213 seconds and 4 git commands to generate.