* m10300-opc.c, m10300-dis.c: Add am33 support.
[deliverable/binutils-gdb.git] / gas / read.c
index bdd88644d3dffdc5180ec5198324f667d1a36081..b64203b5959a037fa919640e15799ba61ad07ead 100644 (file)
@@ -1,5 +1,5 @@
 /* read.c - read a source file -
-   Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 1997
+   Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
    Free Software Foundation, Inc.
 
 This file is part of GAS, the GNU Assembler.
@@ -89,6 +89,10 @@ die horribly;
 #define LEX_QM 0
 #endif
 
+#ifndef LEX_HASH
+#define LEX_HASH 0
+#endif
+
 #ifndef LEX_DOLLAR
 /* The a29k assembler does not permits labels to start with $.  */
 #define LEX_DOLLAR 3
@@ -104,19 +108,20 @@ char lex_type[256] =
 {
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* @ABCDEFGHIJKLMNO */
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* PQRSTUVWXYZ[\]^_ */
-  0, 0, 0, 0, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
+  0, 0, 0, LEX_HASH, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */
   LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */
   0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,      /* `abcdefghijklmno */
   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, LEX_TILDE, 0, /* pqrstuvwxyz{|}~. */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
 };
 
 
@@ -124,33 +129,33 @@ char lex_type[256] =
  * In: a character.
  * Out: 1 if this character ends a line.
  */
-#define _ (0)
+#define Z_ (0)
 char is_end_of_line[256] =
 {
 #ifdef CR_EOL
-  99, _, _, _, _, _, _, _, _, _, 99, _, _, 99, _, _,   /* @abcdefghijklmno */
+  99, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, 99, Z_, Z_, 99, Z_, Z_,      /* @abcdefghijklmno */
 #else
-  99, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, _,    /* @abcdefghijklmno */
+  99, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, 99, Z_, Z_, Z_, Z_, Z_,      /* @abcdefghijklmno */
 #endif
-  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,      /* */
 #ifdef TC_HPPA
-  _,99, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* _!"#$%&'()*+,-./ */
-  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* 0123456789:;<=>? */
+  Z_,99, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,       /* _!"#$%&'()*+,-./ */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,      /* 0123456789:;<=>? */
 #else
-  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* */
-  _, _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _,     /* 0123456789:;<=>? */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,      /* */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, 99, Z_, Z_, Z_, Z_,      /* 0123456789:;<=>? */
 #endif
-  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* */
-  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* */
-  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* */
-  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* */
-  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* */
-  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* */
-  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* */
-  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* */
-  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,      /* */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,      /* */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,      /* */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,      /* */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,      /* */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,      /* */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,      /* */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,      /* */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,      /* */
+  Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_,      /* */
 };
-#undef _
+#undef Z_
 
 /* Functions private to this file. */
 
@@ -165,12 +170,12 @@ static char *old_buffer;  /* JF a hack */
 static char *old_input;
 static char *old_limit;
 
-/* Variables for handling include file directory list. */
+/* Variables for handling include file directory table. */
 
-char **include_dirs;   /* List of pointers to directories to
+char **include_dirs;   /* Table of pointers to directories to
                           search for .include's */
-int include_dir_count; /* How many are in the list */
-int include_dir_maxlen = 1;/* Length of longest in list */
+int include_dir_count; /* How many are in the table */
+int include_dir_maxlen = 1;/* Length of longest in table */
 
 #ifndef WORKING_DOT_WORD
 struct broken_word *broken_words;
@@ -197,17 +202,35 @@ symbolS *mri_common_symbol;
    may be needed.  */
 static int mri_pending_align;
 
+#ifndef NO_LISTING
+#ifdef OBJ_ELF
+/* This variable is set to be non-zero if the next string we see might
+   be the name of the source file in DWARF debugging information.  See
+   the comment in emit_expr for the format we look for.  */
+static int dwarf_file_string;
+#endif
+#endif
+
 static void cons_worker PARAMS ((int, int));
-static int scrub_from_string PARAMS ((char **));
+static int scrub_from_string PARAMS ((char *, int));
 static void do_align PARAMS ((int, char *, int, int));
 static void s_align PARAMS ((int, int));
+static void s_lcomm_internal PARAMS ((int, int));
 static int hex_float PARAMS ((int, char *));
+static inline int sizeof_sleb128 PARAMS ((offsetT));
+static inline int sizeof_uleb128 PARAMS ((valueT));
+static inline int output_sleb128 PARAMS ((char *, offsetT));
+static inline int output_uleb128 PARAMS ((char *, valueT));
+static inline int output_big_sleb128 PARAMS ((char *, LITTLENUM_TYPE *, int));
+static inline int output_big_uleb128 PARAMS ((char *, LITTLENUM_TYPE *, int));
+static int output_big_leb128 PARAMS ((char *, LITTLENUM_TYPE *, int, int));
 static void do_org PARAMS ((segT, expressionS *, int));
 char *demand_copy_string PARAMS ((int *lenP));
 static segT get_segmented_expression PARAMS ((expressionS *expP));
 static segT get_known_segmented_expression PARAMS ((expressionS * expP));
 static void pobegin PARAMS ((void));
 static int get_line_sb PARAMS ((sb *));
+static void generate_file_debug PARAMS ((void));
 \f
 
 void
@@ -285,6 +308,7 @@ static const pseudo_typeS potable[] =
   {"elsec", s_else, 0},
   {"end", s_end, 0},
   {"endc", s_endif, 0},
+  {"endfunc", s_func, 1},
   {"endif", s_endif, 0},
 /* endef */
   {"equ", s_set, 0},
@@ -300,6 +324,7 @@ static const pseudo_typeS potable[] =
   {"fill", s_fill, 0},
   {"float", float_cons, 'f'},
   {"format", s_ignore, 0},
+  {"func", s_func, 0},
   {"global", s_globl, 0},
   {"globl", s_globl, 0},
   {"hword", cons, 2},
@@ -394,7 +419,7 @@ static const pseudo_typeS potable[] =
   {"xstabs", s_xstab, 's'},
   {"word", cons, 2},
   {"zero", s_space, 0},
-  {NULL                      /* end sentinel */
+  {NULL, NULL, 0}                      /* end sentinel */
 };
 
 static int pop_override_ok = 0;
@@ -410,7 +435,7 @@ pop_insert (table)
     {
       errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
       if (errtxt && (!pop_override_ok || strcmp (errtxt, "exists")))
-       as_fatal ("error constructing %s pseudo-op table: %s", pop_table_name,
+       as_fatal (_("error constructing %s pseudo-op table: %s"), pop_table_name,
                  errtxt);
     }
 }
@@ -459,15 +484,18 @@ static char *scrub_string;
 static char *scrub_string_end;
 
 static int
-scrub_from_string (from)
-     char **from;
+scrub_from_string (buf, buflen)
+     char *buf;
+     int buflen;
 {
-  int size;
-
-  *from = scrub_string;
-  size = scrub_string_end - scrub_string;
-  scrub_string = scrub_string_end;
-  return size;
+  int copy;
+
+  copy = scrub_string_end - scrub_string;
+  if (copy > buflen)
+    copy = buflen;
+  memcpy (buf, scrub_string, copy);
+  scrub_string += copy;
+  return copy;
 }
 
 /*     read_a_source_file()
@@ -490,6 +518,11 @@ read_a_source_file (name)
   listing_newline (NULL);
   register_dependency (name);
 
+  /* Generate debugging information before we've read anything in to denote
+     this file as the "main" source file and not a subordinate one
+     (e.g. N_SO vs N_SOL in stabs).  */
+  generate_file_debug ();
+
   while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
     {                          /* We have another line to parse. */
       know (buffer_limit[-1] == '\n'); /* Must have a sentinel. */
@@ -703,7 +736,7 @@ read_a_source_file (name)
                    char *s2 = s;
                    while (*s2)
                      {
-                       if (isupper (*s2))
+                       if (isupper ((unsigned char) *s2))
                          *s2 = tolower (*s2);
                        s2++;
                      }
@@ -762,7 +795,7 @@ read_a_source_file (name)
                          mri_pending_align = 0;
                          if (line_label != NULL)
                            {
-                             line_label->sy_frag = frag_now;
+                             symbol_set_frag (line_label, frag_now);
                              S_SET_VALUE (line_label, frag_now_fix ());
                            }
                        }
