Update Russian translation for the gas/ sub-directory.
[deliverable/binutils-gdb.git] / gas / read.c
index 2f756db862d20170aa071cf387caaf518954037b..7bf52f112182c0d87fa2efbca52268dba0bdba92 100644 (file)
@@ -1,5 +1,5 @@
 /* read.c - read a source file -
-   Copyright (C) 1986-2016 Free Software Foundation, Inc.
+   Copyright (C) 1986-2018 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -19,7 +19,7 @@
    02110-1301, USA.  */
 
 /* If your chars aren't 8 bits, you will change this a bit (eg. to 0xFF).
-   But then, GNU isn't spozed to run on your machine anyway.
+   But then, GNU isn't supposed to run on your machine anyway.
    (RMS is so shortsighted sometimes.)  */
 #define MASK_CHAR ((int)(unsigned char) -1)
 
@@ -62,6 +62,7 @@
 #endif
 
 char *input_line_pointer;      /*->next char of source file to parse.  */
+bfd_boolean input_from_string = FALSE;
 
 #if BITS_PER_CHAR != 8
 /*  The following table is indexed by[(char)] and will break if
@@ -713,19 +714,19 @@ assemble_one (char *line)
       /* Make sure this hasn't pushed the locked sequence
         past the bundle size.  */
       unsigned int bundle_size = pending_bundle_size (bundle_lock_frag);
-      if (bundle_size > (1U << bundle_align_p2))
-       as_bad (_("\
-.bundle_lock sequence at %u bytes but .bundle_align_mode limit is %u bytes"),
+      if (bundle_size > 1U << bundle_align_p2)
+       as_bad (_ (".bundle_lock sequence at %u bytes, "
+                  "but .bundle_align_mode limit is %u bytes"),
                bundle_size, 1U << bundle_align_p2);
     }
   else if (bundle_align_p2 > 0)
     {
       unsigned int insn_size = pending_bundle_size (insn_start_frag);
 
-      if (insn_size > (1U << bundle_align_p2))
-       as_bad (_("\
-single instruction is %u bytes long but .bundle_align_mode limit is %u"),
-               (unsigned int) insn_size, 1U << bundle_align_p2);
+      if (insn_size > 1U << bundle_align_p2)
+       as_bad (_("single instruction is %u bytes long, "
+                 "but .bundle_align_mode limit is %u bytes"),
+               insn_size, 1U << bundle_align_p2);
 
       finish_bundle (insn_start_frag, insn_size);
     }
@@ -1684,16 +1685,16 @@ read_symbol_name (void)
       if (mbstowcs (NULL, name, len) == (size_t) -1)
        as_warn (_("symbol name not recognised in the current locale"));
     }
-  else if (is_name_beginner (c) || c == '\001')
+  else if (is_name_beginner (c) || (input_from_string && c == FAKE_LABEL_CHAR))
     {
       ptrdiff_t len;
 
       name = input_line_pointer - 1;
 
-      /* We accept \001 in a name in case this is
+      /* We accept FAKE_LABEL_CHAR in a name in case this is
         being called with a constructed string.  */
       while (is_part_of_name (c = *input_line_pointer++)
-            || c == '\001')
+            || (input_from_string && c == FAKE_LABEL_CHAR))
        ;
 
       len = (input_line_pointer - name) - 1;
@@ -2202,7 +2203,7 @@ s_fill (int ignore ATTRIBUTE_UNUSED)
   md_cons_align (1);
 #endif
 
