* elf-bfd.h (_bfd_elf_create_linker_section) Don't declare.
[deliverable/binutils-gdb.git] / gas / read.c
index 1e13698f9ddecd64eb33eb86d66d28d45e8d3226..417934807515834335e96612d80c22f68c7caf76 100644 (file)
@@ -1,6 +1,6 @@
 /* read.c - read a source file -
    Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GAS, the GNU Assembler.
 
@@ -35,19 +35,18 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 /* Routines that read assembler source text to build spagetti in memory.
    Another group of these functions is in the expr.c module.  */
 
-/* For isdigit ().  */
-#include <ctype.h>
-
 #include "as.h"
+#include "safe-ctype.h"
 #include "subsegs.h"
 #include "sb.h"
 #include "macro.h"
 #include "obstack.h"
 #include "listing.h"
 #include "ecoff.h"
+#include "dw2gencfi.h"
 
 #ifndef TC_START_LABEL
-#define TC_START_LABEL(x,y) (x==':')
+#define TC_START_LABEL(x,y) (x == ':')
 #endif
 
 /* Set by the object-format or the target.  */
@@ -170,10 +169,6 @@ static char *buffer_limit; /*->1 + last char in buffer.  */
    internals manual.  */
 int target_big_endian = TARGET_BYTES_BIG_ENDIAN;
 
-static char *old_buffer;       /* JF a hack.  */
-static char *old_input;
-static char *old_limit;
-
 /* Variables for handling include file directory table.  */
 
 /* Table of pointers to directories to search for .include's.  */
@@ -317,6 +312,7 @@ static const pseudo_typeS potable[] = {
   {"endc", s_endif, 0},
   {"endfunc", s_func, 1},
   {"endif", s_endif, 0},
+  {"endr", s_bad_endr, 0},
 /* endef  */
   {"equ", s_set, 0},
   {"equiv", s_set, 1},
@@ -456,6 +452,10 @@ pop_insert (table)
 #define obj_pop_insert()       pop_insert(obj_pseudo_table)
 #endif
 
+#ifndef cfi_pop_insert
+#define cfi_pop_insert()       pop_insert(cfi_pseudo_table)
+#endif
+
 static void
 pobegin ()
 {
@@ -473,6 +473,12 @@ pobegin ()
   /* Now portable ones.  Skip any that we've seen already.  */
   pop_table_name = "standard";
   pop_insert (potable);
+  
+#ifdef TARGET_USE_CFIPOP
+  pop_table_name = "cfi";
+  pop_override_ok = 1;
+  cfi_pop_insert ();
+#endif
 }
 \f
 #define HANDLE_CONDITIONAL_ASSEMBLY()                                  \
@@ -534,9 +540,7 @@ read_a_source_file (name)
   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.  */
-    contin:                    /* JF this goto is my fault I admit it.
-                                  Someone brave please re-write the whole
-                                  input section here?  Pleeze???  */
+
       while (input_line_pointer < buffer_limit)
        {
          /* We have more of this buffer to parse.  */
@@ -711,6 +715,9 @@ read_a_source_file (name)
                  line_label = colon (s);       /* User-defined label.  */
                  /* Put ':' back for error messages' sake.  */
                  *input_line_pointer++ = ':';
+#ifdef tc_check_label
+                 tc_check_label (line_label);
+#endif
                  /* Input_line_pointer->after ':'.  */
                  SKIP_WHITESPACE ();
                }
@@ -739,8 +746,7 @@ read_a_source_file (name)
 
                    while (*s2)
                      {
-                       if (isupper ((unsigned char) *s2))
-                         *s2 = tolower (*s2);
+                       *s2 = TOLOWER (*s2);
                        s2++;
                      }
                  }
@@ -864,7 +870,7 @@ read_a_source_file (name)
                          const char *err;
                          macro_entry *macro;
 
