2004-01-09 Michael Chastain <mec.gnu@mindspring.com>
[deliverable/binutils-gdb.git] / gas / stabs.c
index f82b5684b65717270000f6db47d441e1d950f1e2..3d32729901ba0d8fb4fb1a164f764dac372a0c4d 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, 99, 2000
+   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.
@@ -29,8 +29,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #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;
@@ -174,13 +177,10 @@ aout_process_stab (what, string, type, other, desc)
    kinds of stab sections.  */
 
 static void
    kinds of stab sections.  */
 
 static void
-s_stab_generic (what, stab_secname, stabstr_secname)
-     int what;
-     char *stab_secname;
-     char *stabstr_secname;
+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;
@@ -194,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;
        }
@@ -213,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;
     }
@@ -221,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;
        }
@@ -330,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
@@ -350,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;
@@ -386,8 +400,7 @@ s_stab_generic (what, stab_secname, stabstr_secname)
 /* Regular stab directive.  */
 
 void
 /* Regular stab directive.  */
 
 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);
 }
@@ -395,8 +408,7 @@ s_stab (what)
 /* "Extended stabs", used in Solaris only now.  */
 
 void
 /* "Extended stabs", used in Solaris only now.  */
 
 void
-s_xstab (what)
-     int what;
+s_xstab (int what)
 {
   int length;
   char *stab_secname, *stabstr_secname;
 {
   int length;
   char *stab_secname, *stabstr_secname;
@@ -456,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 ();
     }
@@ -477,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);
 }
 
@@ -490,9 +511,7 @@ 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;
 {
   static char *last_file;
   static int label_count;
@@ -502,11 +521,11 @@ generate_asm_file (type, file)
   char *tmp = file;
   char *endp = file + strlen (file);
   char *bufp = buf;
   char *tmp = file;
   char *endp = file + strlen (file);
   char *bufp = buf;
-  
+
   if (last_file != NULL
       && strcmp (last_file, file) == 0)
     return;
   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
   /* 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
@@ -520,19 +539,19 @@ generate_asm_file (type, file)
      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);
      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)
     {
       char *bslash = strchr (tmp, '\\');
   *bufp++ = '"';
 
   while (tmp < endp)
     {
       char *bslash = strchr (tmp, '\\');
-      int len = (bslash ? (bslash - tmp + 1) : strlen (tmp));
-      
+      size_t len = (bslash) ? (size_t) (bslash - tmp + 1) : strlen (tmp);
+
       /* 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);
       /* 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;
 
       tmp += len;
       bufp += len;
 
@@ -549,7 +568,7 @@ generate_asm_file (type, file)
   if (last_file != NULL)
     free (last_file);
   last_file = xstrdup (file);
   if (last_file != NULL)
     free (last_file);
   last_file = xstrdup (file);
-  
+
   free (buf);
 
   input_line_pointer = hold;
   free (buf);
 
   input_line_pointer = hold;
@@ -559,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;
@@ -567,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
@@ -577,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);
@@ -598,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;
@@ -636,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 ATTRIBUTE_UNUSED;
-     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.032024 seconds and 4 git commands to generate.