-  get_known_segmented_expression (&rep_exp);
+  expression (&rep_exp);
   if (*input_line_pointer == ',')
     {
       input_line_pointer++;
@@ -3106,9 +3107,9 @@ s_bad_end (int endr)
 void
 s_rept (int ignore ATTRIBUTE_UNUSED)
 {
-  int count;
+  size_t count;
 
-  count = get_absolute_expression ();
+  count = (size_t) get_absolute_expression ();
 
   do_repeat (count, "REPT", "ENDR");
 }
@@ -3117,11 +3118,17 @@ s_rept (int ignore ATTRIBUTE_UNUSED)
    different directives to be used as the start/end keys.  */
 
 void
-do_repeat (int count, const char *start, const char *end)
+do_repeat (size_t count, const char *start, const char *end)
 {
   sb one;
   sb many;
 
+  if (((ssize_t) count) < 0)
+    {
+      as_bad (_("negative count for %s - ignored"), start);
+      count = 0;
+    }
+
   sb_new (&one);
   if (!buffer_and_nest (start, end, &one, get_non_macro_line_sb))
     {
@@ -3141,10 +3148,10 @@ do_repeat (int count, const char *start, const char *end)
 }
 
 /* Like do_repeat except that any text matching EXPANDER in the
-   block is replaced by the itteration count.  */
+   block is replaced by the iteration count.  */
 
 void
-do_repeat_with_expander (int count,
+do_repeat_with_expander (size_t count,
                         const char * start,
                         const char * end,
                         const char * expander)
@@ -3152,6 +3159,12 @@ do_repeat_with_expander (int count,
   sb one;
   sb many;
 
+  if (((ssize_t) count) < 0)
+    {
+      as_bad (_("negative count for %s - ignored"), start);
+      count = 0;
+    }
+
   sb_new (&one);
   if (!buffer_and_nest (start, end, &one, get_non_macro_line_sb))
     {
@@ -3172,7 +3185,7 @@ do_repeat_with_expander (int count,
          sb_build (& processed, one.len);
          sb_add_sb (& processed, & one);
          sub = strstr (processed.ptr, expander);
-         len = sprintf (sub, "%d", count);
+         len = sprintf (sub, "%lu", (unsigned long) count);
          gas_assert (len < 8);
          strcpy (sub + len, sub + 8);
          processed.len -= (8 - len);
@@ -3394,11 +3407,20 @@ s_space (int mult)
        {
          offsetT i;
 
-         if (mult == 0)
-           mult = 1;
-         bytes = mult * exp.X_add_number;
-         for (i = 0; i < exp.X_add_number; i++)
-           emit_expr (&val, mult);
+         /* PR 20901: Check for excessive values.
+            FIXME: 1<<10 is an arbitrary limit.  Maybe use maxpagesize instead ?  */
+         if (exp.X_add_number < 0 || exp.X_add_number > (1 << 10))
+           as_bad (_("size value for space directive too large: %lx"),
+                   (long) exp.X_add_number);
+         else
+           {
+             if (mult == 0)
+               mult = 1;
+             bytes = mult * exp.X_add_number;
+
+             for (i = 0; i < exp.X_add_number; i++)
+               emit_expr (&val, mult);
+           }
        }
     }
   else
@@ -3861,7 +3883,7 @@ pseudo_set (symbolS *symbolP)
          symbolS *s = exp.X_add_symbol;
 
          if (S_IS_COMMON (s))
-           as_bad (_("`%s' can't be equated to common symbol '%s'"),
+           as_bad (_("`%s' can't be equated to common symbol `%s'"),
                    S_GET_NAME (symbolP), S_GET_NAME (s));
 
          S_SET_SEGMENT (symbolP, seg);
@@ -4468,7 +4490,10 @@ emit_expr_with_reloc (expressionS *exp,
            }
 
          if (i < exp->X_add_number)
-           as_warn (_("bignum truncated to %d bytes"), nbytes);
+           as_warn (ngettext ("bignum truncated to %d byte",
+                              "bignum truncated to %d bytes",
+                              nbytes),
+                    nbytes);
          size = nbytes;
        }
 
@@ -4544,7 +4569,9 @@ emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p,
 
       if (size > nbytes)
        {
-         as_bad (_("%s relocations do not fit in %u bytes\n"),
+         as_bad (ngettext ("%s relocations do not fit in %u byte",
+                           "%s relocations do not fit in %u bytes",
+                           nbytes),
                  reloc_howto->name, nbytes);
          return;
        }
@@ -4653,7 +4680,11 @@ parse_bitfield_cons (expressionS *exp, unsigned int 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 (ngettext ("field width %lu too big to fit in %d byte:"
+                                " truncated to %d bits",
+                                "field width %lu too big to fit in %d bytes:"
+                                " truncated to %d bits",
+                                nbytes),
                       width, nbytes, (BITS_PER_CHAR * nbytes));
              width = BITS_PER_CHAR * nbytes;
            }                   /* Too big.  */
@@ -5335,13 +5366,21 @@ emit_leb128_expr (expressionS *exp, int sign)
   else if (op == O_big)
     {
       /* O_big is a different sort of constant.  */
-
+      int nbr_digits = exp->X_add_number;
       unsigned int size;
       char *p;
 
-      size = output_big_leb128 (NULL, generic_bignum, exp->X_add_number, sign);
+      /* If the leading littenum is 0xffff, prepend a 0 to avoid confusion with
+        a signed number.  Unary operators like - or ~ always extend the
+        bignum to its largest size.  */
+      if (exp->X_unsigned
+         && nbr_digits < SIZE_OF_LARGE_NUMBER
+         && generic_bignum[nbr_digits - 1] == LITTLENUM_MASK)
+       generic_bignum[nbr_digits++] = 0;
+
+      size = output_big_leb128 (NULL, generic_bignum, nbr_digits, sign);
       p = frag_more (size);
-      if (output_big_leb128 (p, generic_bignum, exp->X_add_number, sign) > size)
+      if (output_big_leb128 (p, generic_bignum, nbr_digits, sign) > size)
        abort ();
     }
   else
@@ -5367,7 +5406,7 @@ s_leb128 (int sign)
 
   do
     {
-      expression (&exp);
+      deferred_expression (&exp);
       emit_leb128_expr (&exp, sign);
     }
   while (*input_line_pointer++ == ',');
@@ -5533,6 +5572,12 @@ next_char_of_string (void)
   c = *input_line_pointer++ & CHAR_MASK;
   switch (c)
     {
+    case 0:
+      /* PR 20902: Do not advance past the end of the buffer.  */
+      -- input_line_pointer;
+      c = NOT_A_CHAR;
+      break;
+
     case '\"':
       c = NOT_A_CHAR;
       break;
@@ -5629,6 +5674,12 @@ next_char_of_string (void)
          bump_line_counters ();
          break;
 
+       case 0:
+         /* Do not advance past the end of the buffer.  */
+         -- input_line_pointer;
+         c = NOT_A_CHAR;
+         break;
+
        default:
 
 #ifdef ONLY_STANDARD_ESCAPES
@@ -6194,9 +6245,10 @@ s_bundle_unlock (int arg ATTRIBUTE_UNUSED)
 
   size = pending_bundle_size (bundle_lock_frag);
 
-  if (size > (1U << bundle_align_p2))
-    as_bad (_(".bundle_lock sequence is %u bytes, but bundle size only %u"),
-           size, 1 << bundle_align_p2);
+  if (size > 1U << bundle_align_p2)
+    as_bad (_(".bundle_lock sequence is %u bytes, "
+             "but bundle size is only %u bytes"),
+           size, 1u << bundle_align_p2);
   else
     finish_bundle (bundle_lock_frag, size);
 
@@ -6304,3 +6356,49 @@ find_end_of_line (char *s, int mri_string)
 {
   return _find_end_of_line (s, mri_string, 0, 0);
 }
+
+static char *saved_ilp = NULL;
+static char *saved_limit;
+
+/* Use BUF as a temporary input pointer for calling other functions in this
+   file.  BUF must be a C string, so that its end can be found by strlen.
+   Also sets the buffer_limit variable (local to this file) so that buffer
+   overruns should not occur.  Saves the current input line pointer so that
+   it can be restored by calling restore_ilp().
+
+   Does not support recursion.
+
+   FIXME: This function is currently only used by stabs.c but that
+   should be extended to other files in the gas source directory.  */
+
+void
+temp_ilp (char *buf)
+{
+  gas_assert (saved_ilp == NULL);
+  gas_assert (buf != NULL);
+
+  saved_ilp = input_line_pointer;
+  saved_limit = buffer_limit;
+  /* Prevent the assert in restore_ilp from triggering if
+     the input_line_pointer has not yet been initialised.  */
+  if (saved_ilp == NULL)
+    saved_limit = saved_ilp = (char *) "";
+
+  input_line_pointer = buf;
+  buffer_limit = buf + strlen (buf);
+  input_from_string = TRUE;
+}
+
+/* Restore a saved input line pointer.  */
+
+void
+restore_ilp (void)
+{
+  gas_assert (saved_ilp != NULL);
+
+  input_line_pointer = saved_ilp;
+  buffer_limit = saved_limit;
+  input_from_string = FALSE;
+
+  saved_ilp = NULL;
+}
This page took 0.027155 seconds and 4 git commands to generate.