-                         if (check_macro (s, &out, '\0', &err, &macro))
+                         if (check_macro (s, &out, &err, &macro))
                            {
                              if (err != NULL)
                                as_bad ("%s", err);
@@ -907,8 +913,7 @@ read_a_source_file (name)
          if (is_end_of_line[(unsigned char) c])
            continue;
 
-         if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB)
-             && isdigit ((unsigned char) c))
+         if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB) && ISDIGIT (c))
            {
              /* local label  ("4:")  */
              char *backup = input_line_pointer;
@@ -918,7 +923,7 @@ read_a_source_file (name)
              temp = c - '0';
 
              /* Read the whole number.  */
-             while (isdigit ((unsigned char) *input_line_pointer))
+             while (ISDIGIT (*input_line_pointer))
                {
                  temp = (temp * 10) + *input_line_pointer - '0';
                  ++input_line_pointer;
@@ -953,6 +958,7 @@ read_a_source_file (name)
 
          if (c && strchr (line_comment_chars, c))
            {                   /* Its a comment.  Better say APP or NO_APP.  */
+             sb sbuf;
              char *ends;
              char *new_buf;
              char *new_tmp;
@@ -965,6 +971,7 @@ read_a_source_file (name)
                continue;       /* We ignore it */
              s += 4;
 
+             sb_new (&sbuf);
              ends = strstr (s, "#NO_APP\n");
 
              if (!ends)
@@ -1026,7 +1033,7 @@ read_a_source_file (name)
 
                  if (size < space)
                    {
-                     new_tmp += size;
+                     new_tmp[size] = 0;
                      break;
                    }
 
@@ -1037,13 +1044,19 @@ read_a_source_file (name)
 
              if (tmp_buf)
                free (tmp_buf);
-             old_buffer = buffer;
-             old_input = input_line_pointer;
-             old_limit = buffer_limit;
-             buffer = new_buf;
-             input_line_pointer = new_buf;
-             buffer_limit = new_tmp;
 
+             /* We've "scrubbed" input to the preferred format.  In the
+                process we may have consumed the whole of the remaining
+                file (and included files).  We handle this formatted
+                input similar to that of macro expansion, letting
+                actual macro expansion (possibly nested) and other
+                input expansion work.  Beware that in messages, line
+                numbers and possibly file names will be incorrect.  */
+             sb_add_string (&sbuf, new_buf);
+             input_scrub_include_sb (&sbuf, input_line_pointer, 0);
+             sb_kill (&sbuf);
+             buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+             free (new_buf);
              continue;
            }
 
@@ -1061,20 +1074,6 @@ read_a_source_file (name)
 #ifdef md_after_pass_hook
       md_after_pass_hook ();
 #endif
-
-      if (old_buffer)
-       {
-         free (buffer);
-         bump_line_counters ();
-         if (old_input != 0)
-           {
-             buffer = old_buffer;
-             input_line_pointer = old_input;
-             buffer_limit = old_limit;
-             old_buffer = 0;
-             goto contin;
-           }
-       }
     }
 
  quit:
@@ -1166,6 +1165,19 @@ do_align (n, fill, len, max)
      int len;
      int max;
 {
+  if (now_seg == absolute_section)
+    {
+      if (fill != NULL)
+       while (len-- > 0)
+         if (*fill++ != '\0')
+           {
+             as_warn (_("ignoring fill value in absolute section"));
+             break;
+           }
+      fill = NULL;
+      len = 0;
+    }
+
 #ifdef md_do_align
   md_do_align (n, fill, len, max, just_record_alignment);
 #endif
@@ -1187,7 +1199,7 @@ do_align (n, fill, len, max)
     }
 
 #ifdef md_do_align
- just_record_alignment:
+ just_record_alignment: ATTRIBUTE_UNUSED_LABEL
 #endif
 
   record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
@@ -1377,7 +1389,8 @@ s_comm (ignore)
 
   if ((temp = get_absolute_expression ()) < 0)
     {
-      as_warn (_(".COMMon length (%ld) < 0 ignored"), (long) temp);
+      as_warn (_(".COMMon length (%lu) out of range ignored"),
+              (unsigned long) temp);
       ignore_rest_of_line ();
       if (flag_mri)
        mri_comment_end (stop, stopc);
@@ -1453,7 +1466,7 @@ s_mri_common (small)
   SKIP_WHITESPACE ();
 
   name = input_line_pointer;
-  if (!isdigit ((unsigned char) *name))
+  if (!ISDIGIT (*name))
     c = get_symbol_end ();
   else
     {
@@ -1461,7 +1474,7 @@ s_mri_common (small)
        {
          ++input_line_pointer;
        }
-      while (isdigit ((unsigned char) *input_line_pointer));
+      while (ISDIGIT (*input_line_pointer));
 
       c = *input_line_pointer;
       *input_line_pointer = '\0';
@@ -1561,6 +1574,20 @@ s_data (ignore)
    definition for .file; the APPFILE argument is 1 for .appfile, 0 for
    .file.  */
 
+void
+s_app_file_string (file)
+     char *file;
+{
+#ifdef LISTING
+  if (listing)
+    listing_source_file (file);
+#endif
+  register_dependency (file);
+#ifdef obj_app_file
+  obj_app_file (file);
+#endif
+}
+
 void
 s_app_file (appfile)
      int appfile;
@@ -1586,16 +1613,7 @@ s_app_file (appfile)
 
       demand_empty_rest_of_line ();
       if (!may_omit)
-       {
-#ifdef LISTING
-         if (listing)
-           listing_source_file (s);
-#endif
-         register_dependency (s);
-#ifdef obj_app_file
-         obj_app_file (s);
-#endif
-       }
+       s_app_file_string (s);
     }
 }
 
@@ -1840,7 +1858,7 @@ s_irp (irpc)
 
   sb_new (&out);
 
-  err = expand_irp (irpc, 0, &s, &out, get_line_sb, '\0');
+  err = expand_irp (irpc, 0, &s, &out, get_line_sb);
   if (err != NULL)
     as_bad_where (file, line, "%s", err);
 
@@ -1988,7 +2006,7 @@ s_lcomm_internal (needs_align, bytes_p)
       || OUTPUT_FLAVOR == bfd_target_elf_flavour)
     {
       /* For MIPS and Alpha ECOFF or ELF, small objects are put in .sbss.  */
-      if (temp <= bfd_get_gp_size (stdoutput))
+      if ((unsigned) temp <= bfd_get_gp_size (stdoutput))
        {
          bss_seg = subseg_new (".sbss", 1);
          seg_info (bss_seg)->bss = 1;
@@ -2220,13 +2238,15 @@ s_lsym (ignore)
   demand_empty_rest_of_line ();
 }
 
-/* Read a line into an sb.  */
+/* Read a line into an sb.  Returns the character that ended the line
+   or zero if there are no more lines.  */
 
 static int
 get_line_sb (line)
      sb *line;
 {
   char quote1, quote2, inquote;
+  unsigned char c;
 
   if (input_line_pointer[-1] == '\n')
     bump_line_counters ();
@@ -2254,35 +2274,32 @@ get_line_sb (line)
 
   inquote = '\0';
 
-  while (!is_end_of_line[(unsigned char) *input_line_pointer]
-        || (inquote != '\0' && *input_line_pointer != '\n'))
+  while ((c = * input_line_pointer ++) != 0
+        && (!is_end_of_line[c]
+            || (inquote != '\0' && c != '\n')))
     {
-      if (inquote == *input_line_pointer)
+      if (inquote == c)
        inquote = '\0';
       else if (inquote == '\0')
        {
-         if (*input_line_pointer == quote1)
+         if (c == quote1)
            inquote = quote1;
-         else if (*input_line_pointer == quote2)
+         else if (c == quote2)
            inquote = quote2;
        }
 
-      sb_add_char (line, *input_line_pointer++);
-    }
-
-  while (input_line_pointer < buffer_limit
-        && is_end_of_line[(unsigned char) *input_line_pointer])
-    {
-      if (input_line_pointer[-1] == '\n')
-       bump_line_counters ();
-      ++input_line_pointer;
+      sb_add_char (line, c);
     }
 
-  return 1;
+  /* Don't skip multiple end-of-line characters, because that breaks support
+     for the IA-64 stop bit (;;) which looks like two consecutive end-of-line
+     characters but isn't.  Instead just skip one end of line character and
+     return the character skipped so that the caller can re-insert it if
+     necessary.   */
+  return c;
 }
 
-/* Define a macro.  This is an interface to macro.c, which is shared
-   between gas and gasp.  */
+/* Define a macro.  This is an interface to macro.c.  */
 
 void
 s_macro (ignore)
@@ -2488,7 +2505,7 @@ s_mri_sect (type)
   SKIP_WHITESPACE ();
 
   name = input_line_pointer;
-  if (!isdigit ((unsigned char) *name))
+  if (!ISDIGIT (*name))
     c = get_symbol_end ();
   else
     {
@@ -2496,7 +2513,7 @@ s_mri_sect (type)
        {
          ++input_line_pointer;
        }
-      while (isdigit ((unsigned char) *input_line_pointer));
+      while (ISDIGIT (*input_line_pointer));
 
       c = *input_line_pointer;
       *input_line_pointer = '\0';
@@ -2521,7 +2538,7 @@ s_mri_sect (type)
   if (*input_line_pointer == ',')
     {
       c = *++input_line_pointer;
-      c = toupper ((unsigned char) c);
+      c = TOUPPER (c);
       if (c == 'C' || c == 'D' || c == 'M' || c == 'R')
        *type = c;
       else
@@ -2684,6 +2701,16 @@ s_purgem (ignore)
 
 /* Handle the .rept pseudo-op.  */
 
+void
+s_bad_endr (ignore)
+     int ignore ATTRIBUTE_UNUSED;
+{
+  as_warn (_(".endr encountered without preceeding .rept, .irc, or .irp"));
+  demand_empty_rest_of_line ();
+}
+
+/* Handle the .rept pseudo-op.  */
+
 void
 s_rept (ignore)
      int ignore ATTRIBUTE_UNUSED;
@@ -3044,7 +3071,7 @@ 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 ((unsigned char) input_line_pointer[1]))
+      && ISALPHA (input_line_pointer[1]))
     input_line_pointer += 2;
 
   /* Accept :xxxx, where the x's are hex digits, for a floating point
@@ -3141,7 +3168,7 @@ ignore_rest_of_line ()
   /* For suspect lines: gives warning.  */
   if (!is_end_of_line[(unsigned char) *input_line_pointer])
     {
-      if (isprint ((unsigned char) *input_line_pointer))
+      if (ISPRINT (*input_line_pointer))
        as_warn (_("rest of line ignored; first ignored character is `%c'"),
                 *input_line_pointer);
       else
@@ -3207,8 +3234,6 @@ pseudo_set (symbolP)
        as_bad (_("floating point number invalid"));
     }
   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))
           && (symbol_get_frag (exp.X_add_symbol)
               == symbol_get_frag (exp.X_op_symbol)))