@@ -770,7 +803,7 @@ read_a_source_file (name)
                      /* Print the error msg now, while we still can */
                      if (pop == NULL)
                        {
-                         as_bad ("Unknown pseudo-op:  `%s'", s);
+                         as_bad (_("Unknown pseudo-op:  `%s'"), s);
                          *input_line_pointer = c;
                          s_ignore (0);
                          continue;
@@ -797,6 +830,9 @@ read_a_source_file (name)
                  else
                    {
                      int inquote = 0;
+#ifdef QUOTES_IN_INSN
+                     int inescape = 0;
+#endif
 
                      /* WARNING: c has char, which may be end-of-line. */
                      /* Also: input_line_pointer->`\0` where c was. */
@@ -810,36 +846,21 @@ read_a_source_file (name)
                        {
                          if (flag_m68k_mri && *input_line_pointer == '\'')
                            inquote = ! inquote;
+#ifdef QUOTES_IN_INSN
+                         if (inescape)
+                           inescape = 0;
+                         else if (*input_line_pointer == '"')
+                           inquote = ! inquote;
+                         else if (*input_line_pointer == '\\')
+                           inescape = 1;
+#endif
                          input_line_pointer++;
                        }
 
                      c = *input_line_pointer;
                      *input_line_pointer = '\0';
 
-                     if (debug_type == DEBUG_STABS)
-                       stabs_generate_asm_lineno ();
-
-#ifdef OBJ_GENERATE_ASM_LINENO
-#ifdef ECOFF_DEBUGGING
-                     /* ECOFF assemblers automatically generate
-                         debugging information.  FIXME: This should
-                         probably be handled elsewhere.  */
-                     if (debug_type == DEBUG_NONE)
-                       {
-                         if (ecoff_no_current_file ())
-                           debug_type = DEBUG_ECOFF;
-                       }
-
-                     if (debug_type == DEBUG_ECOFF)
-                       {
-                         unsigned int lineno;
-                         char *s;
-
-                         as_where (&s, &lineno);
-                         OBJ_GENERATE_ASM_LINENO (s, lineno);
-                       }
-#endif
-#endif
+                     generate_lineno_debug ();
 
                      if (macro_defined)
                        {
@@ -866,7 +887,7 @@ read_a_source_file (name)
                          mri_pending_align = 0;
                          if (line_label != NULL)
                            {
-                             line_label->sy_frag = frag_now;
+                             symbol_set_frag (line_label, frag_now);
                              S_SET_VALUE (line_label, frag_now_fix ());
                            }
                        }
@@ -888,7 +909,7 @@ read_a_source_file (name)
            continue;
 
          if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB)
-             && isdigit (c))
+             && isdigit ((unsigned char) c))
            {
              /* local label  ("4:") */
              char *backup = input_line_pointer;
@@ -897,7 +918,7 @@ read_a_source_file (name)
 
              temp = c - '0';
 
-             while (isdigit (*input_line_pointer))
+             while (isdigit ((unsigned char) *input_line_pointer))
                {
                  temp = (temp * 10) + *input_line_pointer - '0';
                  ++input_line_pointer;
@@ -911,7 +932,7 @@ read_a_source_file (name)
 
                  if (dollar_label_defined (temp))
                    {
-                     as_fatal ("label \"%d$\" redefined", temp);
+                     as_fatal (_("label \"%d$\" redefined"), temp);
                    }
 
                  define_dollar_label (temp);
@@ -1126,9 +1147,9 @@ mri_comment_end (stop, stopc)
 
 void 
 s_abort (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
-  as_fatal (".abort detected.  Abandoning ship.");
+  as_fatal (_(".abort detected.  Abandoning ship."));
 }
 
 /* Guts of .align directive.  N is the power of two to which to align.
@@ -1152,21 +1173,7 @@ do_align (n, fill, len, max)
 
   if (fill == NULL)
     {
-      int maybe_text;
-
-#ifdef BFD_ASSEMBLER
-      if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
-       maybe_text = 1;
-      else
-       maybe_text = 0;
-#else
-      if (now_seg != data_section && now_seg != bss_section)
-       maybe_text = 1;
-      else
-       maybe_text = 0;
-#endif
-
-      if (maybe_text)
+      if (subseg_text_p (now_seg))
        default_fill = NOP_OPCODE;
       else
        default_fill = 0;
@@ -1233,7 +1240,7 @@ s_align (arg, bytes_p)
          for (i = 0; (align & 1) == 0; align >>= 1, ++i)
            ;
          if (align != 1)
-           as_bad ("Alignment not a power of 2");
+           as_bad (_("Alignment not a power of 2"));
          align = i;
        }
     }
@@ -1241,7 +1248,7 @@ s_align (arg, bytes_p)
   if (align > 15)
     {
       align = 15;
-      as_bad ("Alignment too large: %u assumed", align);
+      as_bad (_("Alignment too large: %u assumed"), align);
     }
 
   if (*input_line_pointer != ',')
@@ -1273,7 +1280,7 @@ s_align (arg, bytes_p)
   if (! fill_p)
     {
       if (arg < 0)
-       as_warn ("expected fill pattern missing");
+       as_warn (_("expected fill pattern missing"));
       do_align (align, (char *) NULL, 0, max);
     }
   else
@@ -1295,17 +1302,17 @@ s_align (arg, bytes_p)
        {
          char ab[16];
 
-         if (fill_len > sizeof ab)
+         if ((size_t) fill_len > sizeof ab)
            abort ();
          md_number_to_chars (ab, fill, fill_len);
          do_align (align, ab, fill_len, max);
        }
     }
 
+  demand_empty_rest_of_line ();
+
   if (flag_mri)
     mri_comment_end (stop, stopc);
-
-  demand_empty_rest_of_line ();
 }
 
 /* Handle the .align pseudo-op on machines where ".align 4" means
@@ -1330,7 +1337,7 @@ s_align_ptwo (arg)
 
 void 
 s_comm (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   register char *name;
   register char c;
@@ -1351,19 +1358,19 @@ s_comm (ignore)
   SKIP_WHITESPACE ();
   if (*input_line_pointer != ',')
     {
-      as_bad ("Expected comma after symbol-name: rest of line ignored.");
+      as_bad (_("Expected comma after symbol-name: rest of line ignored."));
+      ignore_rest_of_line ();
       if (flag_mri)
        mri_comment_end (stop, stopc);
-      ignore_rest_of_line ();
       return;
     }
   input_line_pointer++;                /* skip ',' */
   if ((temp = get_absolute_expression ()) < 0)
     {
-      as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp);
+      as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
+      ignore_rest_of_line ();
       if (flag_mri)
        mri_comment_end (stop, stopc);
-      ignore_rest_of_line ();
       return;
     }
   *p = 0;
@@ -1371,17 +1378,17 @@ s_comm (ignore)
   *p = c;
   if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
     {
-      as_bad ("Ignoring attempt to re-define symbol `%s'.",
+      as_bad (_("Ignoring attempt to re-define symbol `%s'."),
              S_GET_NAME (symbolP));
+      ignore_rest_of_line ();
       if (flag_mri)
        mri_comment_end (stop, stopc);
-      ignore_rest_of_line ();
       return;
     }
   if (S_GET_VALUE (symbolP))
     {
       if (S_GET_VALUE (symbolP) != (valueT) temp)
-       as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
+       as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
                S_GET_NAME (symbolP),
                (long) S_GET_VALUE (symbolP),
                (long) temp);
@@ -1400,10 +1407,10 @@ s_comm (ignore)
 #endif /* not OBJ_VMS */
   know (symbolP->sy_frag == &zero_address_frag);
 
+  demand_empty_rest_of_line ();
+
   if (flag_mri)
     mri_comment_end (stop, stopc);
-
-  demand_empty_rest_of_line ();
 }                              /* s_comm() */
 
 /* The MRI COMMON pseudo-op.  We handle this by creating a common
@@ -1412,7 +1419,7 @@ s_comm (ignore)
 
 void
 s_mri_common (small)
-     int small;
+     int small ATTRIBUTE_UNUSED;
 {
   char *name;
   char c;
@@ -1470,9 +1477,9 @@ s_mri_common (small)
 
   if (S_IS_DEFINED (sym) && ! S_IS_COMMON (sym))
     {
-      as_bad ("attempt to re-define symbol `%s'", S_GET_NAME (sym));
-      mri_comment_end (stop, stopc);
+      as_bad (_("attempt to re-define symbol `%s'"), S_GET_NAME (sym));
       ignore_rest_of_line ();
+      mri_comment_end (stop, stopc);
       return;
     }
 
@@ -1486,10 +1493,12 @@ s_mri_common (small)
 
   if (line_label != NULL)
     {
-      line_label->sy_value.X_op = O_symbol;
-      line_label->sy_value.X_add_symbol = sym;
-      line_label->sy_value.X_add_number = S_GET_VALUE (sym);
-      line_label->sy_frag = &zero_address_frag;
+      expressionS exp;
+      exp.X_op = O_symbol;
+      exp.X_add_symbol = sym;
+      exp.X_add_number = 0;
+      symbol_set_value_expression (line_label, &exp);
+      symbol_set_frag (line_label, &zero_address_frag);
       S_SET_SEGMENT (line_label, expr_section);
     }
 
@@ -1502,14 +1511,14 @@ s_mri_common (small)
   if (*input_line_pointer == ',')
     input_line_pointer += 2;
 
-  mri_comment_end (stop, stopc);
-
   demand_empty_rest_of_line ();
+
+  mri_comment_end (stop, stopc);
 }
 
 void
 s_data (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   segT section;
   register int temp;
@@ -1551,7 +1560,8 @@ s_app_file (appfile)
       /* If this is a fake .appfile, a fake newline was inserted into
         the buffer.  Passing -2 to new_logical_line tells it to
         account for it.  */
-      new_logical_line (s, appfile ? -2 : -1);
+      int may_omit
+       = (! new_logical_line (s, appfile ? -2 : -1) && appfile);
 
       /* In MRI mode, the preprocessor may have inserted an extraneous
          backquote.  */
@@ -1561,15 +1571,18 @@ s_app_file (appfile)
        ++input_line_pointer;
 
       demand_empty_rest_of_line ();
+      if (! may_omit)
+       {
 #ifdef LISTING
-      if (listing)
-       listing_source_file (s);
+         if (listing)
+           listing_source_file (s);
 #endif
-      register_dependency (s);
-    }
+         register_dependency (s);
 #ifdef obj_app_file
-  obj_app_file (s);
+         obj_app_file (s);
 #endif
+       }
+    }
 }
 
 /* Handle the .appline pseudo-op.  This is automatically generated by
@@ -1579,7 +1592,7 @@ s_app_file (appfile)
 
 void
 s_app_line (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   int l;
 
@@ -1588,7 +1601,7 @@ s_app_line (ignore)
   if (l < 0)
     /* Some of the back ends can't deal with non-positive line numbers.
        Besides, it's silly.  */
