This set of patches add support for aout emulation on the x86
[deliverable/binutils-gdb.git] / gas / config / obj-coff.c
index b50716c49f061b4430f327415ea2c8c0cd41f41e..eceda5a1b8eb68230b39a59e2705ccf92ca29a82 100644 (file)
 
 static void obj_coff_bss PARAMS ((int));
 const char *s_get_name PARAMS ((symbolS * s));
-static symbolS *def_symbol_in_progress;
+static void obj_coff_ln PARAMS ((int));
+static void obj_coff_def PARAMS ((int));
+static void obj_coff_endef PARAMS ((int));
+static void obj_coff_dim PARAMS ((int));
+static void obj_coff_line PARAMS ((int));
+static void obj_coff_size PARAMS ((int));
+static void obj_coff_scl PARAMS ((int));
+static void obj_coff_tag PARAMS ((int));
+static void obj_coff_val PARAMS ((int));
+static void obj_coff_type PARAMS ((int));
+static void obj_coff_ident PARAMS ((int));
+#ifdef BFD_ASSEMBLER
+static void obj_coff_loc PARAMS((int));
+#endif
 
+/* This is used to hold the symbol built by a sequence of pseudo-ops
+   from .def and .endef.  */
+static symbolS *def_symbol_in_progress;
 \f
 /* stack stuff */
 typedef struct
@@ -334,6 +350,8 @@ c_dot_file_symbol (filename)
 {
   symbolS *symbolP;
 
+  /* BFD converts filename to a .file symbol with an aux entry.  It
+     also handles chaining.  */
   symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
 
   S_SET_STORAGE_CLASS (symbolP, C_FILE);
@@ -420,6 +438,12 @@ add_lineno (frag, offset, num)
     {
       abort ();
     }
+  if (num <= 0) 
+    {
+      /* Zero is used as an end marker in the file.  */
+      as_bad (_("Line numbers must be positive integers\n"));
+      return;
+    }
   new_line->next = line_nos;
   new_line->frag = frag;
   new_line->l.line_number = num;
@@ -480,6 +504,84 @@ obj_coff_ln (appline)
   demand_empty_rest_of_line ();
 }
 
+/* .loc is essentially the same as .ln; parse it for assembler
+   compatibility.  */
+
+static void
+obj_coff_loc (ignore)
+     int ignore ATTRIBUTE_UNUSED;
+{
+  int lineno;
+
+  /* FIXME: Why do we need this check?  We need it for ECOFF, but why
+     do we need it for COFF?  */
+  if (now_seg != text_section)
+    {
+      as_warn (_(".loc outside of .text"));
+      demand_empty_rest_of_line ();
+      return;
+    }
+
+  if (def_symbol_in_progress != NULL)
+    {
+      as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
+      demand_empty_rest_of_line ();
+      return;
+    }
+
+  /* Skip the file number.  */
+  SKIP_WHITESPACE ();
+  get_absolute_expression ();
+  SKIP_WHITESPACE ();
+
+  lineno = get_absolute_expression ();
+
+#ifndef NO_LISTING
+  {
+    extern int listing;
+
+    if (listing)
+      {
+        lineno += coff_line_base - 1;
+       listing_source_line (lineno);
+      }
+  }
+#endif
+
+  demand_empty_rest_of_line ();
+
+  add_lineno (frag_now, frag_now_fix (), lineno);
+}
+
+/* Handle the .ident pseudo-op.  */
+
+static void
+obj_coff_ident (ignore)
+     int ignore ATTRIBUTE_UNUSED;
+{
+  segT current_seg = now_seg;
+  subsegT current_subseg = now_subseg;
+
+#ifdef TE_PE
+  {
+    segT sec;
+
+    /* We could put it in .comment, but that creates an extra section
+       that shouldn't be loaded into memory, which requires linker
+       changes...  For now, until proven otherwise, use .rdata.  */
+    sec = subseg_new (".rdata$zzz", 0);
+    bfd_set_section_flags (stdoutput, sec,
+                          ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
+                           & bfd_applicable_section_flags (stdoutput)));
+  }
+#else
+  subseg_new (".comment", 0);
+#endif
+
+  stringer (1);
+  subseg_set (current_seg, current_subseg);
+}
+
 /*
  *                     def()
  *
@@ -501,7 +603,7 @@ obj_coff_ln (appline)
 
 static void
 obj_coff_def (what)
-     int what;
+     int what ATTRIBUTE_UNUSED;
 {
   char name_end;               /* Char after the end of name */
   char *symbol_name;           /* Name of the debug symbol */
