* ldlang.c (lang_add_section): Discard debugging sections that have
[deliverable/binutils-gdb.git] / binutils / wrstabs.c
index 985b7009632000809f06ddabb07e3b5c866cb4e0..5d0dc3bd30dd29a0054cd4a85116319c6ee167ec 100644 (file)
@@ -1,5 +1,5 @@
 /* wrstabs.c -- Output stabs debugging information
-   Copyright (C) 1996 Free Software Foundation, Inc.
+   Copyright 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GNU Binutils.
    information.  */
 
 #include <stdio.h>
-#include <ctype.h>
 #include <assert.h>
 
 #include "bfd.h"
 #include "bucomm.h"
 #include "libiberty.h"
+#include "safe-ctype.h"
 #include "debug.h"
 #include "budbg.h"
 
@@ -47,6 +47,8 @@
 struct string_hash_entry
 {
   struct bfd_hash_entry root;
+  /* Next string in this table.  */
+  struct string_hash_entry *next;
   /* Index in string table.  */
   long index;
   /* Size of type if this is a typedef.  */
@@ -139,10 +141,12 @@ struct stab_write_handle
   bfd_byte *symbols;
   size_t symbols_size;
   size_t symbols_alloc;
-  /* This buffer holds the strings.  */
-  bfd_byte *strings;
+  /* This is a list of hash table entries for the strings.  */
+  struct string_hash_entry *strings;
+  /* The last string hash table entry.  */
+  struct string_hash_entry *last_string;
+  /* The size of the strings.  */
   size_t strings_size;
-  size_t strings_alloc;
   /* This hash table eliminates duplicate strings.  */
   struct string_hash_table strhash;
   /* The type stack.  */
@@ -323,6 +327,7 @@ string_hash_newfunc (entry, table, string)
   if (ret)
     {
       /* Initialize the local fields.  */
+      ret->next = NULL;
       ret->index = -1;
       ret->size = 0;
     }
@@ -355,31 +360,25 @@ stab_write_symbol (info, type, desc, value, string)
     {
       struct string_hash_entry *h;
 
-      h = string_hash_lookup (&info->strhash, string, true, false);
+      h = string_hash_lookup (&info->strhash, string, true, true);
       if (h == NULL)
        {
-         fprintf (stderr, "string_hash_lookup failed: %s\n",
-                  bfd_errmsg (bfd_get_error ()));
+         non_fatal (_("string_hash_lookup failed: %s"),
+                    bfd_errmsg (bfd_get_error ()));
          return false;
        }
       if (h->index != -1)
        strx = h->index;
       else
        {
-         size_t len;
-
          strx = info->strings_size;
          h->index = strx;
-
-         len = strlen (string);
-         while (info->strings_size + len + 1 > info->strings_alloc)
-           {
-             info->strings_alloc *= 2;
-             info->strings = (bfd_byte *) xrealloc (info->strings,
-                                                    info->strings_alloc);
-           }
-         strcpy (info->strings + info->strings_size, string);
-         info->strings_size += len + 1;
+         if (info->last_string == NULL)
+           info->strings = h;
+         else
+           info->last_string->next = h;
+         info->last_string = h;
+         info->strings_size += strlen (string) + 1;
        }
     }
 
@@ -489,6 +488,8 @@ write_stabs_in_sections_debugging_info (abfd, dhandle, psyms, psymsize,
      bfd_size_type *pstringsize;
 {
   struct stab_write_handle info;
+  struct string_hash_entry *h;
+  bfd_byte *p;
 
   info.abfd = abfd;
 
@@ -496,16 +497,16 @@ write_stabs_in_sections_debugging_info (abfd, dhandle, psyms, psymsize,
   info.symbols_alloc = 500;
   info.symbols = (bfd_byte *) xmalloc (info.symbols_alloc);
 
+  info.strings = NULL;
+  info.last_string = NULL;
+  /* Reserve 1 byte for a null byte.  */
   info.strings_size = 1;
-  info.strings_alloc = 500;
-  info.strings = (bfd_byte *) xmalloc (info.strings_alloc);
-  info.strings[0] = '\0';
 
   if (! bfd_hash_table_init (&info.strhash.table, string_hash_newfunc)
       || ! bfd_hash_table_init (&info.typedef_hash.table, string_hash_newfunc))
     {
-      fprintf (stderr, "bfd_hash_table_init_failed: %s\n",
-              bfd_errmsg (bfd_get_error ()));
+      non_fatal ("bfd_hash_table_init_failed: %s",
+                bfd_errmsg (bfd_get_error ()));
       return false;
     }
 
@@ -544,8 +545,16 @@ write_stabs_in_sections_debugging_info (abfd, dhandle, psyms, psymsize,
   *psyms = info.symbols;
   *psymsize = info.symbols_size;
 
-  *pstrings = info.strings;
   *pstringsize = info.strings_size;
+  *pstrings = (bfd_byte *) xmalloc (info.strings_size);
+
+  p = *pstrings;
+  *p++ = '\0';
+  for (h = info.strings; h != NULL; h = h->next)
+    {
+      strcpy ((char *) p, h->root.string);
+      p += strlen ((char *) p) + 1;
+    }
 
   return true;
 }
@@ -654,7 +663,7 @@ stab_int_type (p, size, unsignedp)
 
   if (size <= 0 || (size > sizeof (long) && size != 8))
     {
-      fprintf (stderr, "stab_int_type: bad size %u\n", size);
+      non_fatal (_("stab_int_type: bad size %u"), size);
       return false;
     }
 
@@ -786,7 +795,7 @@ stab_bool_type (p, size)
     case 2:
       index = -22;
       break;
-      
+
     default:
     case 4:
       index = -16;
@@ -835,6 +844,8 @@ stab_enum_type (p, tag, names, vals)
   for (pn = names; *pn != NULL; pn++)
     len += strlen (*pn) + 20;
 
+  buf = (char *) xmalloc (len);
+
   if (tag == NULL)
     strcpy (buf, "e");
   else
@@ -844,7 +855,6 @@ stab_enum_type (p, tag, names, vals)
       sprintf (buf, "%s:T%ld=e", tag, index);
     }
 
-  buf = (char *) xmalloc (len);
   for (pn = names, pv = vals; *pn != NULL; pn++, pv++)
     sprintf (buf + strlen (buf), "%s:%ld,", *pn, (long) *pv);
   strcat (buf, ";");
@@ -905,14 +915,14 @@ stab_modify_type (info, mod, size, cache, cache_alloc)
     }
   else
     {
-      if (targindex >= *cache_alloc)
+      if ((size_t) targindex >= *cache_alloc)
        {
          size_t alloc;
 
          alloc = *cache_alloc;
          if (alloc == 0)
            alloc = 10;
-         while (targindex >= alloc)
+         while ((size_t) targindex >= alloc)
            alloc *= 2;
          *cache = (long *) xrealloc (*cache, alloc * sizeof (long));
          memset (*cache + *cache_alloc, 0,
@@ -921,12 +931,14 @@ stab_modify_type (info, mod, size, cache, cache_alloc)
        }
 
       index = (*cache)[targindex];
-      if (index != 0)
+      if (index != 0 && ! info->type_stack->definition)
        {
-         /* If we have already defined a modification of this type,
-             then the entry on the type stack can not be a definition,
-             so we can safely discard it.  */
-         assert (! info->type_stack->definition);
+         /* We have already defined a modification of this type, and
+             the entry on the type stack is not a definition, so we
+             can safely discard it (we may have a definition on the
+             stack, even if we already defined a modification, if it
+             is a struct which we did not define at the time it was
+             referenced).  */
          free (stab_pop_type (info));
          if (! stab_push_defined_type (info, index, size))
            return false;
@@ -951,7 +963,7 @@ stab_modify_type (info, mod, size, cache, cache_alloc)
     }
 
   return true;
-}  
+}
 
 /* Push a pointer type.  */
 
@@ -972,14 +984,14 @@ static boolean
 stab_function_type (p, argcount, varargs)
      PTR p;
      int argcount;
-     boolean varargs;
+     boolean varargs ATTRIBUTE_UNUSED;
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
   int i;
 
   /* We have no way to represent the argument types, so we just
      discard them.  However, if they define new types, we must output
-     them.  We do this by producing meaningless typedefs.  */
+     them.  We do this by producing empty typedefs.  */
   for (i = 0; i < argcount; i++)
     {
       if (! info->type_stack->definition)
@@ -987,15 +999,11 @@ stab_function_type (p, argcount, varargs)
       else
        {
          char *s, *buf;
-         long index;
 
          s = stab_pop_type (info);
 
-         buf = (char *) xmalloc (strlen (s) + 40);
-         index = info->type_index;
-         ++info->type_index;
-         sprintf (buf, "__fake_type_%ld:t%s", index, s);
-
+         buf = (char *) xmalloc (strlen (s) + 3);
+         sprintf (buf, ":t%s", s);
          free (s);
 
          if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
@@ -1091,11 +1099,12 @@ stab_array_type (p, low, high, stringp)
       sprintf (buf, "%ld=@S;", index);
     }
 
-  sprintf (buf + strlen (buf), "ar%s;%ld;%ld;%s", range, low, high, element);
+  sprintf (buf + strlen (buf), "ar%s;%ld;%ld;%s",
+          range, (long) low, (long) high, element);
   free (range);
   free (element);
 
-  if (high <= low)
+  if (high < low)
     size = 0;
   else
     size = element_size * ((high - low) + 1);
@@ -1359,7 +1368,6 @@ stab_get_struct_index (info, tag, id, kind, psize)
 /* Start outputting a struct.  We ignore the tag, and handle it in
    stab_tag.  */
 
-/*ARGSUSED*/
 static boolean
 stab_start_struct_type (p, tag, id, structp, size)
      PTR p;
@@ -1455,9 +1463,8 @@ stab_struct_field (p, name, bitpos, bitsize, visibility)
     {
       bitsize = size * 8;
       if (bitsize == 0)
-       fprintf (stderr,
-                "%s: warning: unknown size for field `%s' in struct\n",
-                bfd_get_filename (info->abfd), name);
+       non_fatal (_("%s: warning: unknown size for field `%s' in struct"),
+                  bfd_get_filename (info->abfd), name);
     }
 
   sprintf (n, "%s%s:%s%s,%ld,%ld;", info->type_stack->fields, name, vis, s,
@@ -1875,7 +1882,7 @@ stab_end_class_type (p)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
   size_t len;
-  unsigned int i;
+  unsigned int i = 0;
   char *buf;
 
   assert (info->type_stack != NULL && info->type_stack->fields != NULL);
@@ -2016,8 +2023,8 @@ stab_typdef (p, name)
   h = string_hash_lookup (&info->typedef_hash, name, true, false);
   if (h == NULL)
     {
-      fprintf (stderr, "string_hash_lookup failed: %s\n",
-              bfd_errmsg (bfd_get_error ()));
+      non_fatal (_("string_hash_lookup failed: %s"),
+                bfd_errmsg (bfd_get_error ()));
       return false;
     }
 
@@ -2164,7 +2171,7 @@ stab_variable (p, name, kind, val)
       kindstr = "";
 
       /* Make sure that this is a type reference or definition.  */
-      if (! isdigit (*s))
+      if (! ISDIGIT (*s))
        {
          char *n;
          long index;
@@ -2179,7 +2186,7 @@ stab_variable (p, name, kind, val)
       break;
 
     case DEBUG_REGISTER:
-      stab_type = N_LSYM;
+      stab_type = N_RSYM;
       kindstr = "r";
       break;
     }
@@ -2371,10 +2378,9 @@ stab_end_block (p, addr)
 
 /* End a function.  */
 
-/*ARGSUSED*/
 static boolean
 stab_end_function (p)
-     PTR p;
+     PTR p ATTRIBUTE_UNUSED;
 {
   return true;
 }
This page took 0.028012 seconds and 4 git commands to generate.