Add XCOFF64 support.
[deliverable/binutils-gdb.git] / gas / config / obj-coff.c
index 394bc19f74bb229a7da735e0ad7affe318a190d1..11648b998d2af9db67e9d9e4065e29d039852edb 100644 (file)
@@ -1,5 +1,5 @@
 /* coff object file format
-   Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 1997
+   Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
    Free Software Foundation, Inc.
 
    This file is part of GAS.
 #define KEEP_RELOC_INFO
 #endif
 
+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
@@ -129,7 +146,7 @@ tag_insert (name, symbolP)
 
   if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
     {
-      as_fatal ("Inserting \"%s\" into structure table failed: %s",
+      as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
                name, error_string);
     }
 }
@@ -165,7 +182,59 @@ tag_find_or_make (name)
   return symbolP;
 }
 
+/* We accept the .bss directive to set the section for backward
+   compatibility with earlier versions of gas.  */
+
+static void
+obj_coff_bss (ignore)
+     int ignore ATTRIBUTE_UNUSED;
+{
+  if (*input_line_pointer == '\n')
+    subseg_new (".bss", get_absolute_expression ());
+  else
+    s_lcomm (0);
+}
+
+/* Handle .weak.  This is a GNU extension.  */
+
+static void
+obj_coff_weak (ignore)
+     int ignore ATTRIBUTE_UNUSED;
+{
+  char *name;
+  int c;
+  symbolS *symbolP;
+  do
+    {
+      name = input_line_pointer;
+      c = get_symbol_end ();
+      symbolP = symbol_find_or_make (name);
+      *input_line_pointer = c;
+      SKIP_WHITESPACE ();
+
+#ifdef BFD_ASSEMLER
+      S_SET_WEAK (symbolP);
+#endif
+
+#ifdef TE_PE
+      S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
+#else
+      S_SET_STORAGE_CLASS (symbolP, C_WEAKEXT);
+#endif
+
+      if (c == ',')
+       {
+         input_line_pointer++;
+         SKIP_WHITESPACE ();
+         if (*input_line_pointer == '\n')
+           c = '\n';
+       }
+    }
+  while (c == ',');
 
+  demand_empty_rest_of_line ();
+}
 
 #ifdef BFD_ASSEMBLER
 
@@ -196,8 +265,8 @@ SA_SET_SYM_ENDNDX (sym, val)
 {
   combined_entry_type *entry, *p;
 
-  entry = &coffsymbol (sym->bsym)->native[1];
-  p = coffsymbol (val->bsym)->native;
+  entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
+  p = coffsymbol (symbol_get_bfdsym (val))->native;
   entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
   entry->fix_end = 1;
 }
@@ -209,8 +278,8 @@ SA_SET_SYM_TAGNDX (sym, val)
 {
   combined_entry_type *entry, *p;
 
-  entry = &coffsymbol (sym->bsym)->native[1];
-  p = coffsymbol (val->bsym)->native;
+  entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
+  p = coffsymbol (symbol_get_bfdsym (val))->native;
   entry->u.auxent.x_sym.x_tagndx.p = p;
   entry->fix_tag = 1;
 }
@@ -219,7 +288,7 @@ static int
 S_GET_DATA_TYPE (sym)
      symbolS *sym;
 {
-  return coffsymbol (sym->bsym)->native->u.syment.n_type;
+  return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
 }
 
 int
@@ -227,7 +296,7 @@ S_SET_DATA_TYPE (sym, val)
      symbolS *sym;
      int val;
 {
-  coffsymbol (sym->bsym)->native->u.syment.n_type = val;
+  coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
   return val;
 }
 
@@ -235,7 +304,7 @@ int
 S_GET_STORAGE_CLASS (sym)
      symbolS *sym;
 {
-  return coffsymbol (sym->bsym)->native->u.syment.n_sclass;
+  return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
 }
 
 int
@@ -243,7 +312,7 @@ S_SET_STORAGE_CLASS (sym, val)
      symbolS *sym;
      int val;
 {
-  coffsymbol (sym->bsym)->native->u.syment.n_sclass = val;
+  coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
   return val;
 }
 
@@ -258,21 +327,17 @@ c_symbol_merge (debug, normal)
   S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
 
   if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
-    /* take the most we have */
-    S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
+    {
+      /* take the most we have */
+      S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
+    }
 
   if (S_GET_NUMBER_AUXILIARY (debug) > 0)
     {
       /* Move all the auxiliary information.  */
-      /* @@ How many fields do we want to preserve?  Would it make more
-        sense to pick and choose those we want to copy?  Should look
-        into this further....  [raeburn:19920512.2209EST]  */
-      alent *linenos;
-      linenos = coffsymbol (normal->bsym)->lineno;
-      memcpy ((char *) &coffsymbol (normal->bsym)->native,
-             (char *) &coffsymbol (debug->bsym)->native,
-             S_GET_NUMBER_AUXILIARY(debug) * AUXESZ);
-      coffsymbol (normal->bsym)->lineno = linenos;
+      memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
+             (S_GET_NUMBER_AUXILIARY (debug)
+              * sizeof (*SYM_AUXINFO (debug))));
     }
 
   /* Move the debug flags. */
@@ -285,12 +350,14 @@ 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);
   S_SET_NUMBER_AUXILIARY (symbolP, 1);
 
