Revert the AM_ZLIB change in gas
[deliverable/binutils-gdb.git] / gas / read.c
index d65971cfbec53185df42ed04759f6fe5e65500f3..2224c0ed241845eb2e73f59b807dedd617f2a0e0 100644 (file)
@@ -1,7 +1,5 @@
 /* read.c - read a source file -
-   Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-   2010, 2011, 2012  Free Software Foundation, Inc.
+   Copyright (C) 1986-2015 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -265,8 +263,11 @@ read_begin (void)
   obstack_begin (&notes, chunksize);
   obstack_begin (&cond_obstack, chunksize);
 
+#ifndef tc_line_separator_chars
+#define tc_line_separator_chars line_separator_chars
+#endif
   /* Use machine dependent syntax.  */
-  for (p = line_separator_chars; *p; p++)
+  for (p = tc_line_separator_chars; *p; p++)
     is_end_of_line[(unsigned char) *p] = 2;
   /* Use more.  FIXME-SOMEDAY.  */
 
@@ -556,10 +557,11 @@ pobegin (void)
   cfi_pop_insert ();
 }
 \f
-#define HANDLE_CONDITIONAL_ASSEMBLY()                                  \
+#define HANDLE_CONDITIONAL_ASSEMBLY(num_read)                          \
   if (ignore_input ())                                                 \
     {                                                                  \
-      char *eol = find_end_of_line (input_line_pointer, flag_m68k_mri); \
+      char *eol = find_end_of_line (input_line_pointer - (num_read),   \
+                                   flag_m68k_mri);                     \
       input_line_pointer = (input_line_pointer <= buffer_limit         \
                            && eol >= buffer_limit)                     \
                           ? buffer_limit                               \
@@ -833,7 +835,7 @@ read_a_source_file (char *name)
                      char *line_start = input_line_pointer;
                      int mri_line_macro;
 
-                     HANDLE_CONDITIONAL_ASSEMBLY ();
+                     HANDLE_CONDITIONAL_ASSEMBLY (0);
 
                      c = get_symbol_end ();
 
@@ -904,7 +906,7 @@ read_a_source_file (char *name)
          if (is_name_beginner (c))
            {
              /* Want user-defined label or pseudo/opcode.  */
-             HANDLE_CONDITIONAL_ASSEMBLY ();
+             HANDLE_CONDITIONAL_ASSEMBLY (1);
 
              s = --input_line_pointer;
              c = get_symbol_end ();    /* name's delimiter.  */
@@ -1118,7 +1120,7 @@ read_a_source_file (char *name)
              /* local label  ("4:")  */
              char *backup = input_line_pointer;
 
-             HANDLE_CONDITIONAL_ASSEMBLY ();
+             HANDLE_CONDITIONAL_ASSEMBLY (1);
 
              temp = c - '0';
 
@@ -1265,7 +1267,7 @@ read_a_source_file (char *name)
              continue;
            }
 
-         HANDLE_CONDITIONAL_ASSEMBLY ();
+         HANDLE_CONDITIONAL_ASSEMBLY (1);
 
 #ifdef tc_unrecognized_line
          if (tc_unrecognized_line (c))
@@ -1306,10 +1308,10 @@ read_a_source_file (char *name)
 }
 
 /* Convert O_constant expression EXP into the equivalent O_big representation.
-   Take the sign of the number from X_unsigned rather than X_add_number.  */
+   Take the sign of the number from SIGN rather than X_add_number.  */
 
 static void
-convert_to_bignum (expressionS *exp)
+convert_to_bignum (expressionS *exp, int sign)
 {
   valueT value;
   unsigned int i;
@@ -1322,8 +1324,8 @@ convert_to_bignum (expressionS *exp)
     }
   /* Add a sequence of sign bits if the top bit of X_add_number is not
      the sign of the original value.  */
-  if ((exp->X_add_number < 0) != !exp->X_unsigned)
-    generic_bignum[i++] = exp->X_unsigned ? 0 : LITTLENUM_MASK;
+  if ((exp->X_add_number < 0) == !sign)
+    generic_bignum[i++] = sign ? LITTLENUM_MASK : 0;
   exp->X_op = O_big;
   exp->X_add_number = i;
 }