-    as_warn ("Line numbers must be positive; line number %d rejected.", l+1);
+    as_warn (_("Line numbers must be positive; line number %d rejected."), l+1);
   else
     {
       new_logical_line ((char *) NULL, l);
@@ -1605,7 +1618,7 @@ s_app_line (ignore)
 
 void
 s_end (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (flag_mri)
     {
@@ -1615,7 +1628,7 @@ s_end (ignore)
       if (! is_end_of_line[(unsigned char) *input_line_pointer]
          && *input_line_pointer != '*'
          && *input_line_pointer != '!')
-       as_warn ("start address not supported");
+       as_warn (_("start address not supported"));
     }
 }
 
@@ -1623,9 +1636,9 @@ s_end (ignore)
 
 void
 s_err (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
-  as_bad (".err encountered");
+  as_bad (_(".err encountered"));
   demand_empty_rest_of_line ();
 }
 
@@ -1633,7 +1646,7 @@ s_err (ignore)
 
 void
 s_fail (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   offsetT temp;
   char *stop = NULL;
@@ -1644,75 +1657,105 @@ s_fail (ignore)
 
   temp = get_absolute_expression ();
   if (temp >= 500)
-    as_warn (".fail %ld encountered", (long) temp);
+    as_warn (_(".fail %ld encountered"), (long) temp);
   else
-    as_bad (".fail %ld encountered", (long) temp);
+    as_bad (_(".fail %ld encountered"), (long) temp);
+
+  demand_empty_rest_of_line ();
 
   if (flag_mri)
     mri_comment_end (stop, stopc);
-
-  demand_empty_rest_of_line ();
 }
 
 void 
 s_fill (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
-  long temp_repeat = 0;
-  long temp_size = 1;
-  register long temp_fill = 0;
+  expressionS rep_exp;
+  long size = 1;
+  register long fill = 0;
   char *p;
 
 #ifdef md_flush_pending_output
   md_flush_pending_output ();
 #endif
 
-  temp_repeat = get_absolute_expression ();
+  get_known_segmented_expression (&rep_exp);
   if (*input_line_pointer == ',')
     {
       input_line_pointer++;
-      temp_size = get_absolute_expression ();
+      size = get_absolute_expression ();
       if (*input_line_pointer == ',')
        {
          input_line_pointer++;
-         temp_fill = get_absolute_expression ();
+         fill = get_absolute_expression ();
        }
     }
+
   /* This is to be compatible with BSD 4.2 AS, not for any rational reason.  */
 #define BSD_FILL_SIZE_CROCK_8 (8)
-  if (temp_size > BSD_FILL_SIZE_CROCK_8)
+  if (size > BSD_FILL_SIZE_CROCK_8)
     {
-      as_warn (".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8);
-      temp_size = BSD_FILL_SIZE_CROCK_8;
+      as_warn (_(".fill size clamped to %d."), BSD_FILL_SIZE_CROCK_8);
+      size = BSD_FILL_SIZE_CROCK_8;
     }
-  if (temp_size < 0)
+  if (size < 0)
     {
-      as_warn ("Size negative: .fill ignored.");
-      temp_size = 0;
+      as_warn (_("Size negative: .fill ignored."));
+      size = 0;
     }
-  else if (temp_repeat <= 0)
+  else if (rep_exp.X_op == O_constant && rep_exp.X_add_number <= 0)
     {
-      if (temp_repeat < 0)
-       as_warn ("Repeat < 0, .fill ignored");
-      temp_size = 0;
+      if (rep_exp.X_add_number < 0)
+       as_warn (_("Repeat < 0, .fill ignored"));
+      size = 0;
     }
 
-  if (temp_size && !need_pass_2)
+  if (size && !need_pass_2)
     {
-      p = frag_var (rs_fill, (int) temp_size, (int) temp_size,
-                   (relax_substateT) 0, (symbolS *) 0, (offsetT) temp_repeat,
-                   (char *) 0);
-      memset (p, 0, (unsigned int) temp_size);
+      if (rep_exp.X_op == O_constant)
+       {
+         p = frag_var (rs_fill, (int) size, (int) size,
+                       (relax_substateT) 0, (symbolS *) 0,
+                       (offsetT) rep_exp.X_add_number,
+                       (char *) 0);
+       }
+      else
+       {
+         /* We don't have a constant repeat count, so we can't use
+            rs_fill.  We can get the same results out of rs_space,
+            but its argument is in bytes, so we must multiply the
+            repeat count by size.  */
+
+         symbolS *rep_sym;
+         rep_sym = make_expr_symbol (&rep_exp);
+         if (size != 1)
+           {
+             expressionS size_exp;
+             size_exp.X_op = O_constant;
+             size_exp.X_add_number = size;
+
+             rep_exp.X_op = O_multiply;
+             rep_exp.X_add_symbol = rep_sym;
+             rep_exp.X_op_symbol = make_expr_symbol (&size_exp);
+             rep_exp.X_add_number = 0;
+             rep_sym = make_expr_symbol (&rep_exp);
+           }
+
+         p = frag_var (rs_space, (int) size, (int) size,
+                       (relax_substateT) 0, rep_sym, (offsetT) 0, (char *) 0);
+       }
+      memset (p, 0, (unsigned int) size);
       /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX
        * flavoured AS.  The following bizzare behaviour is to be
        * compatible with above.  I guess they tried to take up to 8
        * bytes from a 4-byte expression and they forgot to sign
        * extend. Un*x Sux. */
 #define BSD_FILL_SIZE_CROCK_4 (4)
-      md_number_to_chars (p, (valueT) temp_fill,
-                         (temp_size > BSD_FILL_SIZE_CROCK_4
+      md_number_to_chars (p, (valueT) fill,
+                         (size > BSD_FILL_SIZE_CROCK_4
                           ? BSD_FILL_SIZE_CROCK_4
-                          : (int) temp_size));
+                          : (int) size));
       /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
        * but emits no error message because it seems a legal thing to do.
        * It is a degenerate case of .fill but could be emitted by a compiler.
@@ -1723,7 +1766,7 @@ s_fill (ignore)
 
 void 
 s_globl (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   char *name;
   int c;
@@ -1739,9 +1782,11 @@ s_globl (ignore)
       name = input_line_pointer;
       c = get_symbol_end ();
       symbolP = symbol_find_or_make (name);
+      S_SET_EXTERNAL (symbolP);
+
       *input_line_pointer = c;
       SKIP_WHITESPACE ();
-      S_SET_EXTERNAL (symbolP);
+      c = *input_line_pointer;
       if (c == ',')
        {
          input_line_pointer++;
@@ -1752,10 +1797,10 @@ s_globl (ignore)
     }
   while (c == ',');
 
+  demand_empty_rest_of_line ();
+
   if (flag_mri)
     mri_comment_end (stop, stopc);
-
-  demand_empty_rest_of_line ();
 }
 
 /* Handle the MRI IRP and IRPC pseudo-ops.  */
@@ -1796,7 +1841,7 @@ s_irp (irpc)
 
 void
 s_linkonce (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   enum linkonce_type type;
 
@@ -1820,7 +1865,7 @@ s_linkonce (ignore)
       else if (strcasecmp (s, "same_contents") == 0)
        type = LINKONCE_SAME_CONTENTS;
       else
-       as_warn ("unrecognized .linkonce type `%s'", s);
+       as_warn (_("unrecognized .linkonce type `%s'"), s);
 
       *input_line_pointer = c;
     }
@@ -1833,7 +1878,7 @@ s_linkonce (ignore)
     flagword flags;
 
     if ((bfd_applicable_section_flags (stdoutput) & SEC_LINK_ONCE) == 0)
-      as_warn (".linkonce is not supported for this object file format");
+      as_warn (_(".linkonce is not supported for this object file format"));
 
     flags = bfd_get_section_flags (stdoutput, now_seg);
     flags |= SEC_LINK_ONCE;
@@ -1855,11 +1900,11 @@ s_linkonce (ignore)
        break;
       }
     if (! bfd_set_section_flags (stdoutput, now_seg, flags))
-      as_bad ("bfd_set_section_flags: %s",
+      as_bad (_("bfd_set_section_flags: %s"),
              bfd_errmsg (bfd_get_error ()));
   }
 #else /* ! defined (BFD_ASSEMBLER) */
-  as_warn (".linkonce is not supported for this object file format");
+  as_warn (_(".linkonce is not supported for this object file format"));
 #endif /* ! defined (BFD_ASSEMBLER) */
 #endif /* ! defined (obj_handle_link_once) */
 
@@ -1902,13 +1947,13 @@ s_lcomm_internal (needs_align, bytes_p)
 
   if (*input_line_pointer == '\n')
     {
-      as_bad ("Missing size expression");
+      as_bad (_("Missing size expression"));
       return;
     }
 
   if ((temp = get_absolute_expression ()) < 0)
     {
-      as_warn ("BSS length (%d.) <0! Ignored.", temp);
+      as_warn (_("BSS length (%d.) <0! Ignored."), temp);
       ignore_rest_of_line ();
       return;
     }
@@ -1924,7 +1969,7 @@ s_lcomm_internal (needs_align, bytes_p)
          seg_info (bss_seg)->bss = 1;
 #ifdef BFD_ASSEMBLER
          if (! bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC))
-           as_warn ("error setting flags for \".sbss\": %s",
+           as_warn (_("error setting flags for \".sbss\": %s"),
                     bfd_errmsg (bfd_get_error ()));
 #endif
        }
@@ -1956,7 +2001,7 @@ s_lcomm_internal (needs_align, bytes_p)
       SKIP_WHITESPACE ();
       if (*input_line_pointer != ',')
        {
-         as_bad ("Expected comma after size");
+         as_bad (_("Expected comma after size"));
          ignore_rest_of_line ();
          return;
        }
@@ -1964,7 +2009,7 @@ s_lcomm_internal (needs_align, bytes_p)
       SKIP_WHITESPACE ();
       if (*input_line_pointer == '\n')
        {
-         as_bad ("Missing alignment");
+         as_bad (_("Missing alignment"));
          return;
        }
       align = get_absolute_expression ();
@@ -1978,19 +2023,19 @@ s_lcomm_internal (needs_align, bytes_p)
              for (i = 0; (align & 1) == 0; align >>= 1, ++i)
                ;
              if (align != 1)
-               as_bad ("Alignment not a power of 2");
+               as_bad (_("Alignment not a power of 2"));
              align = i;
            }
        }
       if (align > max_alignment)
        {
          align = max_alignment;
-         as_warn ("Alignment too large: %d. assumed.", align);
+         as_warn (_("Alignment too large: %d. assumed."), align);
        }
       else if (align < 0)
        {
          align = 0;
-         as_warn ("Alignment negative. 0 assumed.");
+         as_warn (_("Alignment negative. 0 assumed."));
        }
       record_alignment (bss_seg, align);
     }                          /* if needs align */