@@ -3322,6 +3347,13 @@ parse_repeat_cons PARAMS ((expressionS *exp, unsigned int nbytes));
 #endif
 #endif
 
+void
+do_parse_cons_expression (expressionS *exp, int nbytes)
+{
+  TC_PARSE_CONS_EXPRESSION (exp, nbytes);
+}
+
+
 /* Worker to do .byte etc statements.
    Clobbers input_line_pointer and checks end-of-line.  */
 
@@ -3420,6 +3452,8 @@ emit_expr (exp, nbytes)
   if (need_pass_2)
     return;
 
+  dot_value = frag_now_fix ();
+
 #ifndef NO_LISTING
 #ifdef OBJ_ELF
   /* When gcc emits DWARF 1 debugging pseudo-ops, a line number will
@@ -3568,6 +3602,7 @@ emit_expr (exp, nbytes)
       x->sub = exp->X_op_symbol;
       x->addnum = exp->X_add_number;
       x->added = 0;
+      x->use_jump = 0;
       new_broken_words++;
       return;
     }
@@ -3663,7 +3698,7 @@ emit_expr (exp, nbytes)
            }
 
          nums = generic_bignum + size / CHARS_PER_LITTLENUM;
-         while (size > 0)
+         while (size >= CHARS_PER_LITTLENUM)
            {
              --nums;
              md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
@@ -3674,7 +3709,7 @@ emit_expr (exp, nbytes)
       else
        {
          nums = generic_bignum;
-         while (size > 0)
+         while (size >= CHARS_PER_LITTLENUM)
            {
              md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
              ++nums;
@@ -3683,7 +3718,7 @@ emit_expr (exp, nbytes)
              nbytes -= CHARS_PER_LITTLENUM;
            }
 
-         while (nbytes > 0)
+         while (nbytes >= CHARS_PER_LITTLENUM)
            {
              md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM);
              nbytes -= CHARS_PER_LITTLENUM;
@@ -4130,7 +4165,7 @@ 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 ((unsigned char) input_line_pointer[1]))
+         && ISALPHA (input_line_pointer[1]))
        input_line_pointer += 2;
 
       /* Accept :xxxx, where the x's are hex digits, for a floating
@@ -4539,6 +4574,15 @@ stringer (append_zero)           /* Worker to do .ascii etc statements.  */
     {
       c = ',';                 /* Do loop.  */
     }