@@ -1577,7 +1579,7 @@ s_align_ptwo (int arg)
 
 /* Switch in and out of alternate macro mode.  */
 
-void
+static void
 s_altmacro (int on)
 {
   demand_empty_rest_of_line ();
@@ -1598,7 +1600,7 @@ s_altmacro (int on)
    If a symbol name could not be read, the routine issues an error
    messages, skips to the end of the line and returns NULL.  */
 
-static char *
+char *
 read_symbol_name (void)
 {
   char * name;
@@ -1703,7 +1705,7 @@ s_comm_internal (int param,
 
   temp = get_absolute_expr (&exp);
   size = temp;
-  size &= ((offsetT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
+  size &= ((addressT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
   if (exp.X_op == O_absent)
     {
       as_bad (_("missing size expression"));
@@ -3186,7 +3188,7 @@ assign_symbol (char *name, int mode)
          symbol_set_frag (symbolP, dummy_frag);
        }
 #endif
-#ifdef OBJ_COFF
+#if defined (OBJ_COFF) && !defined (TE_PE)
       /* "set" symbols are local unless otherwise specified.  */
       SF_SET_LOCAL (symbolP);
 #endif
@@ -3850,19 +3852,22 @@ parse_mri_cons (expressionS *exp, unsigned int nbytes);
 
 #ifndef TC_PARSE_CONS_EXPRESSION
 #ifdef BITFIELD_CONS_EXPRESSIONS
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  (parse_bitfield_cons (EXP, NBYTES), TC_PARSE_CONS_RETURN_NONE)
 static void
 parse_bitfield_cons (expressionS *exp, unsigned int nbytes);
 #endif
 #ifdef REPEAT_CONS_EXPRESSIONS
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  (parse_repeat_cons (EXP, NBYTES), TC_PARSE_CONS_RETURN_NONE)
 static void
 parse_repeat_cons (expressionS *exp, unsigned int nbytes);
 #endif
 
 /* If we haven't gotten one yet, just call expression.  */
 #ifndef TC_PARSE_CONS_EXPRESSION
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  (expression (EXP), TC_PARSE_CONS_RETURN_NONE)
 #endif
 #endif
 
@@ -3870,7 +3875,7 @@ void
 do_parse_cons_expression (expressionS *exp,
                          int nbytes ATTRIBUTE_UNUSED)
 {
-  TC_PARSE_CONS_EXPRESSION (exp, nbytes);
+  (void) TC_PARSE_CONS_EXPRESSION (exp, nbytes);
 }
 
 
@@ -3913,6 +3918,14 @@ cons_worker (int nbytes, /* 1=.byte, 2=.word, 4=.long.  */
   c = 0;
   do
     {
+      TC_PARSE_CONS_RETURN_TYPE ret = TC_PARSE_CONS_RETURN_NONE;
+#ifdef TC_CONS_FIX_CHECK
+      fixS **cur_fix = &frchain_now->fix_tail;
+
+      if (*cur_fix != NULL)
+       cur_fix = &(*cur_fix)->fx_next;
+#endif
+
 #ifdef TC_M68K
       if (flag_m68k_mri)
        parse_mri_cons (&exp, (unsigned int) nbytes);
@@ -3925,7 +3938,7 @@ cons_worker (int nbytes,  /* 1=.byte, 2=.word, 4=.long.  */
              ignore_rest_of_line ();
              return;
            }
-         TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
+         ret = TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
        }
 
       if (rva)
@@ -3935,7 +3948,10 @@ cons_worker (int nbytes, /* 1=.byte, 2=.word, 4=.long.  */
          else
            as_fatal (_("rva without symbol"));
        }
-      emit_expr (&exp, (unsigned int) nbytes);
+      emit_expr_with_reloc (&exp, (unsigned int) nbytes, ret);
+#ifdef TC_CONS_FIX_CHECK
+      TC_CONS_FIX_CHECK (&exp, nbytes, *cur_fix);
+#endif
       ++c;
     }
   while (*input_line_pointer++ == ',');
@@ -3968,7 +3984,7 @@ s_rva (int size)
 
 /* .reloc offset, reloc_name, symbol+addend.  */
 
-void
+static void
 s_reloc (int ignore ATTRIBUTE_UNUSED)
 {
   char *stop = NULL;
@@ -3977,6 +3993,14 @@ s_reloc (int ignore ATTRIBUTE_UNUSED)
   char *r_name;
   int c;
   struct reloc_list *reloc;
+  struct _bfd_rel { char *name; bfd_reloc_code_real_type code; };
+  static struct _bfd_rel bfd_relocs[] = {
+    { "NONE", BFD_RELOC_NONE },
+    { "8", BFD_RELOC_8 },
+    { "16", BFD_RELOC_16 },
+    { "32", BFD_RELOC_32 },
+    { "64", BFD_RELOC_64 }
+  };
 
   reloc = (struct reloc_list *) xmalloc (sizeof (*reloc));
 
@@ -4019,7 +4043,20 @@ s_reloc (int ignore ATTRIBUTE_UNUSED)
   SKIP_WHITESPACE ();
   r_name = input_line_pointer;
   c = get_symbol_end ();
-  reloc->u.a.howto = bfd_reloc_name_lookup (stdoutput, r_name);
+  if (strncasecmp (r_name, "BFD_RELOC_", 10) == 0)
+    {
+      unsigned int i;
+
+      for (reloc->u.a.howto = NULL, i = 0; i < ARRAY_SIZE (bfd_relocs); i++)
+       if (strcasecmp (r_name + 10, bfd_relocs[i].name) == 0)
+         {
+           reloc->u.a.howto = bfd_reloc_type_lookup (stdoutput,
+                                                     bfd_relocs[i].code);
+           break;
+         }
+    }
+  else
+    reloc->u.a.howto = bfd_reloc_name_lookup (stdoutput, r_name);
   *input_line_pointer = c;
   if (reloc->u.a.howto == NULL)
     {
@@ -4078,6 +4115,14 @@ s_reloc (int ignore ATTRIBUTE_UNUSED)
 
 void
 emit_expr (expressionS *exp, unsigned int nbytes)
+{
+  emit_expr_with_reloc (exp, nbytes, TC_PARSE_CONS_RETURN_NONE);
+}
+
+void
+emit_expr_with_reloc (expressionS *exp,
+                     unsigned int nbytes,
+                     TC_PARSE_CONS_RETURN_TYPE reloc)
 {
   operatorT op;
   char *p;
@@ -4087,10 +4132,9 @@ emit_expr (expressionS *exp, unsigned int nbytes)
   if (need_pass_2)
     return;
 
-  /* Grow the current frag now so that dot_value does not get invalidated
-     if the frag were to fill up in the frag_more() call below.  */
   frag_grow (nbytes);
   dot_value = frag_now_fix ();
+  dot_frag = frag_now;
 
 #ifndef NO_LISTING
 #ifdef OBJ_ELF
@@ -4221,6 +4265,12 @@ emit_expr (expressionS *exp, unsigned int nbytes)
 
   p = frag_more ((int) nbytes);
 
+  if (reloc != TC_PARSE_CONS_RETURN_NONE)
+    {
+      emit_expr_fix (exp, nbytes, frag_now, p, reloc);
+      return;
+    }
+
 #ifndef WORKING_DOT_WORD
   /* If we have the difference of two symbols in a word, save it on
      the broken_words list.  See the code in write.c.  */
@@ -4251,7 +4301,7 @@ emit_expr (expressionS *exp, unsigned int nbytes)
   if (op == O_constant && nbytes > sizeof (valueT))
     {
       extra_digit = exp->X_unsigned ? 0 : -1;
-      convert_to_bignum (exp);
+      convert_to_bignum (exp, !exp->X_unsigned);
       op = O_big;
     }
 
@@ -4379,23 +4429,41 @@ emit_expr (expressionS *exp, unsigned int nbytes)
        }
     }
   else
-    emit_expr_fix (exp, nbytes, frag_now, p);
+    emit_expr_fix (exp, nbytes, frag_now, p, TC_PARSE_CONS_RETURN_NONE);
 }
 
 void
-emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p)
+emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p,
+              TC_PARSE_CONS_RETURN_TYPE r ATTRIBUTE_UNUSED)
 {
-  memset (p, 0, nbytes);
+  int offset = 0;
+  unsigned int size = nbytes;
+
+  memset (p, 0, size);
 
   /* Generate a fixS to record the symbol value.  */
 
 #ifdef TC_CONS_FIX_NEW
-  TC_CONS_FIX_NEW (frag, p - frag->fr_literal, nbytes, exp);
+  TC_CONS_FIX_NEW (frag, p - frag->fr_literal + offset, size, exp, r);
 #else
-  {
-    bfd_reloc_code_real_type r;
+  if (r != TC_PARSE_CONS_RETURN_NONE)
+    {
+      reloc_howto_type *reloc_howto;
 
-    switch (nbytes)
+      reloc_howto = bfd_reloc_type_lookup (stdoutput, r);
+      size = bfd_get_reloc_size (reloc_howto);
+
+      if (size > nbytes)
+       {
+         as_bad (_("%s relocations do not fit in %u bytes\n"),
+                 reloc_howto->name, nbytes);
+         return;
+       }
+      else if (target_big_endian)
+       offset = nbytes - size;
+    }
+  else
+    switch (size)
       {
       case 1:
        r = BFD_RELOC_8;
@@ -4413,13 +4481,11 @@ emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p)
        r = BFD_RELOC_64;
        break;
       default:
-       as_bad (_("unsupported BFD relocation size %u"), nbytes);
-       r = BFD_RELOC_32;
-       break;
+       as_bad (_("unsupported BFD relocation size %u"), size);
+       return;
       }
-    fix_new_exp (frag, p - frag->fr_literal, (int) nbytes, exp,
-                0, r);
-  }
+  fix_new_exp (frag, p - frag->fr_literal + offset, size,
+              exp, 0, r);
 #endif
 }
 \f
@@ -4545,6 +4611,7 @@ parse_bitfield_cons (exp, nbytes)
       exp->X_add_number = value;
       exp->X_op = O_constant;
       exp->X_unsigned = 1;
+      exp->X_extrabit = 0;
     }
 }
 
@@ -4554,15 +4621,13 @@ parse_bitfield_cons (exp, nbytes)
 
 #ifdef TC_M68K
 static void
-parse_mri_cons (exp, nbytes)
-     expressionS *exp;
-     unsigned int nbytes;
+parse_mri_cons (expressionS *exp, unsigned int nbytes)
 {
   if (*input_line_pointer != '\''
       && (input_line_pointer[1] != '\''
          || (*input_line_pointer != 'A'
              && *input_line_pointer != 'E')))
-    TC_PARSE_CONS_EXPRESSION (exp, nbytes);
+    (void) TC_PARSE_CONS_EXPRESSION (exp, nbytes);
   else
     {
       unsigned int scan;
@@ -5104,12 +5169,12 @@ emit_leb128_expr (expressionS *exp, int sign)
     }
   else if (op == O_constant
           && sign
-          && (exp->X_add_number < 0) != !exp->X_unsigned)
+          && (exp->X_add_number < 0) == !exp->X_extrabit)
     {
       /* We're outputting a signed leb128 and the sign of X_add_number
         doesn't reflect the sign of the original value.  Convert EXP
         to a correctly-extended bignum instead.  */
-      convert_to_bignum (exp);
+      convert_to_bignum (exp, exp->X_extrabit);
       op = O_big;
     }
 
@@ -5794,8 +5859,8 @@ add_include_dir (char *path)
     {
       include_dir_count++;
       include_dirs =
-       (char **) realloc (include_dirs,
-                          include_dir_count * sizeof (*include_dirs));
+       (char **) xrealloc (include_dirs,
+                           include_dir_count * sizeof (*include_dirs));
     }
 
   include_dirs[include_dir_count - 1] = path;  /* New one.  */
@@ -6095,7 +6160,7 @@ _find_end_of_line (char *s, int mri_string, int insn ATTRIBUTE_UNUSED,
     }
   if (inquote)
     as_warn (_("missing closing `%c'"), inquote);
-  if (inescape)
+  if (inescape && !ignore_input ())
     as_warn (_("stray `\\'"));
   return s;
 }
This page took 0.031097 seconds and 4 git commands to generate.