-  symbolP->bsym->flags = BSF_DEBUGGING;
+  symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
 
 #ifndef NO_LISTING
   {
@@ -332,21 +399,20 @@ void
 coff_obj_symbol_new_hook (symbolP)
      symbolS *symbolP;
 {
-  char underscore = 0;         /* Symbol has leading _ */
+  long   sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
+  char * s  = (char *) xmalloc (sz);
+  
+  memset (s, 0, sz);
+  coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
 
-  {
-    long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
-    char *s = (char *) xmalloc (sz);
-    memset (s, 0, sz);
-    coffsymbol (symbolP->bsym)->native = (combined_entry_type *) s;
-  }
   S_SET_DATA_TYPE (symbolP, T_NULL);
   S_SET_STORAGE_CLASS (symbolP, 0);
   S_SET_NUMBER_AUXILIARY (symbolP, 0);
 
   if (S_IS_STRING (symbolP))
     SF_SET_STRING (symbolP);
-  if (!underscore && S_IS_LOCAL (symbolP))
+  
+  if (S_IS_LOCAL (symbolP))
     SF_SET_LOCAL (symbolP);
 }
 
@@ -363,7 +429,7 @@ int coff_n_line_nos;
 static void
 add_lineno (frag, offset, num)
      fragS *frag;
-     int offset;
+     addressT offset;
      int num;
 {
   struct line_no *new_line =
@@ -372,6 +438,12 @@ add_lineno (frag, offset, num)
     {
       abort ();
     }
+  if (num <= 0) 
+    {
+      /* Zero is used as an end marker in the file.  */
+      as_warn (_("Line numbers must be positive integers\n"));
+      num = 1;
+    }
   new_line->next = line_nos;
   new_line->frag = frag;
   new_line->l.line_number = num;
@@ -386,7 +458,8 @@ coff_add_linesym (sym)
 {
   if (line_nos)
     {
-      coffsymbol (current_lineno_sym->bsym)->lineno = (alent *) line_nos;
+      coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
+       (alent *) line_nos;
       coff_n_line_nos++;
       line_nos = 0;
     }
@@ -401,7 +474,7 @@ obj_coff_ln (appline)
 
   if (! appline && def_symbol_in_progress != NULL)
     {
-      as_warn (".ln pseudo-op inside .def/.endef: ignored.");
+      as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }
@@ -431,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()
  *
@@ -452,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 */
@@ -461,7 +612,7 @@ obj_coff_def (what)
 
   if (def_symbol_in_progress != NULL)
     {
-      as_warn (".def pseudo-op used inside of .def/.endef: ignored.");
+      as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -484,7 +635,7 @@ obj_coff_def (what)
 
   /* Initialize the new symbol */
   def_symbol_in_progress = symbol_make (symbol_name_copy);
-  def_symbol_in_progress->sy_frag = &zero_address_frag;
+  symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
   S_SET_VALUE (def_symbol_in_progress, 0);
 
   if (S_IS_STRING (def_symbol_in_progress))
@@ -499,14 +650,15 @@ unsigned int dim_index;
 
 static void
 obj_coff_endef (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   symbolS *symbolP;
+
   /* DIM BUG FIX sac@cygnus.com */
   dim_index = 0;
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".endef pseudo-op used outside of .def/.endef: ignored.");
+      as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -536,15 +688,31 @@ obj_coff_endef (ignore)
        CONST char *name;
        S_SET_SEGMENT (def_symbol_in_progress, text_section);
 
-       name = bfd_asymbol_name (def_symbol_in_progress->bsym);
-       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 ();
+       name = S_GET_NAME (def_symbol_in_progress);
+       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;
@@ -569,22 +737,30 @@ obj_coff_endef (ignore)
       break;
 
     case C_EXT:
+    case C_WEAKEXT:
+#ifdef TE_PE
+    case C_NT_WEAK:
+#endif
     case C_STAT:
     case C_LABEL:
       /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
       break;
 
+    default:
     case C_USTATIC:
     case C_EXTDEF:
     case C_ULABEL:
-      as_warn ("unexpected storage class %d",
+      as_warn (_("unexpected storage class %d"),
               S_GET_STORAGE_CLASS (def_symbol_in_progress));
       break;
     }                          /* switch on storage class */
 
   /* 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
@@ -599,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
     {
@@ -673,13 +857,13 @@ obj_coff_endef (ignore)
 
 static void
 obj_coff_dim (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   int dim_index;
 
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".dim pseudo-op used outside of .def/.endef: ignored.");
+      as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -699,7 +883,7 @@ obj_coff_dim (ignore)
          break;
 
        default:
-         as_warn ("badly formed .dim directive ignored");
+         as_warn (_("badly formed .dim directive ignored"));
          /* intentional fallthrough */
        case '\n':
        case ';':
@@ -713,7 +897,7 @@ obj_coff_dim (ignore)
 
 static void
 obj_coff_line (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   int this_base;
 
@@ -729,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 ();
 
@@ -739,18 +923,18 @@ 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)
     {
-      as_warn (".size pseudo-op used outside of .def/.endef ignored.");
+      as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -762,11 +946,11 @@ obj_coff_size (ignore)
 
 static void
 obj_coff_scl (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".scl pseudo-op used outside of .def/.endef ignored.");
+      as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -777,14 +961,14 @@ obj_coff_scl (ignore)
 
 static void
 obj_coff_tag (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   char *symbol_name;
   char name_end;
 
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".tag pseudo-op used outside of .def/.endef ignored.");
+      as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
       demand_empty_rest_of_line ();
       return;
     }
@@ -803,7 +987,7 @@ obj_coff_tag (ignore)
                     tag_find_or_make (symbol_name));
   if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
     {
-      as_warn ("tag not found for .tag %s", symbol_name);
+      as_warn (_("tag not found for .tag %s"), symbol_name);
     }                          /* not defined */
 
   SF_SET_TAGGED (def_symbol_in_progress);
@@ -814,11 +998,11 @@ obj_coff_tag (ignore)
 
 static void
 obj_coff_type (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".type pseudo-op used outside of .def/.endef ignored.");
+      as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -836,11 +1020,11 @@ obj_coff_type (ignore)
 
 static void
 obj_coff_val (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".val pseudo-op used outside of .def/.endef ignored.");
+      as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -855,24 +1039,33 @@ obj_coff_val (ignore)
 #endif
       if (!strcmp (symbol_name, "."))
        {
-         def_symbol_in_progress->sy_frag = frag_now;
+         symbol_set_frag (def_symbol_in_progress, frag_now);
          S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
          /* If the .val is != from the .def (e.g. statics) */
        }
       else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
        {
-         def_symbol_in_progress->sy_value.X_op = O_symbol;
-         def_symbol_in_progress->sy_value.X_add_symbol =
-           symbol_find_or_make (symbol_name);
-         def_symbol_in_progress->sy_value.X_op_symbol = NULL;
-         def_symbol_in_progress->sy_value.X_add_number = 0;
+         expressionS exp;
+
+         exp.X_op = O_symbol;
+         exp.X_add_symbol = symbol_find_or_make (symbol_name);
+         exp.X_op_symbol = NULL;
+         exp.X_add_number = 0;
+         symbol_set_value_expression (def_symbol_in_progress, &exp);
 
          /* If the segment is undefined when the forward reference is
             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
@@ -920,7 +1113,18 @@ coff_frob_symbol (symp, punt)
   if (!block_stack)
     block_stack = stack_init (512, sizeof (symbolS*));
 
-  if (!S_IS_DEFINED (symp) && S_GET_STORAGE_CLASS (symp) != C_STAT)
+  if (S_IS_WEAK (symp))
+    {
+#ifdef TE_PE
+      S_SET_STORAGE_CLASS (symp, C_NT_WEAK);
+#else
+      S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
+#endif
+    }
+
+  if (!S_IS_DEFINED (symp)
+      && !S_IS_WEAK (symp)
+      && S_GET_STORAGE_CLASS (symp) != C_STAT)
     S_SET_STORAGE_CLASS (symp, C_EXT);
 
   if (!SF_GET_DEBUG (symp))
@@ -958,7 +1162,7 @@ coff_frob_symbol (symp, punt)
                  symbolS *begin;
                  begin = *(symbolS **) stack_pop (block_stack);
                  if (begin == 0)
-                   as_warn ("mismatched .eb");
+                   as_warn (_("mismatched .eb"));
                  else
                    next_set_end = begin;
                }
@@ -969,14 +1173,14 @@ coff_frob_symbol (symp, punt)
              coff_last_function = symp;
              if (S_GET_NUMBER_AUXILIARY (symp) < 1)
                S_SET_NUMBER_AUXILIARY (symp, 1);
-             auxp = &coffsymbol (symp->bsym)->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));
            }
          if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
            {
              if (coff_last_function == 0)
-               as_fatal ("C_EFCN symbol out of scope");
+               as_fatal (_("C_EFCN symbol out of scope"));
              SA_SET_SYM_FSIZE (coff_last_function,
                                (long) (S_GET_VALUE (symp)
                                        - S_GET_VALUE (coff_last_function)));
@@ -990,11 +1194,16 @@ coff_frob_symbol (symp, punt)
        *punt = 1;
 
       if (SF_GET_FUNCTION (symp))
-       symp->bsym->flags |= BSF_FUNCTION;
+       symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
 
       /* 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)
@@ -1003,17 +1212,17 @@ coff_frob_symbol (symp, punt)
 #ifdef OBJ_XCOFF
   /* This is pretty horrible, but we have to set *punt correctly in
      order to call SA_SET_SYM_ENDNDX correctly.  */
-  if (! symp->sy_used_in_reloc
-      && ((symp->bsym->flags & BSF_SECTION_SYM) != 0
+  if (! symbol_used_in_reloc_p (symp)
+      && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
          || (! S_IS_EXTERNAL (symp)
-             && ! symp->sy_tc.output
+             && ! symbol_get_tc (symp)->output
              && S_GET_STORAGE_CLASS (symp) != C_FILE)))
     *punt = 1;
 #endif
 
   if (set_end != (symbolS *) NULL
       && ! *punt
-      && ((symp->bsym->flags & BSF_NOT_AT_END) != 0
+      && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
          || (S_IS_DEFINED (symp)
              && ! S_IS_COMMON (symp)
              && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
@@ -1022,9 +1231,13 @@ coff_frob_symbol (symp, punt)
       set_end = NULL;
     }
 
-  if (next_set_end != NULL
-      && ! *punt)
-    set_end = next_set_end;
+  if (next_set_end != NULL)
+    {
+      if (set_end != NULL)
+       as_warn ("Warning: internal error: forgetting to set endndx of %s",
+                S_GET_NAME (set_end));
+      set_end = next_set_end;
+    }
 
   if (! *punt
       && S_GET_STORAGE_CLASS (symp) == C_FCN
@@ -1035,28 +1248,28 @@ coff_frob_symbol (symp, punt)
       coff_last_bf = symp;
     }
 
-  if (coffsymbol (symp->bsym)->lineno)
+  if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
     {
       int i;
       struct line_no *lptr;
       alent *l;
 
-      lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno;
+      lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
       for (i = 0; lptr; lptr = lptr->next)
        i++;
-      lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno;
+      lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
 
       /* We need i entries for line numbers, plus 1 for the first
         entry which BFD will override, plus 1 for the last zero
         entry (a marker for BFD).  */
       l = (alent *) xmalloc ((i + 2) * sizeof (alent));
-      coffsymbol (symp->bsym)->lineno = l;
+      coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
       l[i + 1].line_number = 0;
       l[i + 1].u.sym = NULL;
       for (; i > 0; i--)
        {
          if (lptr->frag)
-           lptr->l.u.offset += lptr->frag->fr_address;
+           lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
          l[i] = lptr->l;
          lptr = lptr->next;
        }
@@ -1065,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);
@@ -1088,8 +1301,9 @@ coff_adjust_section_syms (abfd, sec, x)
     fixS *fixp = seginfo->fix_root;
     while (fixp)
       {
+       if (! fixp->fx_done)
+         nrelocs++;
        fixp = fixp->fx_next;
-       nrelocs++;
       }
   }
   if (bfd_get_section_size_before_reloc (sec) == 0
@@ -1100,12 +1314,14 @@ 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);
 }
 
 void
-coff_frob_file ()
+coff_frob_file_after_relocs ()
 {
   bfd_map_over_sections (stdoutput, coff_adjust_section_syms, (char*) 0);
 }
@@ -1123,13 +1339,14 @@ coff_frob_file ()
  *                                              '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;
@@ -1158,7 +1375,7 @@ obj_coff_section (ignore)
   SKIP_WHITESPACE ();
 
   exp = 0;
-  flags = SEC_NO_FLAGS;
+  flags = SEC_LOAD;
 
   if (*input_line_pointer == ',')
     {
@@ -1176,20 +1393,21 @@ obj_coff_section (ignore)
                {
                case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break;
                case 'n': flags &=~ SEC_LOAD; break;
-               case 'd':
+               case 'd': flags |= SEC_DATA | SEC_LOAD; /* fall through */
                case 'w': flags &=~ SEC_READONLY; break;
-               case 'x': flags |= SEC_CODE; 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 */
                case 'o': /* STYP_OVER */
-                 as_warn ("unsupported section attribute '%c'",
+                 as_warn (_("unsupported section attribute '%c'"),
                           *input_line_pointer);
                  break;
 
                default:
-                 as_warn("unknown section attribute '%c'",
+                 as_warn(_("unknown section attribute '%c'"),
                          *input_line_pointer);
                  break;
                }
@@ -1204,8 +1422,14 @@ obj_coff_section (ignore)
 
   if (flags != SEC_NO_FLAGS)
     {
+      flagword oldflags;
+
+      oldflags = bfd_get_section_flags (stdoutput, sec);
+      oldflags &= SEC_LINK_ONCE | SEC_LINK_DUPLICATES;
+      flags |= oldflags;
+
       if (! bfd_set_section_flags (stdoutput, sec, flags))
-       as_warn ("error setting flags for \"%s\": %s",
+       as_warn (_("error setting flags for \"%s\": %s"),
                 bfd_section_name (stdoutput, sec),
                 bfd_errmsg (bfd_get_error ()));
     }
@@ -1229,25 +1453,32 @@ coff_frob_section (sec)
   char *p;
   fragS *fragp;
   bfd_vma size, n_entries, mask;
+  bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
 
   /* The COFF back end in BFD requires that all section sizes be
-     rounded up to multiples of the corresponding section alignments.
-     Seems kinda silly to me, but that's the way it is.  */
+     rounded up to multiples of the corresponding section alignments,
+     supposedly because standard COFF has no other way of encoding alignment
+     for sections.  If your COFF flavor has a different way of encoding
+     section alignment, then skip this step, as TICOFF does. */
   size = bfd_get_section_size_before_reloc (sec);
-  mask = ((bfd_vma) 1 << (bfd_vma) sec->alignment_power) - 1;
+  mask = ((bfd_vma) 1 << align_power) - 1;
+#if !defined(TICOFF)
   if (size & mask)
     {
       size = (size + mask) & ~mask;
       bfd_set_section_size (stdoutput, sec, size);
     }
+#endif
 
   /* If the section size is non-zero, the section symbol needs an aux
      entry associated with it, indicating the size.  We don't know
      all the values yet; coff_frob_symbol will fill them in later.  */
+#ifndef TICOFF
   if (size != 0
       || sec == text_section
       || sec == data_section
       || sec == bss_section)
+#endif
     {
       symbolS *secsym = section_symbol (sec);
 
@@ -1324,7 +1555,7 @@ symbol_dump ()
 
   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
     {
-      printf("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n",
+      printf(_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
             (unsigned long) symbolP,
             S_GET_NAME(symbolP),
             (long) S_GET_DATA_TYPE(symbolP),
@@ -1358,9 +1589,10 @@ symbol_dump ()
 #define S_SET_ZEROES(s,v)              ((s)->sy_symbol.ost_entry.n_zeroes = (v))
 
 #define MIN(a,b) ((a) < (b)? (a) : (b))
-/* This vector is used to turn an internal segment into a section #
-   suitable for insertion into a coff symbol table
- */
+
+/* This vector is used to turn a gas internal segment number into a
+   section number suitable for insertion into a coff symbol table.
+   This must correspond to seg_info_off_by_4.  */
 
 const short seg_N_TYPE[] =
 {                              /* in: segT   out: N_TYPE bits */
@@ -1433,54 +1665,43 @@ 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_bss PARAMS ((int));
-static void obj_coff_ident PARAMS ((int));
 void obj_coff_section PARAMS ((int));
 
-/* Section stuff
-
-   We allow more than just the standard 3 sections, infact, we allow
-   40 sections, (though the usual three have to be there).
+/* When not using BFD_ASSEMBLER, we permit up to 40 sections.
 
-   This structure performs the mappings for us:
-*/
-
-
-typedef struct
-{
-  segT seg_t;
-  int i;
-} seg_info_type;
+   This array maps a COFF section number into a gas section number.
+   Because COFF uses negative section numbers, you must add 4 to the
+   COFF section number when indexing into this array; this is done via
+   the SEG_INFO_FROM_SECTION_NUMBER macro.  This must correspond to
+   seg_N_TYPE.  */
 
-static const seg_info_type seg_info_off_by_4[] =
+static const segT seg_info_off_by_4[] =
 {
{SEG_PTV,  },
{SEG_NTV,  },
{SEG_DEBUG, },
{SEG_ABSOLUTE,  },
{SEG_UNKNOWN,  },
{SEG_E0}, {SEG_E1}, {SEG_E2}, {SEG_E3}, {SEG_E4},
{SEG_E5}, {SEG_E6}, {SEG_E7}, {SEG_E8}, {SEG_E9},
{SEG_E10},{SEG_E11},{SEG_E12},{SEG_E13},{SEG_E14},
{SEG_E15},{SEG_E16},{SEG_E17},{SEG_E18},{SEG_E19},
{SEG_E20},{SEG_E21},{SEG_E22},{SEG_E23},{SEG_E24},
{SEG_E25},{SEG_E26},{SEG_E27},{SEG_E28},{SEG_E29},
{SEG_E30},{SEG_E31},{SEG_E32},{SEG_E33},{SEG_E34},
{SEG_E35},{SEG_E36},{SEG_E37},{SEG_E38},{SEG_E39},
{(segT)40},
{(segT)41},
{(segT)42},
{(segT)43},
{(segT)44},
{(segT)45},
{(segT)0},
{(segT)0},
{(segT)0},
- {SEG_REGISTER}
SEG_PTV,
SEG_NTV,
SEG_DEBUG,
SEG_ABSOLUTE,
SEG_UNKNOWN,
SEG_E0,  SEG_E1,  SEG_E2,  SEG_E3,  SEG_E4,
SEG_E5,  SEG_E6,  SEG_E7,  SEG_E8,  SEG_E9,
SEG_E10, SEG_E11, SEG_E12, SEG_E13, SEG_E14,
SEG_E15, SEG_E16, SEG_E17, SEG_E18, SEG_E19,
SEG_E20, SEG_E21, SEG_E22, SEG_E23, SEG_E24,
SEG_E25, SEG_E26, SEG_E27, SEG_E28, SEG_E29,
SEG_E30, SEG_E31, SEG_E32, SEG_E33, SEG_E34,
SEG_E35, SEG_E36, SEG_E37, SEG_E38, SEG_E39,
(segT) 40,
(segT) 41,
(segT) 42,
(segT) 43,
(segT) 44,
(segT) 45,
(segT) 0,
(segT) 0,
(segT) 0,
+ SEG_REGISTER
 };
 
-
-
 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
 
 static relax_addressT
@@ -1501,14 +1722,14 @@ segT
 s_get_segment (x)
      symbolS * x;
 {
-  return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum).seg_t;
+  return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum);
 }
 
 /* calculate the size of the frag chain and fill in the section header
    to contain all of it, also fill in the addr of the sections */
 static unsigned int
 size_section (abfd, idx)
-     bfd * abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      unsigned int idx;
 {
 
@@ -1519,7 +1740,7 @@ size_section (abfd, idx)
       size = frag->fr_address;
       if (frag->fr_address != size)
        {
-         fprintf (stderr, "Out of step\n");
+         fprintf (stderr, _("Out of step\n"));
          size = frag->fr_address;
        }
 
@@ -1684,7 +1905,7 @@ do_relocs_for (abfd, h, file_cursor)
                      /* Turn the segment of the symbol into an offset.  */
                      if (symbol_ptr)
                        {
-                         resolve_symbol_value (symbol_ptr);
+                         resolve_symbol_value (symbol_ptr, 1);
                          if (! symbol_ptr->sy_resolved)
                            {
                              char *file;
@@ -1692,9 +1913,9 @@ do_relocs_for (abfd, h, file_cursor)
 
                              if (expr_symbol_where (symbol_ptr, &file, &line))
                                as_bad_where (file, line,
-                                             "unresolved relocation");
+                                             _("unresolved relocation"));
                              else
-                               as_bad ("bad relocation: symbol `%s' not in symbol table",
+                               as_bad (_("bad relocation: symbol `%s' not in symbol table"),
                                        S_GET_NAME (symbol_ptr));
                            }
                          dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
@@ -1772,7 +1993,7 @@ do_relocs_for (abfd, h, file_cursor)
 static void
 fill_section (abfd, h, file_cursor)
      bfd * abfd;
-     object_headers *h;
+     object_headers *h ATTRIBUTE_UNUSED;
      unsigned long *file_cursor;
 {
 
@@ -1954,7 +2175,7 @@ coff_header_append (abfd, h)
                                           &(segment_info[i].scnhdr),
                                           buffer);
          if (size == 0)
-           as_bad ("bfd_coff_swap_scnhdr_out failed");
+           as_bad (_("bfd_coff_swap_scnhdr_out failed"));
          bfd_write (buffer, size, 1, abfd);
        }
     }
@@ -2039,7 +2260,7 @@ obj_coff_ln (appline)
 
   if (! appline && def_symbol_in_progress != NULL)
     {
-      as_warn (".ln pseudo-op inside .def/.endef: ignored.");
+      as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* wrong context */
@@ -2087,7 +2308,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 */
@@ -2096,7 +2317,7 @@ obj_coff_def (what)
 
   if (def_symbol_in_progress != NULL)
     {
-      as_warn (".def pseudo-op used inside of .def/.endef: ignored.");
+      as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -2142,14 +2363,14 @@ unsigned int dim_index;
 
 static void
 obj_coff_endef (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   symbolS *symbolP = 0;
   /* DIM BUG FIX sac@cygnus.com */
   dim_index = 0;
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".endef pseudo-op used outside of .def/.endef: ignored.");
+      as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -2181,7 +2402,7 @@ obj_coff_endef (ignore)
        {                       /* .bf */
          if (function_lineoff < 0)
            {
-             fprintf (stderr, "`.bf' symbol without preceding function\n");
+             fprintf (stderr, _("`.bf' symbol without preceding function\n"));
            }                   /* missing function symbol */
          SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff;
 
@@ -2212,6 +2433,10 @@ obj_coff_endef (ignore)
       break;
 
     case C_EXT:
+    case C_WEAKEXT:
+#ifdef TE_PE
+    case C_NT_WEAK:
+#endif
     case C_STAT:
     case C_LABEL:
       /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
@@ -2220,7 +2445,7 @@ obj_coff_endef (ignore)
     case C_USTATIC:
     case C_EXTDEF:
     case C_ULABEL:
-      as_warn ("unexpected storage class %d", S_GET_STORAGE_CLASS (def_symbol_in_progress));
+      as_warn (_("unexpected storage class %d"), S_GET_STORAGE_CLASS (def_symbol_in_progress));
       break;
     }                          /* switch on storage class */
 
@@ -2321,13 +2546,13 @@ obj_coff_endef (ignore)
 
 static void
 obj_coff_dim (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   int dim_index;
 
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".dim pseudo-op used outside of .def/.endef: ignored.");
+      as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -2347,7 +2572,7 @@ obj_coff_dim (ignore)
          break;
 
        default:
-         as_warn ("badly formed .dim directive ignored");
+         as_warn (_("badly formed .dim directive ignored"));
          /* intentional fallthrough */
        case '\n':
        case ';':
@@ -2361,7 +2586,7 @@ obj_coff_dim (ignore)
 
 static void
 obj_coff_line (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   int this_base;
   const char *name;
@@ -2406,11 +2631,11 @@ obj_coff_line (ignore)
 
 static void
 obj_coff_size (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".size pseudo-op used outside of .def/.endef ignored.");
+      as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -2422,11 +2647,11 @@ obj_coff_size (ignore)
 
 static void
 obj_coff_scl (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".scl pseudo-op used outside of .def/.endef ignored.");
+      as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -2437,14 +2662,14 @@ obj_coff_scl (ignore)
 
 static void
 obj_coff_tag (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   char *symbol_name;
   char name_end;
 
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".tag pseudo-op used outside of .def/.endef ignored.");
+      as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
       demand_empty_rest_of_line ();
       return;
     }
@@ -2462,7 +2687,7 @@ obj_coff_tag (ignore)
                     (long) tag_find_or_make (symbol_name));
   if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
     {
-      as_warn ("tag not found for .tag %s", symbol_name);
+      as_warn (_("tag not found for .tag %s"), symbol_name);
     }                          /* not defined */
 
   SF_SET_TAGGED (def_symbol_in_progress);
@@ -2473,11 +2698,11 @@ obj_coff_tag (ignore)
 
 static void
 obj_coff_type (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".type pseudo-op used outside of .def/.endef ignored.");
+      as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -2495,11 +2720,11 @@ obj_coff_type (ignore)
 
 static void
 obj_coff_val (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (".val pseudo-op used outside of .def/.endef ignored.");
+      as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
       demand_empty_rest_of_line ();
       return;
     }                          /* if not inside .def/.endef */
@@ -2532,12 +2757,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. */
@@ -2617,8 +2841,12 @@ yank_symbols ()
     {
       if (symbolP->sy_mri_common)
        {
-         if (S_GET_STORAGE_CLASS (symbolP) == C_EXT)
-           as_bad ("%s: global symbols not supported in common sections",
+         if (S_GET_STORAGE_CLASS (symbolP) == C_EXT
+#ifdef TE_PE
+             || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
+#endif
+             || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT)
+           as_bad (_("%s: global symbols not supported in common sections"),
                    S_GET_NAME (symbolP));
          symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
          continue;
@@ -2660,7 +2888,7 @@ yank_symbols ()
              S_SET_SEGMENT (symbolP, SEG_E0);
            }                   /* push data into text */
 
-         resolve_symbol_value (symbolP);
+         resolve_symbol_value (symbolP, 1);
 
          if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
            {
@@ -2691,7 +2919,7 @@ yank_symbols ()
                      register symbolS *begin_symbolP;
                      begin_symbolP = *(symbolS **) stack_pop (block_stack);
                      if (begin_symbolP == (symbolS *) 0)
-                       as_warn ("mismatched .eb");
+                       as_warn (_("mismatched .eb"));
                      else
                        SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2);
                    }
@@ -2731,7 +2959,7 @@ yank_symbols ()
                  /* I don't even know if this is needed for sdb. But
                     the standard assembler generates it, so...  */
                  if (last_functionP == (symbolS *) 0)
-                   as_fatal ("C_EFCN symbol out of scope");
+                   as_fatal (_("C_EFCN symbol out of scope"));
                  SA_SET_SYM_FSIZE (last_functionP,
                                    (long) (S_GET_VALUE (symbolP) -
                                            S_GET_VALUE (last_functionP)));
@@ -2802,9 +3030,13 @@ yank_symbols ()
        }
       else if (!S_IS_DEFINED (symbolP)
               && !S_IS_DEBUG (symbolP)
-              && !SF_GET_STATICS (symbolP) &&
-              S_GET_STORAGE_CLASS (symbolP) == C_EXT)
-       {                       /* C_EXT && !SF_GET_FUNCTION(symbolP))  */
+              && !SF_GET_STATICS (symbolP)
+              && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
+#ifdef TE_PE
+                  || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
+#endif
+                  || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT))
+       {
          /* if external, Remove from the list */
          symbolS *hold = symbol_previous (symbolP);
 
@@ -2816,7 +3048,11 @@ yank_symbols ()
       else if (! S_IS_DEBUG (symbolP)
               && ! SF_GET_STATICS (symbolP)
               && ! SF_GET_FUNCTION (symbolP)
-              && S_GET_STORAGE_CLASS (symbolP) == C_EXT)
+              && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
+#ifdef TE_PE
+                  || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
+#endif
+                  || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK))
        {
          symbolS *hold = symbol_previous (symbolP);
 
@@ -2910,7 +3146,7 @@ tie_tags ()
 static void
 crawl_symbols (h, abfd)
      object_headers *h;
-     bfd * abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
 {
   unsigned int i;
 
@@ -3126,7 +3362,7 @@ write_object_file ()
 
   if (abfd == 0)
     {
-      as_perror ("FATAL: Can't create %s", out_file_name);
+      as_perror (_("FATAL: Can't create %s"), out_file_name);
       exit (EXIT_FAILURE);
     }
   bfd_set_format (abfd, bfd_object);
@@ -3144,6 +3380,7 @@ write_object_file ()
         at the next frag.  */
 
       subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
+
 #ifndef SUB_SEGMENT_ALIGN
 #define SUB_SEGMENT_ALIGN(SEG) 1
 #endif
@@ -3151,7 +3388,9 @@ write_object_file ()
       md_do_align (SUB_SEGMENT_ALIGN (now_seg), (char *) NULL, 0, 0,
                   alignment_done);
 #endif
-      frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE, 0);
+      frag_align (SUB_SEGMENT_ALIGN (now_seg),
+                 subseg_text_p (now_seg) ? NOP_OPCODE : 0,
+                 0);
 #ifdef md_do_align
     alignment_done:
 #endif
@@ -3204,7 +3443,11 @@ write_object_file ()
 
       /* I think the section alignment is only used on the i960; the
         i960 needs it, and it should do no harm on other targets.  */
+#ifdef ALIGNMENT_IN_S_FLAGS
+      segment_info[i].scnhdr.s_flags |= (section_alignment[i] & 0xF) << 8;
+#else
       segment_info[i].scnhdr.s_align = 1 << section_alignment[i];
+#endif
 
       if (i == SEG_E0)
        H_SET_TEXT_SIZE (&headers, size);
@@ -3296,7 +3539,7 @@ write_object_file ()
   /* Recent changes to write need this, but where it should
      go is up to Ken.. */
   if (bfd_close_all_done (abfd) == false)
-    as_fatal ("Can't close %s: %s", out_file_name,
+    as_fatal (_("Can't close %s: %s"), out_file_name,
              bfd_errmsg (bfd_get_error ()));
 #else
   {
@@ -3330,7 +3573,7 @@ obj_coff_add_segment (name)
 
   if (i == SEG_LAST)
     {
-      as_bad ("Too many new sections; can't add \"%s\"", name);
+      as_bad (_("Too many new sections; can't add \"%s\""), name);
       return now_seg;
     }
 
@@ -3362,7 +3605,7 @@ obj_coff_add_segment (name)
 
 void
 obj_coff_section (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   /* Strip out the section name */
   char *section_name, *name;
@@ -3422,7 +3665,7 @@ obj_coff_section (ignore)
                case 'x': flags |= STYP_TEXT;   break;
                case 'r': flags |= STYP_LIT;    break;
                default:
-                 as_warn("unknown section attribute '%c'",
+                 as_warn(_("unknown section attribute '%c'"),
                          *input_line_pointer);
                  break;
                }
@@ -3443,7 +3686,7 @@ obj_coff_section (ignore)
 
 static void
 obj_coff_text (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   subseg_new (".text", get_absolute_expression ());
 }
@@ -3451,7 +3694,7 @@ obj_coff_text (ignore)
 
 static void
 obj_coff_data (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (flag_readonly_data_in_text)
     subseg_new (".text", get_absolute_expression () + 1000);
@@ -3459,19 +3702,9 @@ obj_coff_data (ignore)
     subseg_new (".data", get_absolute_expression ());
 }
 
-static void
-obj_coff_bss (ignore)
-     int ignore;
-{
-  if (*input_line_pointer == '\n')     /* .bss                 */
-    subseg_new(".bss", get_absolute_expression());
-  else                                 /* .bss id,expr         */
-    obj_coff_lcomm(0);
-}
-
 static void
 obj_coff_ident (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   segT current_seg = now_seg;          /* save current seg     */
   subsegT current_subseg = now_subseg;
@@ -3617,9 +3850,15 @@ c_section_symbol (name, idx)
 {
   symbolS *symbolP;
 
-  symbolP = symbol_new (name, idx,
-                       0,
-                       &zero_address_frag);
+  symbolP = symbol_find_base (name, DO_NOT_STRIP);
+  if (symbolP == NULL)
+    symbolP = symbol_new (name, idx, 0, &zero_address_frag);
+  else
+    {
+      /* Mmmm.  I just love violating interfaces.  Makes me feel...dirty.  */
+      S_SET_SEGMENT (symbolP, idx);
+      symbolP->sy_frag = &zero_address_frag;
+    }
 
   S_SET_STORAGE_CLASS (symbolP, C_STAT);
   S_SET_NUMBER_AUXILIARY (symbolP, 1);
@@ -3724,7 +3963,7 @@ w_symbols (abfd, where, symbol_rootP)
 
 static void
 obj_coff_lcomm (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   s_lcomm(0);
   return;
@@ -3744,19 +3983,19 @@ obj_coff_lcomm (ignore)
   SKIP_WHITESPACE ();
   if (*input_line_pointer != ',')
     {
-      as_bad ("Expected comma after name");
+      as_bad (_("Expected comma after name"));
       ignore_rest_of_line ();
       return;
     }
   if (*input_line_pointer == '\n')
     {
-      as_bad ("Missing size expression");
+      as_bad (_("Missing size expression"));
       return;
     }
   input_line_pointer++;
   if ((temp = get_absolute_expression ()) < 0)
     {
-      as_warn ("lcomm length (%d.) <0! Ignored.", temp);
+      as_warn (_("lcomm length (%d.) <0! Ignored."), temp);
       ignore_rest_of_line ();
       return;
     }
@@ -3784,7 +4023,7 @@ obj_coff_lcomm (ignore)
        }
     }
   else
-    as_bad("Symbol %s already defined", name);
+    as_bad(_("Symbol %s already defined"), name);
 
   demand_empty_rest_of_line();
 #endif
@@ -3878,7 +4117,7 @@ fixup_segment (segP, this_segment_type)
          if (!SF_GET_BALNAME (tc_get_bal_of_call (add_symbolP)))
            {
              as_bad_where (fixP->fx_file, fixP->fx_line,
-                           "No 'bal' entry point for leafproc %s",
+                           _("No 'bal' entry point for leafproc %s"),
                            S_GET_NAME (add_symbolP));
              continue;
            }
@@ -3889,7 +4128,7 @@ fixup_segment (segP, this_segment_type)
       /* Make sure the symbols have been resolved; this may not have
          happened if these are expression symbols.  */
       if (add_symbolP != NULL && ! add_symbolP->sy_resolved)
-       resolve_symbol_value (add_symbolP);
+       resolve_symbol_value (add_symbolP, 1);
 
       if (add_symbolP != NULL)
        {
@@ -3919,7 +4158,7 @@ fixup_segment (segP, this_segment_type)
        }
 
       if (sub_symbolP != NULL && ! sub_symbolP->sy_resolved)
-       resolve_symbol_value (sub_symbolP);
+       resolve_symbol_value (sub_symbolP, 1);
 
       if (add_symbolP != NULL
          && add_symbolP->sy_mri_common)
@@ -3957,7 +4196,7 @@ fixup_segment (segP, this_segment_type)
                {
 #ifndef TC_M68K
                  as_bad_where (fixP->fx_file, fixP->fx_line,
-                               "Negative of non-absolute symbol %s",
+                               _("Negative of non-absolute symbol %s"),
                                S_GET_NAME (sub_symbolP));
 #endif
                  add_number -= S_GET_VALUE (sub_symbolP);
@@ -3978,7 +4217,7 @@ fixup_segment (segP, this_segment_type)
              if (fixP->fx_tcbit)
                {
                  as_bad_where (fixP->fx_file, fixP->fx_line,
-                               "callj to difference of 2 symbols");
+                               _("callj to difference of 2 symbols"));
                }
 #endif /* TC_I960 */
              add_number += S_GET_VALUE (add_symbolP) -
@@ -4024,7 +4263,7 @@ fixup_segment (segP, this_segment_type)
              else
                {
                  as_bad_where (fixP->fx_file, fixP->fx_line,
-                               "Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld.",
+                               _("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld."),
                                segment_name (S_GET_SEGMENT (sub_symbolP)),
                                S_GET_NAME (sub_symbolP),
                                (long) (fragP->fr_address + where));
@@ -4114,7 +4353,7 @@ fixup_segment (segP, this_segment_type)
                       * relocation.
                       */
                      as_bad_where (fixP->fx_file, fixP->fx_line,
-                                   "can't use COBR format with external label");
+                                   _("can't use COBR format with external label"));
                      fixP->fx_addsy = NULL;
                      fixP->fx_done = 1;
                      continue;
@@ -4171,6 +4410,12 @@ fixup_segment (segP, this_segment_type)
 #endif
        }                       /* if pcrel */
 
+#ifdef MD_APPLY_FIX3
+      md_apply_fix3 (fixP, (valueT *) &add_number, this_segment_type);
+#else
+      md_apply_fix (fixP, add_number);
+#endif
+
       if (!fixP->fx_bit_fixP && ! fixP->fx_no_overflow)
        {
 #ifndef TC_M88K
@@ -4188,7 +4433,7 @@ fixup_segment (segP, this_segment_type)
                      || (add_number & 0x8000) == 0)))
            {
              as_bad_where (fixP->fx_file, fixP->fx_line,
-                           "Value of %ld too large for field of %d bytes at 0x%lx",
+                           _("Value of %ld too large for field of %d bytes at 0x%lx"),
                            (long) add_number, size,
                            (unsigned long) (fragP->fr_address + where));
            }
@@ -4202,18 +4447,11 @@ fixup_segment (segP, this_segment_type)
              && size == 2
              && add_number > 0x7fff)
            as_bad_where (fixP->fx_file, fixP->fx_line,
-                         "Signed .word overflow; switch may be too large; %ld at 0x%lx",
+                         _("Signed .word overflow; switch may be too large; %ld at 0x%lx"),
                          (long) add_number,
                          (unsigned long) (fragP->fr_address + where));
 #endif
        }                       /* not a bit fix */
-      /* Once this fix has been applied, we don't have to output
-        anything nothing more need be done.  */
-#ifdef MD_APPLY_FIX3
-      md_apply_fix3 (fixP, &add_number, this_segment_type);
-#else
-      md_apply_fix (fixP, add_number);
-#endif
     }                          /* For each fixS in this segment. */
 }                              /* fixup_segment() */
 
@@ -4296,13 +4534,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},
@@ -4314,16 +4555,18 @@ const pseudo_typeS obj_pseudo_table[] =
   /* FIXME: We ignore the MRI short attribute.  */
   {"section.s", obj_coff_section, 0},
   {"sect.s", obj_coff_section, 0},
+  /* We accept the .bss directive for backward compatibility with
+     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},
-  {"bss", obj_coff_bss, 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},
@@ -4331,62 +4574,43 @@ const pseudo_typeS obj_pseudo_table[] =
   /* The m88k uses sdef instead of def.  */
   {"sdef", obj_coff_def, 0},
 #endif
-  {NULL}                       /* end sentinel */
-};                             /* obj_pseudo_table */
+  {NULL, NULL, 0}              /* end sentinel */
+};                             /* 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,
-  coff_frob_file,
-  no_func,
-  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,   /* frob_file */
+  coff_frob_file_after_relocs,
+  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.048321 seconds and 4 git commands to generate.