+  /* If we have been switched into the abs_section then we
+     will not have an obstack onto which we can hang strings.  */
+  if (now_seg == absolute_section)
+    {
+      as_bad (_("strings must be placed into a section"));
+      c = 0;
+      ignore_rest_of_line ();
+    }
+  
   while (c == ',' || c == '<' || c == '"')
     {
       SKIP_WHITESPACE ();
@@ -4668,7 +4712,7 @@ next_char_of_string ()
            int i;
 
            for (i = 0, number = 0;
-                isdigit (c) && i < 3;
+                ISDIGIT (c) && i < 3;
                 c = *input_line_pointer++, i++)
              {
                number = number * 8 + c - '0';
@@ -4686,11 +4730,11 @@ next_char_of_string ()
 
            number = 0;
            c = *input_line_pointer++;
-           while (isxdigit (c))
+           while (ISXDIGIT (c))
              {
-               if (isdigit (c))
+               if (ISDIGIT (c))
                  number = number * 16 + c - '0';
-               else if (isupper (c))
+               else if (ISUPPER (c))
                  number = number * 16 + c - 'A' + 10;
                else
                  number = number * 16 + c - 'a' + 10;
@@ -4770,18 +4814,25 @@ get_known_segmented_expression (expP)
 }
 
 offsetT
-get_absolute_expression ()
+get_absolute_expr (exp)
+     expressionS *exp;
 {
-  expressionS exp;
-
-  expression (&exp);
-  if (exp.X_op != O_constant)
+  expression (exp);
+  if (exp->X_op != O_constant)
     {
-      if (exp.X_op != O_absent)
+      if (exp->X_op != O_absent)
        as_bad (_("bad or irreducible absolute expression"));
-      exp.X_add_number = 0;
+      exp->X_add_number = 0;
     }
-  return exp.X_add_number;
+  return exp->X_add_number;
+}
+
+offsetT
+get_absolute_expression ()
+{
+  expressionS exp;
+
+  return get_absolute_expr (&exp);
 }
 
 char                           /* Return terminator.  */
This page took 0.030517 seconds and 4 git commands to generate.