Add support for ColdFire MAC instructions and tidy up support for other m68k
[deliverable/binutils-gdb.git] / gas / stabs.c
index 11d4655f36fa95f465131dd1a97e05f9ccf01193..f8acdc8425754a349f987ca4036be0c863e6408f 100644 (file)
@@ -1,5 +1,5 @@
 /* Generic stabs parsing for gas.
 /* Generic stabs parsing for gas.
-   Copyright (C) 1989, 90, 91, 93, 94, 95, 96, 97, 98, 1999
+   Copyright 1989, 1990, 1991, 1993, 1995, 1996, 1997, 1998, 2000, 2001
    Free Software Foundation, Inc.
 
 This file is part of GAS, the GNU Assembler.
    Free Software Foundation, Inc.
 
 This file is part of GAS, the GNU Assembler.
@@ -17,7 +17,7 @@ the GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with GAS; see the file COPYING.  If not, write to the Free
 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 You should have received a copy of the GNU General Public License
 along with GAS; see the file COPYING.  If not, write to the Free
 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+02111-1307, USA.  */
 
 #include "as.h"
 #include "obstack.h"
 
 #include "as.h"
 #include "obstack.h"
@@ -25,12 +25,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "ecoff.h"
 
 /* We need this, despite the apparent object format dependency, since
 #include "ecoff.h"
 
 /* We need this, despite the apparent object format dependency, since
-   it defines stab types, which all object formats can use now. */
+   it defines stab types, which all object formats can use now.  */
 
 #include "aout/stab_gnu.h"
 
 
 #include "aout/stab_gnu.h"
 
-static void s_stab_generic PARAMS ((int, char *, char *));
-static void generate_asm_file PARAMS ((int, char *));
+/* Holds whether the assembler is generating stabs line debugging
+   information or not.  Potentially used by md_cleanup function.  */
+
+int outputting_stabs_line_debug = 0;
+
+static void s_stab_generic (int, char *, char *);
+static void generate_asm_file (int, char *);
 
 /* Allow backends to override the names used for the stab sections.  */
 #ifndef STAB_SECTION_NAME
 
 /* Allow backends to override the names used for the stab sections.  */
 #ifndef STAB_SECTION_NAME
@@ -75,9 +80,7 @@ static const char *current_function_label;
 #endif
 
 unsigned int
 #endif
 
 unsigned int
-get_stab_string_offset (string, stabstr_secname)
-     const char *string;
-     const char *stabstr_secname;
+get_stab_string_offset (const char *string, const char *stabstr_secname)
 {
   unsigned int length;
   unsigned int retval;
 {
   unsigned int length;
   unsigned int retval;
@@ -112,7 +115,7 @@ get_stab_string_offset (string, stabstr_secname)
     }
 
   if (length > 0)
     }
 
   if (length > 0)