@@ -2027,9 +2072,9 @@ s_lcomm_internal (needs_align, bytes_p)
        frag_align (align, 0, 0);
                                        /* detach from old frag */
       if (S_GET_SEGMENT (symbolP) == bss_seg)
-       symbolP->sy_frag->fr_symbol = NULL;
+       symbol_get_frag (symbolP)->fr_symbol = NULL;
 
-      symbolP->sy_frag = frag_now;
+      symbol_set_frag (symbolP, frag_now);
       pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
                        (offsetT) temp, (char *) 0);
       *pfrag = 0;
@@ -2051,7 +2096,7 @@ s_lcomm_internal (needs_align, bytes_p)
 #endif
     }
   else
-    as_bad ("Ignoring attempt to re-define symbol `%s'.",
+    as_bad (_("Ignoring attempt to re-define symbol `%s'."),
            S_GET_NAME (symbolP));
 
   subseg_set (current_seg, current_subseg);
@@ -2074,7 +2119,7 @@ void s_lcomm_bytes (needs_align)
 
 void 
 s_lsym (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   register char *name;
   register char c;
@@ -2091,7 +2136,7 @@ s_lsym (ignore)
   if (*input_line_pointer != ',')
     {
       *p = 0;
-      as_bad ("Expected comma after name \"%s\"", name);
+      as_bad (_("Expected comma after name \"%s\""), name);
       *p = c;
       ignore_rest_of_line ();
       return;
@@ -2101,7 +2146,7 @@ s_lsym (ignore)
   if (exp.X_op != O_constant
       && exp.X_op != O_register)
     {
-      as_bad ("bad expression");
+      as_bad (_("bad expression"));
       ignore_rest_of_line ();
       return;
     }
@@ -2128,7 +2173,7 @@ s_lsym (ignore)
     }
   else
     {
-      as_bad ("Symbol %s already defined", name);
+      as_bad (_("Symbol %s already defined"), name);
     }
   *p = c;
   demand_empty_rest_of_line ();
@@ -2181,7 +2226,8 @@ get_line_sb (line)
        }
       sb_add_char (line, *input_line_pointer++);
     }