@@ -548,7 +650,7 @@ unsigned int dim_index;
 
 static void
 obj_coff_endef (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   symbolS *symbolP;
 
@@ -587,14 +689,30 @@ obj_coff_endef (ignore)
        S_SET_SEGMENT (def_symbol_in_progress, text_section);
 
        name = S_GET_NAME (def_symbol_in_progress);
-       if (name[1] == 'b' && name[2] == 'f')
-         {
-           if (! in_function ())
-             as_warn (_("`%s' symbol without preceding function"), name);
-/*         SA_SET_SYM_LNNO (def_symbol_in_progress, 12345);*/
-           /* Will need relocating */
-           SF_SET_PROCESS (def_symbol_in_progress);
-           clear_function ();
+       if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
+         {
+           switch (name[1])
+             {
+             case 'b':  
+               /* .bf */
+               if (! in_function ())
+                 as_warn (_("`%s' symbol without preceding function"), name);
+               /* Will need relocating.  */
+               SF_SET_PROCESS (def_symbol_in_progress);
+               clear_function ();
+               break;
+#ifdef TE_PE
+             case 'e':  
+               /* .ef */
+               /* The MS compilers output the actual endline, not the
+                  function-relative one... we want to match without
+                  changing the assembler input.  */
+               SA_SET_SYM_LNNO (def_symbol_in_progress, 
+                                (SA_GET_SYM_LNNO (def_symbol_in_progress)
+                                 + coff_line_base));
+               break;
+#endif
+             }
          }
       }
       break;
@@ -639,7 +757,10 @@ obj_coff_endef (ignore)
 
   /* Now that we have built a debug symbol, try to find if we should
      merge with an existing symbol or not.  If a symbol is C_EFCN or
-     SEG_ABSOLUTE or untagged SEG_DEBUG it never merges. */
+     absolute_section or untagged SEG_DEBUG it never merges.  We also
+     don't merge labels, which are in a different namespace, nor
+     symbols which have not yet been defined since they are typically
+     unique, nor do we merge tags with non-tags.  */
 
   /* Two cases for functions.  Either debug followed by definition or
      definition followed by debug.  For definition first, we will
@@ -654,16 +775,24 @@ obj_coff_endef (ignore)
      time. */
 
   if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
+      || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
       || (!strcmp (bfd_get_section_name (stdoutput,
                                         S_GET_SEGMENT (def_symbol_in_progress)),
                   "*DEBUG*")
          && !SF_GET_TAG (def_symbol_in_progress))
       || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
-      || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL)
+      || ! symbol_constant_p (def_symbol_in_progress)
+      || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
+                                      DO_NOT_STRIP)) == NULL
+      || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
     {
+      /* If it already is at the end of the symbol list, do nothing */
       if (def_symbol_in_progress != symbol_lastP)
-       symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
-                      &symbol_lastP);
+        {
+         symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
+         symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
+                        &symbol_lastP);
+        }
     }
   else
     {
@@ -728,7 +857,7 @@ obj_coff_endef (ignore)
 
 static void
 obj_coff_dim (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   int dim_index;
 
@@ -768,7 +897,7 @@ obj_coff_dim (ignore)
 
 static void
 obj_coff_line (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   int this_base;
 
@@ -784,7 +913,7 @@ obj_coff_line (ignore)
     coff_line_base = this_base;
 
   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
-  SA_SET_SYM_LNNO (def_symbol_in_progress, coff_line_base);
+  SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
 
   demand_empty_rest_of_line ();
 
@@ -794,14 +923,14 @@ obj_coff_line (ignore)
       extern int listing;
 
       if (listing)
-       listing_source_line ((unsigned int) coff_line_base);
+       listing_source_line ((unsigned int) this_base);
     }
 #endif
 }
 
 static void
 obj_coff_size (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (def_symbol_in_progress == NULL)
     {
@@ -817,7 +946,7 @@ obj_coff_size (ignore)
 
 static void
 obj_coff_scl (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (def_symbol_in_progress == NULL)
     {
@@ -832,7 +961,7 @@ obj_coff_scl (ignore)
 
 static void
 obj_coff_tag (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   char *symbol_name;
   char name_end;
@@ -869,7 +998,7 @@ obj_coff_tag (ignore)
 
 static void
 obj_coff_type (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (def_symbol_in_progress == NULL)
     {
@@ -891,7 +1020,7 @@ obj_coff_type (ignore)
 
 static void
 obj_coff_val (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (def_symbol_in_progress == NULL)
     {
@@ -928,8 +1057,15 @@ obj_coff_val (ignore)
             resolved, then copy the segment id from the forward
             symbol.  */
          SF_SET_GET_SEGMENT (def_symbol_in_progress);
+
+         /* FIXME: gcc can generate address expressions here in
+            unusual cases (search for "obscure" in sdbout.c).  We
+            just ignore the offset here, thus generating incorrect
+            debugging information.  We ignore the rest of the line
+            just below.  */
        }
-      /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
+      /* Otherwise, it is the name of a non debug symbol and its value
+         will be calculated later. */
       *input_line_pointer = name_end;
     }
   else
@@ -1037,8 +1173,7 @@ coff_frob_symbol (symp, punt)
              coff_last_function = symp;
              if (S_GET_NUMBER_AUXILIARY (symp) < 1)
                S_SET_NUMBER_AUXILIARY (symp, 1);
-             auxp =
-               &coffsymbol (symbol_get_bfdsym (symp))->native[1].u.auxent;
+             auxp = SYM_AUXENT (symp);
              memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
                      sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
            }
@@ -1064,6 +1199,11 @@ coff_frob_symbol (symp, punt)
       /* more ... */
     }
 
+  /* Double check weak symbols.  */
+  if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
+    as_bad (_("Symbol `%s' can not be both weak and common"),
+           S_GET_NAME (symp));
+
   if (SF_GET_TAG (symp))
     last_tagP = symp;
   else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
@@ -1138,9 +1278,9 @@ coff_frob_symbol (symp, punt)
 
 void
 coff_adjust_section_syms (abfd, sec, x)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      asection *sec;
-     PTR x;
+     PTR x ATTRIBUTE_UNUSED;
 {
   symbolS *secsym;
   segment_info_type *seginfo = seg_info (sec);
@@ -1174,6 +1314,8 @@ coff_adjust_section_syms (abfd, sec, x)
       && sec != bss_section)
     return;
   secsym = section_symbol (sec);
+  /* This is an estimate; we'll plug in the real value using
+     SET_SECTION_RELOCS later */
   SA_SET_SCN_NRELOC (secsym, nrelocs);
   SA_SET_SCN_NLINNO (secsym, nlnno);
 }
@@ -1197,13 +1339,14 @@ coff_frob_file_after_relocs ()
  *                                              'd' (apparently m88k for data)
  *                                               'x' for text
  *                                              'r' for read-only data
+ *                                              's' for shared data (PE)
  * But if the argument is not a quoted string, treat it as a
  * subsegment number.
  */
 
 void
 obj_coff_section (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   /* Strip out the section name */
   char *section_name;
@@ -1232,7 +1375,7 @@ obj_coff_section (ignore)
   SKIP_WHITESPACE ();
 
   exp = 0;
-  flags = SEC_NO_FLAGS;
+  flags = SEC_LOAD;
 
   if (*input_line_pointer == ',')
     {
@@ -1250,10 +1393,11 @@ obj_coff_section (ignore)
                {
                case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break;
                case 'n': flags &=~ SEC_LOAD; break;
-               case 'd':
-               case 'w': flags |= SEC_DATA; flags &=~ SEC_READONLY; break;
-               case 'x': flags |= SEC_CODE; break;
+               case 'd': flags |= SEC_DATA | SEC_LOAD; /* fall through */
+               case 'w': flags &=~ SEC_READONLY; break;
+               case 'x': flags |= SEC_CODE | SEC_LOAD; break;
                case 'r': flags |= SEC_READONLY; break;
+               case 's': flags |= SEC_SHARED; break;
 
                case 'i': /* STYP_INFO */
                case 'l': /* STYP_LIB */
@@ -1514,7 +1658,6 @@ static void adjust_stab_section PARAMS ((bfd *abfd, segT seg));
 static void obj_coff_lcomm PARAMS ((int));
 static void obj_coff_text PARAMS ((int));
 static void obj_coff_data PARAMS ((int));
-static void obj_coff_ident PARAMS ((int));
 void obj_coff_section PARAMS ((int));
 
 /* When not using BFD_ASSEMBLER, we permit up to 40 sections.
@@ -2607,12 +2750,11 @@ obj_coff_val (ignore)
             symbol.  */
          SF_SET_GET_SEGMENT (def_symbol_in_progress);
 
-         /* FIXME: gcc can generate address expressions
-            here in unusual cases (search for "obscure"
-            in sdbout.c).  We just ignore the offset
-            here, thus generating incorrect debugging
-            information.  We ignore the rest of the
-            line just below.  */
+         /* FIXME: gcc can generate address expressions here in
+            unusual cases (search for "obscure" in sdbout.c).  We
+            just ignore the offset here, thus generating incorrect
+            debugging information.  We ignore the rest of the line
+            just below.  */
        }
       /* Otherwise, it is the name of a non debug symbol and
         its value will be calculated later. */
@@ -4385,13 +4527,16 @@ adjust_stab_section(abfd, seg)
 
 #endif /* not BFD_ASSEMBLER */
 
-const pseudo_typeS obj_pseudo_table[] =
+const pseudo_typeS coff_pseudo_table[] =
 {
   {"def", obj_coff_def, 0},
   {"dim", obj_coff_dim, 0},
   {"endef", obj_coff_endef, 0},
   {"line", obj_coff_line, 0},
   {"ln", obj_coff_ln, 0},
+#ifdef BFD_ASSEMBLER
+  {"loc", obj_coff_loc, 0},
+#endif
   {"appline", obj_coff_ln, 1},
   {"scl", obj_coff_scl, 0},
   {"size", obj_coff_size, 0},
@@ -4407,15 +4552,14 @@ const pseudo_typeS obj_pseudo_table[] =
      earlier versions of gas.  */
   {"bss", obj_coff_bss, 0},
   {"weak", obj_coff_weak, 0},
+  {"ident", obj_coff_ident, 0},
 #ifndef BFD_ASSEMBLER
   {"use", obj_coff_section, 0},
   {"text", obj_coff_text, 0},
   {"data", obj_coff_data, 0},
   {"lcomm", obj_coff_lcomm, 0},
-  {"ident", obj_coff_ident, 0},
 #else
   {"optim", s_ignore, 0},      /* For sun386i cc (?) */
-  {"ident", s_ignore, 0},      /* we don't yet handle this. */
 #endif
   {"version", s_ignore, 0},
   {"ABORT", s_abort, 0},
@@ -4424,61 +4568,42 @@ const pseudo_typeS obj_pseudo_table[] =
   {"sdef", obj_coff_def, 0},
 #endif
   {NULL, NULL, 0}              /* end sentinel */
-};                             /* obj_pseudo_table */
+};                             /* coff_pseudo_table */
 \f
 #ifdef BFD_ASSEMBLER
 
 /* Support for a COFF emulation.  */
 
-static void
-coff_pop_insert ()
-{
-  pop_insert (obj_pseudo_table);
-}
-
-static int
-coff_sec_sym_ok_for_reloc (sec)
-     asection *sec;
-{
-  return 0;
-}
+static void coff_pop_insert PARAMS ((void));
 
 static void
-no_func ()
+coff_pop_insert ()
 {
-  abort ();
+  pop_insert (coff_pseudo_table);
 }
 
 const struct format_ops coff_format_ops =
 {
   bfd_target_coff_flavour,
-  0,
-  1,
+  0,   /* dfl_leading_underscore */
+  1,   /* emit_section_symbols */
   coff_frob_symbol,
-  no_func,
+  0,   /* frob_file */
   coff_frob_file_after_relocs,
-  0, 0,
-  0, 0,
-  0,
-#if 0
-  obj_generate_asm_lineno,
-#else
-  no_func,
-#endif
-#if 0
-  obj_stab,
-#else
-  no_func,
-#endif
-  coff_sec_sym_ok_for_reloc,
+  0,   /* s_get_size */
+  0,   /* s_set_size */
+  0,   /* s_get_align */
+  0,   /* s_set_align */
+  0,   /* s_get_other */
+  0,   /* s_get_desc */
+  0,   /* copy_symbol_attributes */
+  0,   /* generate_asm_lineno */
+  0,   /* process_stab */
+  0,   /* sec_sym_ok_for_reloc */
   coff_pop_insert,
-#if 0
-  obj_set_ext,
-#else
-  no_func,
-#endif
+  0,   /* ecoff_set_ext */
   coff_obj_read_begin_hook,
-  coff_obj_symbol_new_hook,
+  coff_obj_symbol_new_hook
 };
 
 #endif
This page took 0.032981 seconds and 4 git commands to generate.