-    {                          /* Ordinary case. */
+    {                          /* Ordinary case.  */
       p = frag_more (length + 1);
       strcpy (p, string);
 
       p = frag_more (length + 1);
       strcpy (p, string);
 
@@ -131,9 +134,8 @@ get_stab_string_offset (string, stabstr_secname)
 #define OBJ_PROCESS_STAB(SEG,W,S,T,O,D)        aout_process_stab(W,S,T,O,D)
 #endif
 
 #define OBJ_PROCESS_STAB(SEG,W,S,T,O,D)        aout_process_stab(W,S,T,O,D)
 #endif
 
-static void aout_process_stab PARAMS ((int, const char *, int, int, int));
-
-static void
+/* Here instead of obj-aout.c because other formats use it too.  */
+void
 aout_process_stab (what, string, type, other, desc)
      int what;
      const char *string;
 aout_process_stab (what, string, type, other, desc)
      int what;
      const char *string;
@@ -172,16 +174,13 @@ aout_process_stab (what, string, type, other, desc)
 #endif
 
 /* This can handle different kinds of stabs (s,n,d) and different
 #endif
 
 /* This can handle different kinds of stabs (s,n,d) and different
-   kinds of stab sections. */
+   kinds of stab sections.  */
 
 
-static void 
-s_stab_generic (what, stab_secname, stabstr_secname)
-     int what;
-     char *stab_secname;
-     char *stabstr_secname;
+static void
+s_stab_generic (int what, char *stab_secname, char *stabstr_secname)
 {
   long longint;
 {
   long longint;
-  char *string;
+  char *string, *saved_string_obstack_end;
   int type;
   int other;
   int desc;
   int type;
   int other;
   int desc;
@@ -195,18 +194,25 @@ s_stab_generic (what, stab_secname, stabstr_secname)
      'd' indicating which type of .stab this is.  */
 
   if (what != 's')
      'd' indicating which type of .stab this is.  */
 
   if (what != 's')
-    string = "";
+    {
+      string = "";
+      saved_string_obstack_end = 0;
+    }
   else
     {
       int length;
 
       string = demand_copy_C_string (&length);
   else
     {
       int length;
 
       string = demand_copy_C_string (&length);
+      /* FIXME: We should probably find some other temporary storage
+        for string, rather than leaking memory if someone else
+        happens to use the notes obstack.  */
+      saved_string_obstack_end = notes.next_free;
       SKIP_WHITESPACE ();
       if (*input_line_pointer == ',')
        input_line_pointer++;
       else
        {
       SKIP_WHITESPACE ();
       if (*input_line_pointer == ',')
        input_line_pointer++;
       else
        {
-         as_warn (_(".stabs: Missing comma"));
+         as_warn (_(".stab%c: missing comma"), what);
          ignore_rest_of_line ();
          return;
        }
          ignore_rest_of_line ();
          return;
        }
@@ -214,7 +220,7 @@ s_stab_generic (what, stab_secname, stabstr_secname)
 
   if (get_absolute_expression_and_terminator (&longint) != ',')
     {
 
   if (get_absolute_expression_and_terminator (&longint) != ',')
     {
-      as_warn (_(".stab%c: Missing comma"), what);
+      as_warn (_(".stab%c: missing comma"), what);
       ignore_rest_of_line ();
       return;
     }
       ignore_rest_of_line ();
       return;
     }
@@ -222,18 +228,26 @@ s_stab_generic (what, stab_secname, stabstr_secname)
 
   if (get_absolute_expression_and_terminator (&longint) != ',')
     {
 
   if (get_absolute_expression_and_terminator (&longint) != ',')
     {
-      as_warn (_(".stab%c: Missing comma"), what);
+      as_warn (_(".stab%c: missing comma"), what);
       ignore_rest_of_line ();
       return;
     }
   other = longint;
 
   desc = get_absolute_expression ();
       ignore_rest_of_line ();
       return;
     }
   other = longint;
 
   desc = get_absolute_expression ();
+
+  if ((desc > 0xffff) || (desc < -0x8000))
+    /* This could happen for example with a source file with a huge
+       number of lines.  The only cure is to use a different debug
+       format, probably DWARF.  */
+    as_warn (_(".stab%c: description field '%x' too big, try a different debug format"),
+            what, desc);
+
   if (what == 's' || what == 'n')
     {
       if (*input_line_pointer != ',')
        {
   if (what == 's' || what == 'n')
     {
       if (*input_line_pointer != ',')
        {
-         as_warn (_(".stab%c: Missing comma"), what);
+         as_warn (_(".stab%c: missing comma"), what);
          ignore_rest_of_line ();
          return;
        }
          ignore_rest_of_line ();
          return;
        }
@@ -331,8 +345,9 @@ s_stab_generic (what, stab_secname, stabstr_secname)
       stroff = get_stab_string_offset (string, stabstr_secname);
       if (what == 's')
        {
       stroff = get_stab_string_offset (string, stabstr_secname);
       if (what == 's')
        {
-         /* release the string */
-         obstack_free (&notes, string);
+         /* Release the string, if nobody else has used the obstack.  */
+         if (saved_string_obstack_end == notes.next_free)
+           obstack_free (&notes, string);
        }
 
       /* At least for now, stabs in a special stab section are always
        }
 
       /* At least for now, stabs in a special stab section are always
@@ -351,13 +366,11 @@ s_stab_generic (what, stab_secname, stabstr_secname)
        }
       else
        {
        }
       else
        {
-         const char *fake;
          symbolS *symbol;
          expressionS exp;
 
          /* Arrange for a value representing the current location.  */
          symbolS *symbol;
          expressionS exp;
 
          /* Arrange for a value representing the current location.  */
-         fake = FAKE_LABEL_NAME;
-         symbol = symbol_new (fake, saved_seg, dot, saved_frag);
+         symbol = symbol_temp_new (saved_seg, dot, saved_frag);
 
          exp.X_op = O_symbol;
          exp.X_add_symbol = symbol;
 
          exp.X_op = O_symbol;
          exp.X_add_symbol = symbol;
@@ -384,20 +397,18 @@ s_stab_generic (what, stab_secname, stabstr_secname)
   demand_empty_rest_of_line ();
 }
 
   demand_empty_rest_of_line ();
 }
 
-/* Regular stab directive. */
+/* Regular stab directive.  */
 
 void
 
 void
-s_stab (what)
-     int what;
+s_stab (int what)
 {
   s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME);
 }
 
 {
   s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME);
 }
 
-/* "Extended stabs", used in Solaris only now. */
+/* "Extended stabs", used in Solaris only now.  */
 
 void
 
 void
-s_xstab (what)
-     int what;
+s_xstab (int what)
 {
   int length;
   char *stab_secname, *stabstr_secname;
 {
   int length;
   char *stab_secname, *stabstr_secname;
@@ -439,9 +450,9 @@ s_xstab (what)
 
 /* Frob invented at RMS' request. Set the n_desc of a symbol.  */
 
 
 /* Frob invented at RMS' request. Set the n_desc of a symbol.  */
 
-void 
+void
 s_desc (ignore)
 s_desc (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   char *name;
   char c;
 {
   char *name;
   char c;
@@ -457,7 +468,7 @@ s_desc (ignore)
   if (*input_line_pointer != ',')
     {
       *p = 0;
   if (*input_line_pointer != ',')
     {
       *p = 0;
-      as_bad (_("Expected comma after name \"%s\""), name);
+      as_bad (_("expected comma after \"%s\""), name);
       *p = c;
       ignore_rest_of_line ();
     }
       *p = c;
       ignore_rest_of_line ();
     }
@@ -478,12 +489,21 @@ s_desc (ignore)
 /* Generate stabs debugging information to denote the main source file.  */
 
 void
 /* Generate stabs debugging information to denote the main source file.  */
 
 void
-stabs_generate_asm_file ()
+stabs_generate_asm_file (void)
 {
   char *file;
   unsigned int lineno;
 
   as_where (&file, &lineno);
 {
   char *file;
   unsigned int lineno;
 
   as_where (&file, &lineno);
+  if (use_gnu_debug_info_extensions)
+    {
+      char *dir, *dir2;
+
+      dir = getpwd ();
+      dir2 = alloca (strlen (dir) + 2);
+      sprintf (dir2, "%s%s", dir, "/");
+      generate_asm_file (N_SO, dir2);
+    }
   generate_asm_file (N_SO, file);
 }
 
   generate_asm_file (N_SO, file);
 }
 
@@ -491,39 +511,66 @@ stabs_generate_asm_file ()
    TYPE is one of N_SO, N_SOL.  */
 
 static void
    TYPE is one of N_SO, N_SOL.  */
 
 static void
-generate_asm_file (type, file)
-     int type;
-     char *file;
+generate_asm_file (int type, char *file)
 {
   static char *last_file;
   static int label_count;
   char *hold;
 {
   static char *last_file;
   static int label_count;
   char *hold;
-  char buf[100];
   char sym[30];
   char sym[30];
+  char *buf;
+  char *tmp = file;
+  char *endp = file + strlen (file);
+  char *bufp;
+
+  if (last_file != NULL
+      && strcmp (last_file, file) == 0)
+    return;
 
   /* Rather than try to do this in some efficient fashion, we just
      generate a string and then parse it again.  That lets us use the
      existing stabs hook, which expect to see a string, rather than
      inventing new ones.  */
 
   /* Rather than try to do this in some efficient fashion, we just
      generate a string and then parse it again.  That lets us use the
      existing stabs hook, which expect to see a string, rather than
      inventing new ones.  */
-
   hold = input_line_pointer;
 
   hold = input_line_pointer;
 
-  if (last_file == NULL
-      || strcmp (last_file, file) != 0)
+  sprintf (sym, "%sF%d", FAKE_LABEL_NAME, label_count);
+  ++label_count;
+
+  /* Allocate enough space for the file name (possibly extended with
+     doubled up backslashes), the symbol name, and the other characters
+     that make up a stabs file directive.  */
+  bufp = buf = xmalloc (2 * strlen (file) + strlen (sym) + 12);
+
+  *bufp++ = '"';
+
+  while (tmp < endp)
     {
     {
-      sprintf (sym, "%sF%d", FAKE_LABEL_NAME, label_count);
-      ++label_count;
+      char *bslash = strchr (tmp, '\\');
+      size_t len = (bslash) ? (size_t) (bslash - tmp + 1) : strlen (tmp);
 
 
-      sprintf (buf, "\"%s\",%d,0,0,%s\n", file, type, sym);
-      input_line_pointer = buf;
-      s_stab ('s');
-      colon (sym);
+      /* Double all backslashes, since demand_copy_C_string (used by
+        s_stab to extract the part in quotes) will try to replace them as
+        escape sequences.  backslash may appear in a filespec.  */
+      strncpy (bufp, tmp, len);
+
+      tmp += len;
+      bufp += len;
 
 
-      if (last_file != NULL)
-       free (last_file);
-      last_file = xstrdup (file);
+      if (bslash != NULL)
+       *bufp++ = '\\';
     }
 
     }
 
+  sprintf (bufp, "\",%d,0,0,%s\n", type, sym);
+
+  input_line_pointer = buf;
+  s_stab ('s');
+  colon (sym);
+
+  if (last_file != NULL)
+    free (last_file);
+  last_file = xstrdup (file);
+
+  free (buf);
+
   input_line_pointer = hold;
 }
 
   input_line_pointer = hold;
 }
 
@@ -531,7 +578,7 @@ generate_asm_file (type, file)
    used to produce debugging information for an assembler file.  */
 
 void
    used to produce debugging information for an assembler file.  */
 
 void
-stabs_generate_asm_lineno ()
+stabs_generate_asm_lineno (void)
 {
   static int label_count;
   char *hold;
 {
   static int label_count;
   char *hold;
@@ -539,6 +586,9 @@ stabs_generate_asm_lineno ()
   unsigned int lineno;
   char *buf;
   char sym[30];
   unsigned int lineno;
   char *buf;
   char sym[30];
+  /* Remember the last file/line and avoid duplicates.  */
+  static unsigned int prev_lineno = -1;
+  static char *prev_file = NULL;
 
   /* Rather than try to do this in some efficient fashion, we just
      generate a string and then parse it again.  That lets us use the
 
   /* Rather than try to do this in some efficient fashion, we just
      generate a string and then parse it again.  That lets us use the
@@ -549,6 +599,34 @@ stabs_generate_asm_lineno ()
 
   as_where (&file, &lineno);
 
 
   as_where (&file, &lineno);
 
+  /* Don't emit sequences of stabs for the same line.  */
+  if (prev_file == NULL)
+    {
+      /* First time thru.  */
+      prev_file = xstrdup (file);
+      prev_lineno = lineno;
+    }
+  else if (lineno == prev_lineno
+          && strcmp (file, prev_file) == 0)
+    {
+      /* Same file/line as last time.  */
+      return;
+    }
+  else
+    {
+      /* Remember file/line for next time.  */
+      prev_lineno = lineno;
+      if (strcmp (file, prev_file) != 0)
+       {
+         free (prev_file);
+         prev_file = xstrdup (file);
+       }
+    }
+
+  /* Let the world know that we are in the middle of generating a
+     piece of stabs line debugging information.  */
+  outputting_stabs_line_debug = 1;
+
   generate_asm_file (N_SOL, file);
 
   sprintf (sym, "%sL%d", FAKE_LABEL_NAME, label_count);
   generate_asm_file (N_SOL, file);
 
   sprintf (sym, "%sL%d", FAKE_LABEL_NAME, label_count);
@@ -570,15 +648,14 @@ stabs_generate_asm_lineno ()
   colon (sym);
 
   input_line_pointer = hold;
   colon (sym);
 
   input_line_pointer = hold;
+  outputting_stabs_line_debug = 0;
 }
 
 /* Emit a function stab.
    All assembler functions are assumed to have return type `void'.  */
 
 void
 }
 
 /* Emit a function stab.
    All assembler functions are assumed to have return type `void'.  */
 
 void
-stabs_generate_asm_func (funcname, startlabname)
-     const char *funcname;
-     const char *startlabname;
+stabs_generate_asm_func (const char *funcname, const char *startlabname)
 {
   static int void_emitted_p;
   char *hold = input_line_pointer;
 {
   static int void_emitted_p;
   char *hold = input_line_pointer;
@@ -608,9 +685,8 @@ stabs_generate_asm_func (funcname, startlabname)
 /* Emit a stab to record the end of a function.  */
 
 void
 /* Emit a stab to record the end of a function.  */
 
 void
-stabs_generate_asm_endfunc (funcname, startlabname)
-     const char *funcname;
-     const char *startlabname;
+stabs_generate_asm_endfunc (const char *funcname ATTRIBUTE_UNUSED,
+                           const char *startlabname)
 {
   static int label_count;
   char *hold = input_line_pointer;
 {
   static int label_count;
   char *hold = input_line_pointer;
This page took 0.027366 seconds and 4 git commands to generate.