-  while (input_line_pointer < buffer_limit && *input_line_pointer == '\n')
+  while (input_line_pointer < buffer_limit
+        && is_end_of_line[(unsigned char) *input_line_pointer])
     {
       if (input_line_pointer[-1] == '\n')
        bump_line_counters ();
@@ -2195,7 +2241,7 @@ get_line_sb (line)
 
 void
 s_macro (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   char *file;
   unsigned int line;
@@ -2223,7 +2269,7 @@ s_macro (ignore)
        {
          S_SET_SEGMENT (line_label, undefined_section);
          S_SET_VALUE (line_label, 0);
-         line_label->sy_frag = &zero_address_frag;
+         symbol_set_frag (line_label, &zero_address_frag);
        }
 
       if (((flag_m68k_mri
@@ -2235,7 +2281,7 @@ s_macro (ignore)
          || (! flag_m68k_mri
              && *name == '.'
              && hash_find (po_hash, name + 1) != NULL))
-       as_warn ("attempt to redefine pseudo-op `%s' ignored",
+       as_warn (_("attempt to redefine pseudo-op `%s' ignored"),
                 name);
     }
 
@@ -2247,7 +2293,7 @@ s_macro (ignore)
 
 void
 s_mexit (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   cond_exit_macro (macro_nest);
   buffer_limit = input_scrub_next_buffer (&input_line_pointer);
@@ -2257,7 +2303,7 @@ s_mexit (ignore)
 
 void
 s_mri (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   int on, old_flag;
 
@@ -2269,13 +2315,19 @@ s_mri (ignore)
 #ifdef TC_M68K
       flag_m68k_mri = 1;
 #endif
+      macro_mri_mode (1);
     }
   else
     {
       flag_mri = 0;
       flag_m68k_mri = 0;
+      macro_mri_mode (0);
     }
 
+  /* Operator precedence changes in m68k MRI mode, so we need to
+     update the operator rankings.  */
+  expr_set_precedence ();
+
 #ifdef MRI_MODE_CHANGE
   if (on != old_flag)
     MRI_MODE_CHANGE (on);
@@ -2293,16 +2345,16 @@ do_org (segment, exp, fill)
      int fill;
 {
   if (segment != now_seg && segment != absolute_section)
-    as_bad ("invalid segment \"%s\"; segment \"%s\" assumed",
+    as_bad (_("invalid segment \"%s\"; segment \"%s\" assumed"),
            segment_name (segment), segment_name (now_seg));
 
   if (now_seg == absolute_section)
     {
       if (fill != 0)
-       as_warn ("ignoring fill value in absolute section");
+       as_warn (_("ignoring fill value in absolute section"));
       if (exp->X_op != O_constant)
        {
-         as_bad ("only constant offsets supported in absolute section");
+         as_bad (_("only constant offsets supported in absolute section"));
          exp->X_add_number = 0;
        }
       abs_section_offset = exp->X_add_number;
@@ -2319,18 +2371,22 @@ do_org (segment, exp, fill)
 
 void 
 s_org (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   register segT segment;
   expressionS exp;
   register long temp_fill;
 
+#ifdef md_flush_pending_output
+  md_flush_pending_output ();
+#endif
+
   /* The m68k MRI assembler has a different meaning for .org.  It
      means to create an absolute section at a given address.  We can't
      support that--use a linker script instead.  */
   if (flag_m68k_mri)
     {
-      as_bad ("MRI style ORG pseudo-op not supported");
+      as_bad (_("MRI style ORG pseudo-op not supported"));
       ignore_rest_of_line ();
       return;
     }
@@ -2371,7 +2427,7 @@ s_org (ignore)
 
 void
 s_mri_sect (type)
-     char *type;
+     char *type ATTRIBUTE_UNUSED;
 {
 #ifdef TC_M68K
 
@@ -2418,7 +2474,7 @@ s_mri_sect (type)
       if (c == 'C' || c == 'D' || c == 'M' || c == 'R')
        *type = c;
       else
-       as_bad ("unrecognized section type");
+       as_bad (_("unrecognized section type"));
       ++input_line_pointer;
 
 #ifdef BFD_ASSEMBLER
@@ -2435,7 +2491,7 @@ s_mri_sect (type)
        if (flags != SEC_NO_FLAGS)
          {
            if (! bfd_set_section_flags (stdoutput, seg, flags))
-             as_warn ("error setting flags for \"%s\": %s",
+             as_warn (_("error setting flags for \"%s\": %s"),
                       bfd_section_name (stdoutput, seg),
                       bfd_errmsg (bfd_get_error ()));
          }
@@ -2486,7 +2542,7 @@ s_mri_sect (type)
       else if (strcasecmp (sectype, "romdata") == 0)
        *type = 'R';
       else
-       as_warn ("unrecognized section type `%s'", sectype);
+       as_warn (_("unrecognized section type `%s'"), sectype);
       *input_line_pointer = c;
     }
 
@@ -2500,7 +2556,7 @@ s_mri_sect (type)
       c = get_symbol_end ();
       if (strcasecmp (seccmd, "absolute") == 0)
        {
-         as_bad ("absolute sections are not supported");
+         as_bad (_("absolute sections are not supported"));
          *input_line_pointer = c;
          ignore_rest_of_line ();
          return;
@@ -2515,7 +2571,7 @@ s_mri_sect (type)
        }
       else
        {
-         as_warn ("unrecognized section command `%s'", seccmd);
+         as_warn (_("unrecognized section command `%s'"), seccmd);
          *input_line_pointer = c;
        }
     }
@@ -2525,7 +2581,8 @@ s_mri_sect (type)
 #else /* ! TC_I960 */
   /* The MRI assembler seems to use different forms of .sect for
      different targets.  */
-  abort ();
+  as_bad ("MRI mode not supported for this target");
+  ignore_rest_of_line ();
 #endif /* ! TC_I960 */
 #endif /* ! TC_M68K */
 }
@@ -2534,7 +2591,7 @@ s_mri_sect (type)
 
 void
 s_print (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   char *s;
   int len;
@@ -2548,7 +2605,7 @@ s_print (ignore)
 
 void
 s_purgem (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (is_it_end_of_statement ())
     {
@@ -2578,7 +2635,7 @@ s_purgem (ignore)
 
 void
 s_rept (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   int count;
   sb one;
@@ -2589,7 +2646,7 @@ s_rept (ignore)
   sb_new (&one);
   if (! buffer_and_nest ("REPT", "ENDR", &one, get_line_sb))
     {
-      as_bad ("rept without endr");
+      as_bad (_("rept without endr"));
       return;
     }
 
@@ -2631,7 +2688,7 @@ s_set (equiv)
   if (*input_line_pointer != ',')
     {
       *end_name = 0;
-      as_bad ("Expected comma after name \"%s\"", name);
+      as_bad (_("Expected comma after name \"%s\""), name);
       *end_name = delim;
       ignore_rest_of_line ();
       return;
@@ -2658,7 +2715,24 @@ s_set (equiv)
   if ((symbolP = symbol_find (name)) == NULL
       && (symbolP = md_undefined_symbol (name)) == NULL)
     {
-      symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
+#ifndef NO_LISTING
+      /* When doing symbol listings, play games with dummy fragments living
+        outside the normal fragment chain to record the file and line info
+         for this symbol.  */
+      if (listing & LISTING_SYMBOLS)
+       {
+         extern struct list_info_struct *listing_tail;
+         fragS *dummy_frag = (fragS *) xmalloc (sizeof(fragS));
+         memset (dummy_frag, 0, sizeof(fragS));
+         dummy_frag->fr_type = rs_fill;
+         dummy_frag->line = listing_tail;
+         symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
+         dummy_frag->fr_symbol = symbolP;
+       }
+      else
+#endif
+        symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
+                           
 #ifdef OBJ_COFF
       /* "set" symbols are local unless otherwise specified. */
       SF_SET_LOCAL (symbolP);
@@ -2673,7 +2747,7 @@ s_set (equiv)
   if (equiv
       && S_IS_DEFINED (symbolP)
       && S_GET_SEGMENT (symbolP) != reg_section)
-    as_bad ("symbol `%s' already defined", S_GET_NAME (symbolP));
+    as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
 
   pseudo_set (symbolP);
   demand_empty_rest_of_line ();
@@ -2717,9 +2791,12 @@ s_space (mult)
              S_SET_VALUE (mri_common_symbol, val + 1);
              if (line_label != NULL)
                {
-                 know (line_label->sy_value.X_op == O_symbol);
-                 know (line_label->sy_value.X_add_symbol == mri_common_symbol);
-                 line_label->sy_value.X_add_number += 1;
+                 expressionS *symexp;
+
+                 symexp = symbol_get_value_expression (line_label);
+                 know (symexp->X_op == O_symbol);
+                 know (symexp->X_add_symbol == mri_common_symbol);
+                 symexp->X_add_number += 1;
                }
            }
        }
@@ -2728,7 +2805,7 @@ s_space (mult)
          do_align (1, (char *) NULL, 0, 0);
          if (line_label != NULL)
            {
-             line_label->sy_frag = frag_now;
+             symbol_set_frag (line_label, frag_now);
              S_SET_VALUE (line_label, frag_now_fix ());
            }
        }
@@ -2756,7 +2833,7 @@ s_space (mult)
       || (mult != 0 && mult != 1 && val.X_add_number != 0))
     {
       if (exp.X_op != O_constant)
-       as_bad ("Unsupported variable size or fill value");
+       as_bad (_("Unsupported variable size or fill value"));
       else
        {
          offsetT i;
@@ -2780,9 +2857,10 @@ s_space (mult)
          bytes = repeat;
          if (repeat <= 0)
            {
-             if (! flag_mri || repeat < 0)
-               as_warn (".space repeat count is %s, ignored",
-                        repeat ? "negative" : "zero");
+             if (! flag_mri)
+               as_warn (_(".space repeat count is zero, ignored"));
+             else if (repeat < 0)
+               as_warn (_(".space repeat count is negative, ignored"));
              goto getout;
            }
 
@@ -2811,12 +2889,12 @@ s_space (mult)
        {
          if (now_seg == absolute_section)
            {
-             as_bad ("space allocation too complex in absolute section");
+             as_bad (_("space allocation too complex in absolute section"));
              subseg_set (text_section, 0);
            }
          if (mri_common_symbol != NULL)
            {
-             as_bad ("space allocation too complex in common section");
+             as_bad (_("space allocation too complex in common section"));
              mri_common_symbol = NULL;
            }
          if (!need_pass_2)
@@ -2836,10 +2914,10 @@ s_space (mult)
   if (flag_mri && (bytes & 1) != 0)
     mri_pending_align = 1;
 
+  demand_empty_rest_of_line ();
+
   if (flag_mri)
     mri_comment_end (stop, stopc);
-
-  demand_empty_rest_of_line ();
 }
 
 /* This is like s_space, but the value is a floating point number with
@@ -2864,10 +2942,10 @@ s_float_space (float_type)
   SKIP_WHITESPACE ();
   if (*input_line_pointer != ',')
     {
-      as_bad ("missing value");
+      as_bad (_("missing value"));
+      ignore_rest_of_line ();
       if (flag_mri)
        mri_comment_end (stop, stopc);
-      ignore_rest_of_line ();
       return;
     }
 
@@ -2877,7 +2955,8 @@ s_float_space (float_type)
 
   /* Skip any 0{letter} that may be present.  Don't even check if the
    * letter is legal.  */
-  if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
+  if (input_line_pointer[0] == '0'
+      && isalpha ((unsigned char) input_line_pointer[1]))
     input_line_pointer += 2;
 
   /* Accept :xxxx, where the x's are hex digits, for a floating point
@@ -2887,9 +2966,9 @@ s_float_space (float_type)
       flen = hex_float (float_type, temp);
       if (flen < 0)
        {
+         ignore_rest_of_line ();
          if (flag_mri)
            mri_comment_end (stop, stopc);
-         ignore_rest_of_line ();
          return;
        }
     }
@@ -2902,10 +2981,10 @@ s_float_space (float_type)
       know (flen > 0);
       if (err)
        {
-         as_bad ("Bad floating literal: %s", err);
+         as_bad (_("Bad floating literal: %s"), err);
+         ignore_rest_of_line ();
          if (flag_mri)
            mri_comment_end (stop, stopc);
-         ignore_rest_of_line ();
          return;
        }
     }
@@ -2918,17 +2997,17 @@ s_float_space (float_type)
       memcpy (p, temp, (unsigned int) flen);
     }
 
+  demand_empty_rest_of_line ();
+
   if (flag_mri)
     mri_comment_end (stop, stopc);
-
-  demand_empty_rest_of_line ();
 }
 
 /* Handle the .struct pseudo-op, as found in MIPS assemblers.  */
 
 void
 s_struct (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   char *stop = NULL;
   char stopc;
@@ -2937,14 +3016,14 @@ s_struct (ignore)
     stop = mri_comment_field (&stopc);
   abs_section_offset = get_absolute_expression ();
   subseg_set (absolute_section, 0);
+  demand_empty_rest_of_line ();
   if (flag_mri)
     mri_comment_end (stop, stopc);
-  demand_empty_rest_of_line ();
 }
 
 void
 s_text (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   register int temp;
 
@@ -2977,11 +3056,11 @@ ignore_rest_of_line ()          /* For suspect lines: gives warning. */
 {
   if (!is_end_of_line[(unsigned char) *input_line_pointer])
     {
-      if (isprint (*input_line_pointer))
-       as_bad ("Rest of line ignored. First ignored character is `%c'.",
+      if (isprint ((unsigned char) *input_line_pointer))
+       as_bad (_("Rest of line ignored. First ignored character is `%c'."),
                *input_line_pointer);
       else
-       as_bad ("Rest of line ignored. First ignored character valued 0x%x.",
+       as_bad (_("Rest of line ignored. First ignored character valued 0x%x."),
                *input_line_pointer);
       while (input_line_pointer < buffer_limit
             && !is_end_of_line[(unsigned char) *input_line_pointer])
@@ -2993,6 +3072,18 @@ ignore_rest_of_line ()           /* For suspect lines: gives warning. */
   know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
 }
 
+void
+discard_rest_of_line ()
+{
+  while (input_line_pointer < buffer_limit
+         && !is_end_of_line[(unsigned char) *input_line_pointer])
+    {
+      input_line_pointer++;
+    }
+  input_line_pointer++;         /* Return pointing just after end-of-line. */
+  know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
+}
+
 /*
  *                     pseudo_set()
  *
@@ -3020,17 +3111,22 @@ pseudo_set (symbolP)
   (void) expression (&exp);
 
   if (exp.X_op == O_illegal)
-    as_bad ("illegal expression; zero assumed");
+    as_bad (_("illegal expression; zero assumed"));
   else if (exp.X_op == O_absent)
-    as_bad ("missing expression; zero assumed");
+    as_bad (_("missing expression; zero assumed"));
   else if (exp.X_op == O_big)
-    as_bad ("%s number invalid; zero assumed",
-           exp.X_add_number > 0 ? "bignum" : "floating point");
+    {
+      if (exp.X_add_number > 0)
+       as_bad (_("bignum invalid; zero assumed"));
+      else
+       as_bad (_("floating point number invalid; zero assumed"));
+    }
   else if (exp.X_op == O_subtract
           && (S_GET_SEGMENT (exp.X_add_symbol)
               == S_GET_SEGMENT (exp.X_op_symbol))
           && SEG_NORMAL (S_GET_SEGMENT (exp.X_add_symbol))
-          && exp.X_add_symbol->sy_frag == exp.X_op_symbol->sy_frag)
+          && (symbol_get_frag (exp.X_add_symbol)
+              == symbol_get_frag (exp.X_op_symbol)))
     {
       exp.X_op = O_constant;
       exp.X_add_number = (S_GET_VALUE (exp.X_add_symbol)
@@ -3053,19 +3149,22 @@ pseudo_set (symbolP)
        S_CLEAR_EXTERNAL (symbolP);
 #endif /* OBJ_AOUT or OBJ_BOUT */
       S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
-      symbolP->sy_frag = &zero_address_frag;
+      if (exp.X_op != O_constant)
+        symbol_set_frag (symbolP, &zero_address_frag);
       break;
 
     case O_register:
       S_SET_SEGMENT (symbolP, reg_section);
       S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
-      symbolP->sy_frag = &zero_address_frag;
+      symbol_set_frag (symbolP, &zero_address_frag);
       break;
 
     case O_symbol:
       if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section
          || exp.X_add_number != 0)
-       symbolP->sy_value = exp;
+       symbol_set_value_expression (symbolP, &exp);
+      else if (symbol_section_p (symbolP))
+       as_bad ("invalid attempt to set value of section symbol");
       else
        {
          symbolS *s = exp.X_add_symbol;
@@ -3079,7 +3178,7 @@ pseudo_set (symbolP)
 #endif /* OBJ_AOUT or OBJ_BOUT */
          S_SET_VALUE (symbolP,
                       exp.X_add_number + S_GET_VALUE (s));
-         symbolP->sy_frag = s->sy_frag;
+         symbol_set_frag (symbolP, symbol_get_frag (s));
          copy_symbol_attributes (symbolP, s);
        }
       break;
@@ -3087,7 +3186,7 @@ pseudo_set (symbolP)
     default:
       /* The value is some complex expression.
         FIXME: Should we set the segment to anything?  */
-      symbolP->sy_value = exp;
+      symbol_set_value_expression (symbolP, &exp);
       break;
     }
 }
@@ -3160,9 +3259,9 @@ cons_worker (nbytes, rva)
 
   if (is_it_end_of_statement ())
     {
+      demand_empty_rest_of_line ();
       if (flag_mri)
        mri_comment_end (stop, stopc);
-      demand_empty_rest_of_line ();
       return;
     }
 
@@ -3183,7 +3282,7 @@ cons_worker (nbytes, rva)
          if (exp.X_op == O_symbol)
            exp.X_op = O_symbol_rva;
          else
-           as_fatal ("rva without symbol");
+           as_fatal (_("rva without symbol"));
        }
       emit_expr (&exp, (unsigned int) nbytes);
       ++c;
@@ -3198,10 +3297,10 @@ cons_worker (nbytes, rva)
 
   input_line_pointer--;                /* Put terminator back into stream. */
 
+  demand_empty_rest_of_line ();
+
   if (flag_mri)
     mri_comment_end (stop, stopc);
-
-  demand_empty_rest_of_line ();
 }
 
 
@@ -3219,7 +3318,6 @@ s_rva (size)
   cons_worker (size, 1);
 }
 
-
 /* Put the contents of expression EXP into the object file using
    NBYTES bytes.  If need_pass_2 is 1, this does nothing.  */
 
@@ -3236,13 +3334,80 @@ emit_expr (exp, nbytes)
   if (need_pass_2)
     return;
 
+#ifndef NO_LISTING
+#ifdef OBJ_ELF
+  /* When gcc emits DWARF 1 debugging pseudo-ops, a line number will
+     appear as a four byte positive constant in the .line section,
+     followed by a 2 byte 0xffff.  Look for that case here.  */
+  {
+    static int dwarf_line = -1;
+
+    if (strcmp (segment_name (now_seg), ".line") != 0)
+      dwarf_line = -1;
+    else if (dwarf_line >= 0
+            && nbytes == 2
+            && exp->X_op == O_constant
+            && (exp->X_add_number == -1 || exp->X_add_number == 0xffff))
+      listing_source_line ((unsigned int) dwarf_line);
+    else if (nbytes == 4
+            && exp->X_op == O_constant
+            && exp->X_add_number >= 0)
+      dwarf_line = exp->X_add_number;
+    else
+      dwarf_line = -1;
+  }
+
+  /* When gcc emits DWARF 1 debugging pseudo-ops, a file name will
+     appear as a 2 byte TAG_compile_unit (0x11) followed by a 2 byte
+     AT_sibling (0x12) followed by a four byte address of the sibling
+     followed by a 2 byte AT_name (0x38) followed by the name of the
+     file.  We look for that case here.  */
+  {
+    static int dwarf_file = 0;
+
+    if (strcmp (segment_name (now_seg), ".debug") != 0)
+      dwarf_file = 0;
+    else if (dwarf_file == 0
+            && nbytes == 2
+            && exp->X_op == O_constant
+            && exp->X_add_number == 0x11)
+      dwarf_file = 1;
+    else if (dwarf_file == 1
+            && nbytes == 2
+            && exp->X_op == O_constant
+            && exp->X_add_number == 0x12)
+      dwarf_file = 2;
+    else if (dwarf_file == 2
+            && nbytes == 4)
+      dwarf_file = 3;
+    else if (dwarf_file == 3
+            && nbytes == 2
+            && exp->X_op == O_constant
+            && exp->X_add_number == 0x38)
+      dwarf_file = 4;
+    else
+      dwarf_file = 0;
+
+    /* The variable dwarf_file_string tells stringer that the string
+       may be the name of the source file.  */
+    if (dwarf_file == 4)
+      dwarf_file_string = 1;
+    else
+      dwarf_file_string = 0;
+  }
+#endif
+#endif
+
+  if (check_eh_frame (exp, &nbytes))
+    return;
+
   op = exp->X_op;
 
   /* Allow `.word 0' in the absolute section.  */
   if (now_seg == absolute_section)
     {
       if (op != O_constant || exp->X_add_number != 0)
-       as_bad ("attempt to store value in absolute section");
+       as_bad (_("attempt to store value in absolute section"));
       abs_section_offset += nbytes;
       return;
     }
@@ -3250,13 +3415,13 @@ emit_expr (exp, nbytes)
   /* Handle a negative bignum.  */
   if (op == O_uminus
       && exp->X_add_number == 0
-      && exp->X_add_symbol->sy_value.X_op == O_big
-      && exp->X_add_symbol->sy_value.X_add_number > 0)
+      && symbol_get_value_expression (exp->X_add_symbol)->X_op == O_big
+      && symbol_get_value_expression (exp->X_add_symbol)->X_add_number > 0)
     {
       int i;
       unsigned long carry;
 
-      exp = &exp->X_add_symbol->sy_value;
+      exp = symbol_get_value_expression (exp->X_add_symbol);
 
       /* Negate the bignum: one's complement each digit and add 1.  */
       carry = 1;
@@ -3280,19 +3445,19 @@ emit_expr (exp, nbytes)
 
   if (op == O_absent || op == O_illegal)
     {
-      as_warn ("zero assumed for missing expression");
+      as_warn (_("zero assumed for missing expression"));
       exp->X_add_number = 0;
       op = O_constant;
     }
   else if (op == O_big && exp->X_add_number <= 0)
     {
-      as_bad ("floating point number invalid; zero assumed");
+      as_bad (_("floating point number invalid; zero assumed"));
       exp->X_add_number = 0;
       op = O_constant;
     }
   else if (op == O_register)
     {
-      as_warn ("register value used as expression");
+      as_warn (_("register value used as expression"));
       op = O_constant;
     }
 
@@ -3308,6 +3473,8 @@ emit_expr (exp, nbytes)
       x = (struct broken_word *) xmalloc (sizeof (struct broken_word));
       x->next_broken_word = broken_words;
       broken_words = x;
+      x->seg = now_seg;
+      x->subseg = now_subseg;
       x->frag = frag_now;
       x->word_goes_here = p;
       x->dispfrag = 0;
@@ -3380,7 +3547,7 @@ emit_expr (exp, nbytes)
          && ((get & mask) != mask
              || (get & hibit) == 0))
        {               /* Leading bits contain both 0s & 1s. */
-         as_warn ("Value 0x%lx truncated to 0x%lx.",
+         as_warn (_("Value 0x%lx truncated to 0x%lx."),
                   (unsigned long) get, (unsigned long) use);
        }
       /* put bytes in right order. */
@@ -3388,7 +3555,7 @@ emit_expr (exp, nbytes)
     }
   else if (op == O_big)
     {
-      int size;
+      unsigned int size;
       LITTLENUM_TYPE *nums;
 
       know (nbytes % CHARS_PER_LITTLENUM == 0);
@@ -3396,7 +3563,7 @@ emit_expr (exp, nbytes)
       size = exp->X_add_number * CHARS_PER_LITTLENUM;
       if (nbytes < size)
        {
-         as_warn ("Bignum truncated to %d bytes", nbytes);
+         as_warn (_("Bignum truncated to %d bytes"), nbytes);
          size = nbytes;
        }
 
@@ -3473,7 +3640,7 @@ emit_expr (exp, nbytes)
            r = BFD_RELOC_64;
            break;
          default:
-           as_bad ("unsupported BFD relocation size %u", nbytes);
+           as_bad (_("unsupported BFD relocation size %u"), nbytes);
            r = BFD_RELOC_32;
            break;
          }
@@ -3562,7 +3729,7 @@ parse_bitfield_cons (exp, nbytes)
 
          if (exp->X_op == O_absent)
            {
-             as_warn ("using a bit field width of zero");
+             as_warn (_("using a bit field width of zero"));
              exp->X_add_number = 0;
              exp->X_op = O_constant;
            }                   /* implied zero width bitfield */
@@ -3570,7 +3737,7 @@ parse_bitfield_cons (exp, nbytes)
          if (exp->X_op != O_constant)
            {
              *input_line_pointer = '\0';
-             as_bad ("field width \"%s\" too complex for a bitfield", hold);
+             as_bad (_("field width \"%s\" too complex for a bitfield"), hold);
              *input_line_pointer = ':';
              demand_empty_rest_of_line ();
              return;
@@ -3578,7 +3745,7 @@ parse_bitfield_cons (exp, nbytes)
 
          if ((width = exp->X_add_number) > (BITS_PER_CHAR * nbytes))
            {
-             as_warn ("field width %lu too big to fit in %d bytes: truncated to %d bits",
+             as_warn (_("field width %lu too big to fit in %d bytes: truncated to %d bits"),
                       width, nbytes, (BITS_PER_CHAR * nbytes));
              width = BITS_PER_CHAR * nbytes;
            }                   /* too big */
@@ -3599,7 +3766,7 @@ parse_bitfield_cons (exp, nbytes)
              char cache = *input_line_pointer;
 
              *input_line_pointer = '\0';
-             as_bad ("field value \"%s\" too complex for a bitfield", hold);
+             as_bad (_("field value \"%s\" too complex for a bitfield"), hold);
              *input_line_pointer = cache;
              demand_empty_rest_of_line ();
              return;
@@ -3641,7 +3808,7 @@ parse_mri_cons (exp, nbytes)
     TC_PARSE_CONS_EXPRESSION (exp, nbytes);
   else
     {
-      int scan = 0;
+      unsigned int scan;
       unsigned int result = 0;
 
       /* An MRI style string.  Cut into as many bytes as will fit into
@@ -3651,7 +3818,7 @@ parse_mri_cons (exp, nbytes)
        ++input_line_pointer;
       else if (*input_line_pointer == 'E')
        {
-         as_bad ("EBCDIC constants are not supported");
+         as_bad (_("EBCDIC constants are not supported"));
          ++input_line_pointer;
        }
 
@@ -3721,7 +3888,7 @@ parse_repeat_cons (exp, nbytes)
   if (count.X_op != O_constant
       || count.X_add_number <= 0)
     {
-      as_warn ("Unresolvable or nonpositive repeat count; using 1");
+      as_warn (_("Unresolvable or nonpositive repeat count; using 1"));
       return;
     }
 
@@ -3772,7 +3939,7 @@ hex_float (float_type, bytes)
       break;
 
     default:
-      as_bad ("Unknown floating type type '%c'", float_type);
+      as_bad (_("Unknown floating type type '%c'"), float_type);
       return -1;
     }
 
@@ -3794,7 +3961,7 @@ hex_float (float_type, bytes)
 
       if (i >= length)
        {
-         as_warn ("Floating point constant too large");
+         as_warn (_("Floating point constant too large"));
          return -1;
        }
       d = hex_value (*input_line_pointer) << 4;
@@ -3874,7 +4041,8 @@ float_cons (float_type)
        * has no use for such information. Lusers beware: you get
        * diagnostics if your input is ill-conditioned.
        */
-      if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
+      if (input_line_pointer[0] == '0'
+         && isalpha ((unsigned char) input_line_pointer[1]))
        input_line_pointer += 2;
 
       /* Accept :xxxx, where the x's are hex digits, for a floating
@@ -3896,7 +4064,7 @@ float_cons (float_type)
          know (length > 0);
          if (err)
            {
-             as_bad ("Bad floating literal: %s", err);
+             as_bad (_("Bad floating literal: %s"), err);
              ignore_rest_of_line ();
              return;
            }
@@ -3918,7 +4086,7 @@ float_cons (float_type)
              if (count_exp.X_op != O_constant
                  || count_exp.X_add_number <= 0)
                {
-                 as_warn ("unresolvable or nonpositive repeat count; using 1");
+                 as_warn (_("unresolvable or nonpositive repeat count; using 1"));
                }
              else
                count = count_exp.X_add_number;
@@ -3981,7 +4149,7 @@ sizeof_uleb128 (value)
   return size;
 }
 
-inline int
+int
 sizeof_leb128 (value, sign)
      valueT value;
      int sign;
@@ -4045,7 +4213,7 @@ output_uleb128 (p, value)
   return p - orig;
 }
 
-inline int
+int
 output_leb128 (p, value, sign)
      char *p;
      valueT value;
@@ -4061,14 +4229,14 @@ output_leb128 (p, value, sign)
    we don't output for NULL values of P.  It isn't really as critical as
    for "normal" values that this be streamlined.  */
 
-static int
+static inline int
 output_big_sleb128 (p, bignum, size)
      char *p;
      LITTLENUM_TYPE *bignum;
      int size;
 {
   char *orig = p;
-  valueT val;
+  valueT val = 0;
   int loaded = 0;
   unsigned byte;
 
@@ -4107,14 +4275,14 @@ output_big_sleb128 (p, bignum, size)
   return p - orig;
 }
 
-static int
+static inline int
 output_big_uleb128 (p, bignum, size)
      char *p;
      LITTLENUM_TYPE *bignum;
      int size;
 {
   char *orig = p;
-  valueT val;
+  valueT val = 0;
   int loaded = 0;
   unsigned byte;
 
@@ -4149,7 +4317,7 @@ output_big_uleb128 (p, bignum, size)
   return p - orig;
 }
 
-static inline int
+static int
 output_big_leb128 (p, bignum, size, sign)
      char *p;
      LITTLENUM_TYPE *bignum;
@@ -4173,19 +4341,19 @@ emit_leb128_expr(exp, sign)
 
   if (op == O_absent || op == O_illegal)
     {
-      as_warn ("zero assumed for missing expression");
+      as_warn (_("zero assumed for missing expression"));
       exp->X_add_number = 0;
       op = O_constant;
     }
   else if (op == O_big && exp->X_add_number <= 0)
     {
-      as_bad ("floating point number invalid; zero assumed");
+      as_bad (_("floating point number invalid; zero assumed"));
       exp->X_add_number = 0;
       op = O_constant;
     }
   else if (op == O_register)
     {
-      as_warn ("register value used as expression");
+      as_warn (_("register value used as expression"));
       op = O_constant;
     }
 
@@ -4242,7 +4410,7 @@ s_leb128 (sign)
 /*
  *                     stringer()
  *
- * We read 0 or more ',' seperated, double-quoted strings.
+ * We read 0 or more ',' separated, double-quoted strings.
  *
  * Caller should have checked need_pass_2 is FALSE because we don't check it.
  */
@@ -4254,6 +4422,7 @@ stringer (append_zero)            /* Worker to do .ascii etc statements. */
      register int append_zero; /* 0: don't append '\0', else 1 */
 {
   register unsigned int c;
+  char *start;
 
 #ifdef md_flush_pending_output
   md_flush_pending_output ();
@@ -4261,7 +4430,7 @@ stringer (append_zero)            /* Worker to do .ascii etc statements. */
 
   /*
    * The following awkward logic is to parse ZERO or more strings,
-   * comma seperated. Recall a string expression includes spaces
+   * comma separated. Recall a string expression includes spaces
    * before the opening '\"' and spaces after the closing '\"'.
    * We fake a leading ',' if there is (supposed to be)
    * a 1st, expression. We keep demanding expressions for each
@@ -4283,6 +4452,7 @@ stringer (append_zero)            /* Worker to do .ascii etc statements. */
        {
        case '\"':
          ++input_line_pointer; /*->1st char of string. */
+         start = input_line_pointer;
          while (is_a_char (c = next_char_of_string ()))
            {
              FRAG_APPEND_1_CHAR (c);
@@ -4292,6 +4462,27 @@ stringer (append_zero)           /* Worker to do .ascii etc statements. */
              FRAG_APPEND_1_CHAR (0);
            }
          know (input_line_pointer[-1] == '\"');
+
+#ifndef NO_LISTING
+#ifdef OBJ_ELF
+         /* In ELF, when gcc is emitting DWARF 1 debugging output, it
+             will emit .string with a filename in the .debug section
+             after a sequence of constants.  See the comment in
+             emit_expr for the sequence.  emit_expr will set
+             dwarf_file_string to non-zero if this string might be a
+             source file name.  */
+         if (strcmp (segment_name (now_seg), ".debug") != 0)
+           dwarf_file_string = 0;
+         else if (dwarf_file_string)
+           {
+             c = input_line_pointer[-1];
+             input_line_pointer[-1] = '\0';
+             listing_source_file (start);
+             input_line_pointer[-1] = c;
+           }
+#endif
+#endif
+
          break;
        case '<':
          input_line_pointer++;
@@ -4299,7 +4490,7 @@ stringer (append_zero)            /* Worker to do .ascii etc statements. */
          FRAG_APPEND_1_CHAR (c);
          if (*input_line_pointer != '>')
            {
-             as_bad ("Expected <nn>");
+             as_bad (_("Expected <nn>"));
            }
          input_line_pointer++;
          break;
@@ -4332,7 +4523,7 @@ next_char_of_string ()
       break;
 
     case '\n':
-      as_warn ("Unterminated string: Newline inserted.");
+      as_warn (_("Unterminated string: Newline inserted."));
       bump_line_counters ();
       break;
 
@@ -4415,7 +4606,7 @@ next_char_of_string ()
 
        case '\n':
          /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
-         as_warn ("Unterminated string: Newline inserted.");
+         as_warn (_("Unterminated string: Newline inserted."));
          c = '\n';
          bump_line_counters ();
          break;
@@ -4423,7 +4614,7 @@ next_char_of_string ()
        default:
 
 #ifdef ONLY_STANDARD_ESCAPES
-         as_bad ("Bad escaped character in string, '?' assumed");
+         as_bad (_("Bad escaped character in string, '?' assumed"));
          c = '?';
 #endif /* ONLY_STANDARD_ESCAPES */
 
@@ -4449,7 +4640,7 @@ get_segmented_expression (expP)
       || expP->X_op == O_absent
       || expP->X_op == O_big)
     {
-      as_bad ("expected address expression; zero assumed");
+      as_bad (_("expected address expression; zero assumed"));
       expP->X_op = O_constant;
       expP->X_add_number = 0;
       retval = absolute_section;
@@ -4469,10 +4660,10 @@ get_known_segmented_expression (expP)
         expression.  */
       if (expP->X_add_symbol != NULL
          && S_GET_SEGMENT (expP->X_add_symbol) != expr_section)
-       as_warn ("symbol \"%s\" undefined; zero assumed",
+       as_warn (_("symbol \"%s\" undefined; zero assumed"),
                 S_GET_NAME (expP->X_add_symbol));
       else
-       as_warn ("some symbol undefined; zero assumed");
+       as_warn (_("some symbol undefined; zero assumed"));
       retval = absolute_section;
       expP->X_op = O_constant;
       expP->X_add_number = 0;
@@ -4490,7 +4681,7 @@ get_absolute_expression ()
   if (exp.X_op != O_constant)
     {
       if (exp.X_op != O_absent)
-       as_bad ("bad or irreducible absolute expression; zero assumed");
+       as_bad (_("bad or irreducible absolute expression; zero assumed"));
       exp.X_add_number = 0;
     }
   return exp.X_add_number;
@@ -4528,7 +4719,7 @@ demand_copy_C_string (len_pointer)
              s = 0;
              len = 1;
              *len_pointer = 0;
-             as_bad ("This string may not contain \'\\0\'");
+             as_bad (_("This string may not contain \'\\0\'"));
            }
        }
     }
@@ -4567,7 +4758,7 @@ demand_copy_string (lenP)
     }
   else
     {
-      as_warn ("Missing string");
+      as_warn (_("Missing string"));
       retval = NULL;
       ignore_rest_of_line ();
     }
@@ -4597,7 +4788,7 @@ equals (sym_name, reassign)
      int reassign;
 {
   register symbolS *symbolP;   /* symbol we are working with */
-  char *stop;
+  char *stop = NULL;
   char stopc;
 
   input_line_pointer++;
@@ -4627,12 +4818,15 @@ equals (sym_name, reassign)
       if (! reassign
          && S_IS_DEFINED (symbolP)
          && S_GET_SEGMENT (symbolP) != reg_section)
-       as_bad ("symbol `%s' already defined", S_GET_NAME (symbolP));
+       as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
       pseudo_set (symbolP);
     }
 
   if (flag_mri)
-    mri_comment_end (stop, stopc);
+     {
+       ignore_rest_of_line (); /* check garbage after the expression */
+       mri_comment_end (stop, stopc);
+     }
 }                              /* equals() */
 
 /* .include -- include a file at this point. */
@@ -4640,7 +4834,7 @@ equals (sym_name, reassign)
 /* ARGSUSED */
 void 
 s_include (arg)
-     int arg;
+     int arg ATTRIBUTE_UNUSED;
 {
   char *newbuf;
   char *filename;
@@ -4649,7 +4843,15 @@ s_include (arg)
   char *path;
 
   if (! flag_m68k_mri)
-    filename = demand_copy_string (&i);
+    {
+      filename = demand_copy_string (&i);
+      if (filename == NULL)
+       {
+         /* demand_copy_string has already printed an error and
+             called ignore_rest_of_line.  */
+         return;
+       }
+    }
   else
     {
       SKIP_WHITESPACE ();
@@ -4714,10 +4916,147 @@ add_include_dir (path)
   if (i > include_dir_maxlen)
     include_dir_maxlen = i;
 }                              /* add_include_dir() */
+\f
+/* Output debugging information to denote the source file.  */
+
+static void
+generate_file_debug ()
+{
+  if (debug_type == DEBUG_STABS)
+    stabs_generate_asm_file ();
+}
+
+/* Output line number debugging information for the current source line.  */
+
+void
+generate_lineno_debug ()
+{
+#ifdef ECOFF_DEBUGGING
+  /* ECOFF assemblers automatically generate debugging information. 
+     FIXME: This should probably be handled elsewhere.  */
+  if (debug_type == DEBUG_UNSPECIFIED)
+    {
+      if (ECOFF_DEBUGGING && ecoff_no_current_file ())
+        debug_type = DEBUG_ECOFF;
+      else
+       debug_type = DEBUG_NONE;
+    }
+#endif
+
+  switch (debug_type)
+    {
+    case DEBUG_UNSPECIFIED:
+    case DEBUG_NONE:
+      break;
+    case DEBUG_STABS:
+      stabs_generate_asm_lineno ();
+      break;
+    case DEBUG_ECOFF:
+      ecoff_generate_asm_lineno ();
+      break;
+    case DEBUG_DWARF:
+    case DEBUG_DWARF2:
+      /* FIXME.  */
+      break;
+    }
+}
+
+/* Output debugging information to mark a function entry point or end point.
+   END_P is zero for .func, and non-zero for .endfunc.  */
+
+void
+s_func (end_p)
+     int end_p;
+{
+  do_s_func (end_p, NULL);
+}
+
+/* Subroutine of s_func so targets can choose a different default prefix.
+   If DEFAULT_PREFIX is NULL, use the target's "leading char".  */
 
+void
+do_s_func (end_p, default_prefix)
+     int end_p;
+     const char *default_prefix;
+{
+  /* Record the current function so that we can issue an error message for
+     misplaced .func,.endfunc, and also so that .endfunc needs no
+     arguments.  */
+  static char *current_name;
+  static char *current_label;
+
+  if (end_p)
+    {
+      if (current_name == NULL)
+       {
+         as_bad (_("missing .func"));
+         ignore_rest_of_line ();
+         return;
+       }
+
+      if (debug_type == DEBUG_STABS)
+       stabs_generate_asm_endfunc (current_name, current_label);
+
+      current_name = current_label = NULL;
+    }
+  else /* ! end_p */
+    {
+      char *name,*label;
+      char delim1,delim2;
+
+      if (current_name != NULL)
+       {
+         as_bad (_(".endfunc missing for previous .func"));
+         ignore_rest_of_line ();
+         return;
+       }
+
+      name = input_line_pointer;
+      delim1 = get_symbol_end ();
+      name = xstrdup (name);
+      *input_line_pointer = delim1;
+      SKIP_WHITESPACE ();
+      if (*input_line_pointer != ',')
+       {
+         if (default_prefix)
+           asprintf (&label, "%s%s", default_prefix, name);
+         else
+           {
+             char leading_char = 0;
+#ifdef BFD_ASSEMBLER
+             leading_char = bfd_get_symbol_leading_char (stdoutput);
+#endif
+             /* Missing entry point, use function's name with the leading
+                char prepended.  */
+             if (leading_char)
+               asprintf (&label, "%c%s", leading_char, name);
+             else
+               label = name;
+           }
+       }
+      else
+       {
+         ++input_line_pointer;
+         SKIP_WHITESPACE ();
+         label = input_line_pointer;
+         delim2 = get_symbol_end ();
+         label = xstrdup (label);
+         *input_line_pointer = delim2;
+       }
+
+      if (debug_type == DEBUG_STABS)
+       stabs_generate_asm_func (name, label);
+
+      current_name = name;
+      current_label = label;
+    }
+
+  demand_empty_rest_of_line ();
+}
+\f
 void 
 s_ignore (arg)
-     int arg;
+     int arg ATTRIBUTE_UNUSED;
 {
   while (!is_end_of_line[(unsigned char) *input_line_pointer])
     {
This page took 0.058699 seconds and 4 git commands to generate.