* elf-bfd.h (_bfd_elf_create_linker_section) Don't declare.
[deliverable/binutils-gdb.git] / gas / read.c
index 80389b7a5391eafcc3b9968861905753c2a7d918..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.
 
@@ -43,9 +43,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #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.  */
@@ -168,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.  */
@@ -315,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},
@@ -454,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 ()
 {
@@ -471,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()                                  \
@@ -532,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.  */
@@ -709,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 ();
                }
@@ -861,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);
@@ -949,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;
@@ -961,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)
@@ -1022,7 +1033,7 @@ read_a_source_file (name)
 
                  if (size < space)
                    {
-                     new_tmp += size;
+                     new_tmp[size] = 0;
                      break;
                    }
 
@@ -1033,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;
            }
 
@@ -1057,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:
@@ -1162,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
@@ -1183,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);
@@ -1373,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);
@@ -1557,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;
@@ -1582,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);
     }
 }
 
@@ -1836,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);
 
@@ -2216,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 ();
@@ -2250,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++);
+      sb_add_char (line, c);
     }
 
-  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;
-    }
-
-  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)
@@ -2680,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;
@@ -3203,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)))
@@ -3318,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.  */
 
@@ -3416,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
@@ -3564,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;
     }
@@ -3659,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);
@@ -3670,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;
@@ -3679,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;
@@ -4535,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 ();
@@ -4766,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.029534 seconds and 4 git commands to generate.