[gdb/tui] Refactor prefresh call in tui_source_window_base::refresh_window
[binutils-gdb.git] / binutils / wrstabs.c
index b75d6df58450c51a63bdcf75b99e4d53b3d666b9..293189db2f8fdba6188aa684fa3f70a7df5fed1c 100644 (file)
@@ -1,13 +1,12 @@
 /* wrstabs.c -- Output stabs debugging information
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2006
-   Free Software Foundation, Inc.
+   Copyright (C) 1996-2023 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GNU Binutils.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 /* This file contains code which writes out stabs debugging
    information.  */
 
-#include <stdio.h>
+#include "sysdep.h"
 #include <assert.h>
-
 #include "bfd.h"
-#include "bucomm.h"
 #include "libiberty.h"
+#include "filenames.h"
 #include "safe-ctype.h"
+#include "bucomm.h"
 #include "debug.h"
 #include "budbg.h"
 #include "aout/aout64.h"
@@ -72,7 +71,7 @@ struct stab_type_stack
   /* The size of the type.  */
   unsigned int size;
   /* Whether type string defines a new type.  */
-  bfd_boolean definition;
+  bool definition;
   /* String defining struct fields.  */
   char *fields;
   /* NULL terminated array of strings defining base classes for a
@@ -172,81 +171,64 @@ struct stab_write_handle
   const char *lineno_filename;
 };
 
-static struct bfd_hash_entry *string_hash_newfunc
-  (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
-static bfd_boolean stab_write_symbol
-  (struct stab_write_handle *, int, int, bfd_vma, const char *);
-static bfd_boolean stab_push_string
-  (struct stab_write_handle *, const char *, long, bfd_boolean, unsigned int);
-static bfd_boolean stab_push_defined_type
-  (struct stab_write_handle *, long, unsigned int);
-static char *stab_pop_type (struct stab_write_handle *);
-static bfd_boolean stab_modify_type
-  (struct stab_write_handle *, int, unsigned int, long **, size_t *);
-static long stab_get_struct_index
-  (struct stab_write_handle *, const char *, unsigned int,
-   enum debug_type_kind, unsigned int *);
-static bfd_boolean stab_class_method_var
-  (struct stab_write_handle *, const char *, enum debug_visibility,
-   bfd_boolean, bfd_boolean, bfd_boolean, bfd_vma, bfd_boolean);
-static bfd_boolean stab_start_compilation_unit (void *, const char *);
-static bfd_boolean stab_start_source (void *, const char *);
-static bfd_boolean stab_empty_type (void *);
-static bfd_boolean stab_void_type (void *);
-static bfd_boolean stab_int_type (void *, unsigned int, bfd_boolean);
-static bfd_boolean stab_float_type (void *, unsigned int);
-static bfd_boolean stab_complex_type (void *, unsigned int);
-static bfd_boolean stab_bool_type (void *, unsigned int);
-static bfd_boolean stab_enum_type
+static bool stab_start_compilation_unit (void *, const char *);
+static bool stab_start_source (void *, const char *);
+static bool stab_empty_type (void *);
+static bool stab_void_type (void *);
+static bool stab_int_type (void *, unsigned int, bool);
+static bool stab_float_type (void *, unsigned int);
+static bool stab_complex_type (void *, unsigned int);
+static bool stab_bool_type (void *, unsigned int);
+static bool stab_enum_type
   (void *, const char *, const char **, bfd_signed_vma *);
-static bfd_boolean stab_pointer_type (void *);
-static bfd_boolean stab_function_type (void *, int, bfd_boolean);
-static bfd_boolean stab_reference_type (void *);
-static bfd_boolean stab_range_type (void *, bfd_signed_vma, bfd_signed_vma);
-static bfd_boolean stab_array_type
-  (void *, bfd_signed_vma, bfd_signed_vma, bfd_boolean);
-static bfd_boolean stab_set_type (void *, bfd_boolean);
-static bfd_boolean stab_offset_type (void *);
-static bfd_boolean stab_method_type (void *, bfd_boolean, int, bfd_boolean);
-static bfd_boolean stab_const_type (void *);
-static bfd_boolean stab_volatile_type (void *);
-static bfd_boolean stab_start_struct_type
-  (void *, const char *, unsigned int, bfd_boolean, unsigned int);
-static bfd_boolean stab_struct_field
+static bool stab_pointer_type (void *);
+static bool stab_function_type (void *, int, bool);
+static bool stab_reference_type (void *);
+static bool stab_range_type (void *, bfd_signed_vma, bfd_signed_vma);
+static bool stab_array_type
+  (void *, bfd_signed_vma, bfd_signed_vma, bool);
+static bool stab_set_type (void *, bool);
+static bool stab_offset_type (void *);
+static bool stab_method_type (void *, bool, int, bool);
+static bool stab_const_type (void *);
+static bool stab_volatile_type (void *);
+static bool stab_start_struct_type
+  (void *, const char *, unsigned int, bool, unsigned int);
+static bool stab_struct_field
   (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
-static bfd_boolean stab_end_struct_type (void *);
-static bfd_boolean stab_start_class_type
-  (void *, const char *, unsigned int, bfd_boolean, unsigned int,
-   bfd_boolean, bfd_boolean);
-static bfd_boolean stab_class_static_member
+static bool stab_end_struct_type (void *);
+static bool stab_start_class_type
+  (void *, const char *, unsigned int, bool, unsigned int,
+   bool, bool);
+static bool stab_class_static_member
   (void *, const char *, const char *, enum debug_visibility);
-static bfd_boolean stab_class_baseclass
-  (void *, bfd_vma, bfd_boolean, enum debug_visibility);
-static bfd_boolean stab_class_start_method (void *, const char *);
-static bfd_boolean stab_class_method_variant
-  (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean,
-   bfd_vma, bfd_boolean);
-static bfd_boolean stab_class_static_method_variant
-  (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean);
-static bfd_boolean stab_class_end_method (void *);
-static bfd_boolean stab_end_class_type (void *);
-static bfd_boolean stab_typedef_type (void *, const char *);
-static bfd_boolean stab_tag_type
+static bool stab_class_baseclass
+  (void *, bfd_vma, bool, enum debug_visibility);
+static bool stab_class_start_method (void *, const char *);
+static bool stab_class_method_variant
+  (void *, const char *, enum debug_visibility, bool, bool,
+   bfd_vma, bool);
+static bool stab_class_static_method_variant
+  (void *, const char *, enum debug_visibility, bool, bool);
+static bool stab_class_end_method (void *);
+static bool stab_end_class_type (void *);
+static bool stab_typedef_type (void *, const char *);
+static bool stab_tag_type
   (void *, const char *, unsigned int, enum debug_type_kind);
-static bfd_boolean stab_typdef (void *, const char *);
-static bfd_boolean stab_tag (void *, const char *);
-static bfd_boolean stab_int_constant (void *, const char *, bfd_vma);
-static bfd_boolean stab_float_constant (void *, const char *, double);
-static bfd_boolean stab_typed_constant (void *, const char *, bfd_vma);
-static bfd_boolean stab_variable
+static bool stab_typdef (void *, const char *);
+static bool stab_tag (void *, const char *);
+static bool stab_int_constant (void *, const char *, bfd_vma);
+static bool stab_float_constant (void *, const char *, double);
+static bool stab_typed_constant (void *, const char *, bfd_vma);
+static bool stab_variable
   (void *, const char *, enum debug_var_kind, bfd_vma);
-static bfd_boolean stab_start_function (void *, const char *, bfd_boolean);
-static bfd_boolean stab_function_parameter
+static bool stab_start_function (void *, const char *, bool);
+static bool stab_function_parameter
   (void *, const char *, enum debug_parm_kind, bfd_vma);
-static bfd_boolean stab_start_block (void *, bfd_vma);
-static bfd_boolean stab_end_block (void *, bfd_vma);
-static bfd_boolean stab_end_function (void *);
-static bfd_boolean stab_lineno (void *, const char *, unsigned long, bfd_vma);
+static bool stab_start_block (void *, bfd_vma);
+static bool stab_end_block (void *, bfd_vma);
+static bool stab_end_function (void *);
+static bool stab_lineno (void *, const char *, unsigned long, bfd_vma);
 
 static const struct debug_write_fns stab_fns =
 {
@@ -335,7 +317,7 @@ string_hash_newfunc (struct bfd_hash_entry *entry,
 
 /* Add a symbol to the stabs debugging information we are building.  */
 
-static bfd_boolean
+static bool
 stab_write_symbol (struct stab_write_handle *info, int type, int desc,
                   bfd_vma value, const char *string)
 {
@@ -348,12 +330,12 @@ stab_write_symbol (struct stab_write_handle *info, int type, int desc,
     {
       struct string_hash_entry *h;
 
-      h = string_hash_lookup (&info->strhash, string, TRUE, TRUE);
+      h = string_hash_lookup (&info->strhash, string, true, true);
       if (h == NULL)
        {
          non_fatal (_("string_hash_lookup failed: %s"),
                     bfd_errmsg (bfd_get_error ()));
-         return FALSE;
+         return false;
        }
       if (h->index != -1)
        strx = h->index;
@@ -380,28 +362,36 @@ stab_write_symbol (struct stab_write_handle *info, int type, int desc,
   if (info->symbols_size + STAB_SYMBOL_SIZE > info->symbols_alloc)
     {
       info->symbols_alloc *= 2;
-      info->symbols = (bfd_byte *) xrealloc (info->symbols,
-                                            info->symbols_alloc);
+      info->symbols = xrealloc (info->symbols, info->symbols_alloc);
     }
 
   memcpy (info->symbols + info->symbols_size, sym, STAB_SYMBOL_SIZE);
 
   info->symbols_size += STAB_SYMBOL_SIZE;
 
-  return TRUE;
+  return true;
+}
+
+static bool
+stab_write_symbol_and_free (struct stab_write_handle *info, int type, int desc,
+                           bfd_vma value, char *string)
+{
+  bool ret = stab_write_symbol (info, type, desc, value, string);
+  free (string);
+  return ret;
 }
 
 /* Push a string on to the type stack.  */
 
-static bfd_boolean
-stab_push_string (struct stab_write_handle *info, const char *string,
-                 long index, bfd_boolean definition, unsigned int size)
+static bool
+stab_push_string (struct stab_write_handle *info, char *string,
+                 long tindex, bool definition, unsigned int size)
 {
   struct stab_type_stack *s;
 
-  s = (struct stab_type_stack *) xmalloc (sizeof *s);
-  s->string = xstrdup (string);
-  s->index = index;
+  s = xmalloc (sizeof *s);
+  s->string = string;
+  s->index = tindex;
   s->definition = definition;
   s->size = size;
 
@@ -413,19 +403,26 @@ stab_push_string (struct stab_write_handle *info, const char *string,
   s->next = info->type_stack;
   info->type_stack = s;
 
-  return TRUE;
+  return true;
+}
+
+static bool
+stab_push_string_dup (struct stab_write_handle *info, const char *string,
+                     long tindex, bool definition, unsigned int size)
+{
+  return stab_push_string (info, xstrdup (string), tindex, definition, size);
 }
 
 /* Push a type index which has already been defined.  */
 
-static bfd_boolean
-stab_push_defined_type (struct stab_write_handle *info, long index,
+static bool
+stab_push_defined_type (struct stab_write_handle *info, long tindex,
                        unsigned int size)
 {
   char buf[20];
 
-  sprintf (buf, "%ld", index);
-  return stab_push_string (info, buf, index, FALSE, size);
+  sprintf (buf, "%ld", tindex);
+  return stab_push_string_dup (info, buf, tindex, false, size);
 }
 
 /* Pop a type off the type stack.  The caller is responsible for
@@ -438,7 +435,8 @@ stab_pop_type (struct stab_write_handle *info)
   char *ret;
 
   s = info->type_stack;
-  assert (s != NULL);
+  if (s == NULL)
+    return NULL;
 
   info->type_stack = s->next;
 
@@ -458,7 +456,7 @@ stab_pop_type (struct stab_write_handle *info)
    the symbols, *PSYMSIZE the size of the symbols, *PSTRINGS to the
    strings, and *PSTRINGSIZE to the size of the strings.  */
 
-bfd_boolean
+bool
 write_stabs_in_sections_debugging_info (bfd *abfd, void *dhandle,
                                        bfd_byte **psyms,
                                        bfd_size_type *psymsize,
@@ -468,17 +466,20 @@ write_stabs_in_sections_debugging_info (bfd *abfd, void *dhandle,
   struct stab_write_handle info;
   struct string_hash_entry *h;
   bfd_byte *p;
+  bool ret;
 
+  memset (&info, 0, sizeof info);
   info.abfd = abfd;
 
-  info.symbols_size = 0;
   info.symbols_alloc = 500;
-  info.symbols = (bfd_byte *) xmalloc (info.symbols_alloc);
+  info.symbols = xmalloc (info.symbols_alloc);
 
-  info.strings = NULL;
-  info.last_string = NULL;
   /* Reserve 1 byte for a null byte.  */
   info.strings_size = 1;
+  info.type_index = 1;
+  info.so_offset = -1;
+  info.fun_offset = -1;
+  info.pending_lbrac = (bfd_vma) -1;
 
   if (!bfd_hash_table_init (&info.strhash.table, string_hash_newfunc,
                            sizeof (struct string_hash_entry))
@@ -487,37 +488,28 @@ write_stabs_in_sections_debugging_info (bfd *abfd, void *dhandle,
     {
       non_fatal ("bfd_hash_table_init_failed: %s",
                 bfd_errmsg (bfd_get_error ()));
-      return FALSE;
+      goto fail;
     }
 
-  info.type_stack = NULL;
-  info.type_index = 1;
-  memset (&info.type_cache, 0, sizeof info.type_cache);
-  info.so_offset = -1;
-  info.fun_offset = -1;
-  info.last_text_address = 0;
-  info.nesting = 0;
-  info.fnaddr = 0;
-  info.pending_lbrac = (bfd_vma) -1;
-
   /* The initial symbol holds the string size.  */
   if (! stab_write_symbol (&info, 0, 0, 0, (const char *) NULL))
-    return FALSE;
+    goto fail;
 
   /* Output an initial N_SO symbol.  */
   info.so_offset = info.symbols_size;
   if (! stab_write_symbol (&info, N_SO, 0, 0, bfd_get_filename (abfd)))
-    return FALSE;
+    goto fail;
 
   if (! debug_write (dhandle, &stab_fns, (void *) &info))
-    return FALSE;
+    goto fail;
 
-  assert (info.pending_lbrac == (bfd_vma) -1);
+  if (info.pending_lbrac != (bfd_vma) -1)
+    goto fail;
 
   /* Output a trailing N_SO.  */
   if (! stab_write_symbol (&info, N_SO, 0, info.last_text_address,
                           (const char *) NULL))
-    return FALSE;
+    goto fail;
 
   /* Put the string size in the initial symbol.  */
   bfd_put_32 (abfd, info.strings_size, info.symbols + 8);
@@ -526,7 +518,7 @@ write_stabs_in_sections_debugging_info (bfd *abfd, void *dhandle,
   *psymsize = info.symbols_size;
 
   *pstringsize = info.strings_size;
-  *pstrings = (bfd_byte *) xmalloc (info.strings_size);
+  *pstrings = xmalloc (info.strings_size);
 
   p = *pstrings;
   *p++ = '\0';
@@ -536,12 +528,43 @@ write_stabs_in_sections_debugging_info (bfd *abfd, void *dhandle,
       p += strlen ((char *) p) + 1;
     }
 
-  return TRUE;
+  ret = true;
+  goto out;
+
+ fail:
+  free (info.symbols);
+  ret = false;
+ out:
+  while (info.type_stack != NULL)
+    {
+      struct stab_type_stack *s = info.type_stack;
+      info.type_stack = s->next;
+      free (s->string);
+      free (s->fields);
+      if (s->baseclasses != NULL)
+       {
+         for (int i = 0; s->baseclasses[i] != NULL; i++)
+           free (s->baseclasses[i]);
+         free (s->baseclasses);
+       }
+      free (s->methods);
+      free (s->vtable);
+      free (s);
+    }
+  free (info.type_cache.pointer_types);
+  free (info.type_cache.function_types);
+  free (info.type_cache.reference_types);
+  free (info.type_cache.struct_types);
+  if (info.typedef_hash.table.memory)
+    bfd_hash_table_free (&info.typedef_hash.table);
+  if (info.strhash.table.memory)
+    bfd_hash_table_free (&info.strhash.table);
+  return ret;
 }
 
 /* Start writing out information for a compilation unit.  */
 
-static bfd_boolean
+static bool
 stab_start_compilation_unit (void *p, const char *filename)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -558,7 +581,7 @@ stab_start_compilation_unit (void *p, const char *filename)
 
 /* Start writing out information for a particular source file.  */
 
-static bfd_boolean
+static bool
 stab_start_source (void *p, const char *filename)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -575,7 +598,7 @@ stab_start_source (void *p, const char *filename)
 /* Push an empty type.  This shouldn't normally happen.  We just use a
    void type.  */
 
-static bfd_boolean
+static bool
 stab_empty_type (void *p)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -587,21 +610,21 @@ stab_empty_type (void *p)
     return stab_push_defined_type (info, info->type_cache.void_type, 0);
   else
     {
-      long index;
+      long tindex;
       char buf[40];
 
-      index = info->type_index;
+      tindex = info->type_index;
       ++info->type_index;
 
-      sprintf (buf, "%ld=%ld", index, index);
+      sprintf (buf, "%ld=%ld", tindex, tindex);
 
-      return stab_push_string (info, buf, index, FALSE, 0);
+      return stab_push_string_dup (info, buf, tindex, false, 0);
     }
 }
 
 /* Push a void type.  */
 
-static bfd_boolean
+static bool
 stab_void_type (void *p)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -610,24 +633,24 @@ stab_void_type (void *p)
     return stab_push_defined_type (info, info->type_cache.void_type, 0);
   else
     {
-      long index;
+      long tindex;
       char buf[40];
 
-      index = info->type_index;
+      tindex = info->type_index;
       ++info->type_index;
 
-      info->type_cache.void_type = index;
+      info->type_cache.void_type = tindex;
 
-      sprintf (buf, "%ld=%ld", index, index);
+      sprintf (buf, "%ld=%ld", tindex, tindex);
 
-      return stab_push_string (info, buf, index, TRUE, 0);
+      return stab_push_string_dup (info, buf, tindex, true, 0);
     }
 }
 
 /* Push an integer type.  */
 
-static bfd_boolean
-stab_int_type (void *p, unsigned int size, bfd_boolean unsignedp)
+static bool
+stab_int_type (void *p, unsigned int size, bool unsignedp)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
   long *cache;
@@ -635,7 +658,7 @@ stab_int_type (void *p, unsigned int size, bfd_boolean unsignedp)
   if (size <= 0 || (size > sizeof (long) && size != 8))
     {
       non_fatal (_("stab_int_type: bad size %u"), size);
-      return FALSE;
+      return false;
     }
 
   if (unsignedp)
@@ -647,46 +670,48 @@ stab_int_type (void *p, unsigned int size, bfd_boolean unsignedp)
     return stab_push_defined_type (info, cache[size - 1], size);
   else
     {
-      long index;
+      long tindex;
       char buf[100];
 
-      index = info->type_index;
+      tindex = info->type_index;
       ++info->type_index;
 
-      cache[size - 1] = index;
+      cache[size - 1] = tindex;
 
-      sprintf (buf, "%ld=r%ld;", index, index);
+      int len = sprintf (buf, "%ld=r%ld;", tindex, tindex);
       if (unsignedp)
        {
-         strcat (buf, "0;");
+         strcpy (buf + len, "0;");
+         len += 2;
          if (size < sizeof (long))
-           sprintf (buf + strlen (buf), "%ld;", ((long) 1 << (size * 8)) - 1);
+           sprintf (buf + len, "%ld;", ((long) 1 << (size * 8)) - 1);
          else if (size == sizeof (long))
-           strcat (buf, "-1;");
+           strcpy (buf + len, "-1;");
          else if (size == 8)
-           strcat (buf, "01777777777777777777777;");
+           strcpy (buf + len, "01777777777777777777777;");
          else
            abort ();
        }
       else
        {
          if (size <= sizeof (long))
-           sprintf (buf + strlen (buf), "%ld;%ld;",
+           sprintf (buf + len, "%ld;%ld;",
                     (long) - ((unsigned long) 1 << (size * 8 - 1)),
                     (long) (((unsigned long) 1 << (size * 8 - 1)) - 1));
          else if (size == 8)
-           strcat (buf, "01000000000000000000000;0777777777777777777777;");
+           strcpy (buf + len,
+                   "01000000000000000000000;0777777777777777777777;");
          else
            abort ();
        }
 
-      return stab_push_string (info, buf, index, TRUE, size);
+      return stab_push_string_dup (info, buf, tindex, true, size);
     }
 }
 
 /* Push a floating point type.  */
 
-static bfd_boolean
+static bool
 stab_float_type (void *p, unsigned int size)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -700,83 +725,83 @@ stab_float_type (void *p, unsigned int size)
                                   size);
   else
     {
-      long index;
+      long tindex;
       char *int_type;
       char buf[50];
 
       /* Floats are defined as a subrange of int.  */
-      if (! stab_int_type (info, 4, FALSE))
-       return FALSE;
+      if (! stab_int_type (info, 4, false))
+       return false;
       int_type = stab_pop_type (info);
 
-      index = info->type_index;
+      tindex = info->type_index;
       ++info->type_index;
 
       if (size > 0
          && size - 1 < (sizeof info->type_cache.float_types
                         / sizeof info->type_cache.float_types[0]))
-       info->type_cache.float_types[size - 1] = index;
+       info->type_cache.float_types[size - 1] = tindex;
 
-      sprintf (buf, "%ld=r%s;%u;0;", index, int_type, size);
+      sprintf (buf, "%ld=r%s;%u;0;", tindex, int_type, size);
 
       free (int_type);
 
-      return stab_push_string (info, buf, index, TRUE, size);
+      return stab_push_string_dup (info, buf, tindex, true, size);
     }
 }
 
 /* Push a complex type.  */
 
-static bfd_boolean
+static bool
 stab_complex_type (void *p, unsigned int size)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
   char buf[50];
-  long index;
+  long tindex;
 
-  index = info->type_index;
+  tindex = info->type_index;
   ++info->type_index;
 
-  sprintf (buf, "%ld=r%ld;%u;0;", index, index, size);
+  sprintf (buf, "%ld=r%ld;%u;0;", tindex, tindex, size);
 
-  return stab_push_string (info, buf, index, TRUE, size * 2);
+  return stab_push_string_dup (info, buf, tindex, true, size * 2);
 }
 
-/* Push a bfd_boolean type.  We use an XCOFF predefined type, since gdb
+/* Push a bool type.  We use an XCOFF predefined type, since gdb
    always recognizes them.  */
 
-static bfd_boolean
+static bool
 stab_bool_type (void *p, unsigned int size)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  long index;
+  long tindex;
 
   switch (size)
     {
     case 1:
-      index = -21;
+      tindex = -21;
       break;
 
     case 2:
-      index = -22;
+      tindex = -22;
       break;
 
     default:
     case 4:
-      index = -16;
+      tindex = -16;
       break;
 
     case 8:
-      index = -33;
+      tindex = -33;
       break;
     }
 
-  return stab_push_defined_type (info, index, size);
+  return stab_push_defined_type (info, tindex, size);
 }
 
 /* Push an enum type.  */
 
-static bfd_boolean
+static bool
 stab_enum_type (void *p, const char *tag, const char **names,
                bfd_signed_vma *vals)
 {
@@ -784,92 +809,83 @@ stab_enum_type (void *p, const char *tag, const char **names,
   size_t len;
   const char **pn;
   char *buf;
-  long index = 0;
+  long tindex = 0;
   bfd_signed_vma *pv;
 
   if (names == NULL)
     {
-      assert (tag != NULL);
+      if (tag == NULL)
+       return false;
 
-      buf = (char *) xmalloc (10 + strlen (tag));
+      buf = xmalloc (4 + strlen (tag));
       sprintf (buf, "xe%s:", tag);
       /* FIXME: The size is just a guess.  */
-      if (! stab_push_string (info, buf, 0, FALSE, 4))
-       return FALSE;
-      free (buf);
-      return TRUE;
+      return stab_push_string (info, buf, 0, false, 4);
     }
 
-  len = 10;
+  len = 25;
   if (tag != NULL)
     len += strlen (tag);
   for (pn = names; *pn != NULL; pn++)
-    len += strlen (*pn) + 20;
-
-  buf = (char *) xmalloc (len);
+    len += strlen (*pn) + 22;
 
+  buf = xmalloc (len);
+  char *out = buf;
   if (tag == NULL)
-    strcpy (buf, "e");
+    out = stpcpy (out, "e");
   else
     {
-      index = info->type_index;
+      tindex = info->type_index;
       ++info->type_index;
-      sprintf (buf, "%s:T%ld=e", tag, index);
+      out += sprintf (out, "%s:T%ld=e", tag, tindex);
     }
 
   for (pn = names, pv = vals; *pn != NULL; pn++, pv++)
-    sprintf (buf + strlen (buf), "%s:%ld,", *pn, (long) *pv);
-  strcat (buf, ";");
+    out += sprintf (out, "%s:%ld,", *pn, (long) *pv);
+  strcpy (out, ";");
 
   if (tag == NULL)
     {
       /* FIXME: The size is just a guess.  */
-      if (! stab_push_string (info, buf, 0, FALSE, 4))
-       return FALSE;
+      return stab_push_string (info, buf, 0, false, 4);
     }
   else
     {
       /* FIXME: The size is just a guess.  */
-      if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)
-         || ! stab_push_defined_type (info, index, 4))
-       return FALSE;
+      return (stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf)
+             && stab_push_defined_type (info, tindex, 4));
     }
-
-  free (buf);
-
-  return TRUE;
 }
 
 /* Push a modification of the top type on the stack.  Cache the
    results in CACHE and CACHE_ALLOC.  */
 
-static bfd_boolean
+static bool
 stab_modify_type (struct stab_write_handle *info, int mod,
                  unsigned int size, long **cache, size_t *cache_alloc)
 {
   long targindex;
-  long index;
+  long tindex;
   char *s, *buf;
 
-  assert (info->type_stack != NULL);
+  if (info->type_stack == NULL)
+    return false;
   targindex = info->type_stack->index;
 
   if (targindex <= 0
       || cache == NULL)
     {
-      bfd_boolean definition;
+      bool definition;
 
       /* Either the target type has no index, or we aren't caching
          this modifier.  Either way we have no way of recording the
          new type, so we don't bother to define one.  */
       definition = info->type_stack->definition;
       s = stab_pop_type (info);
-      buf = (char *) xmalloc (strlen (s) + 2);
+      buf = xmalloc (strlen (s) + 2);
       sprintf (buf, "%c%s", mod, s);
       free (s);
-      if (! stab_push_string (info, buf, 0, definition, size))
-       return FALSE;
-      free (buf);
+      return stab_push_string (info, buf, 0, definition, size);
     }
   else
     {
@@ -882,14 +898,14 @@ stab_modify_type (struct stab_write_handle *info, int mod,
            alloc = 10;
          while ((size_t) targindex >= alloc)
            alloc *= 2;
-         *cache = (long *) xrealloc (*cache, alloc * sizeof (long));
+         *cache = xrealloc (*cache, alloc * sizeof (**cache));
          memset (*cache + *cache_alloc, 0,
-                 (alloc - *cache_alloc) * sizeof (long));
+                 (alloc - *cache_alloc) * sizeof (**cache));
          *cache_alloc = alloc;
        }
 
-      index = (*cache)[targindex];
-      if (index != 0 && ! info->type_stack->definition)
+      tindex = (*cache)[targindex];
+      if (tindex != 0 && ! 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
@@ -898,34 +914,28 @@ stab_modify_type (struct stab_write_handle *info, int mod,
              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;
+         return stab_push_defined_type (info, tindex, size);
        }
       else
        {
-         index = info->type_index;
+         tindex = info->type_index;
          ++info->type_index;
 
          s = stab_pop_type (info);
-         buf = (char *) xmalloc (strlen (s) + 20);
-         sprintf (buf, "%ld=%c%s", index, mod, s);
+         buf = xmalloc (strlen (s) + 23);
+         sprintf (buf, "%ld=%c%s", tindex, mod, s);
          free (s);
 
-         (*cache)[targindex] = index;
-
-         if (! stab_push_string (info, buf, index, TRUE, size))
-           return FALSE;
+         (*cache)[targindex] = tindex;
 
-         free (buf);
+         return stab_push_string (info, buf, tindex, true, size);
        }
     }
-
-  return TRUE;
 }
 
 /* Push a pointer type.  */
 
-static bfd_boolean
+static bool
 stab_pointer_type (void *p)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -937,9 +947,9 @@ stab_pointer_type (void *p)
 
 /* Push a function type.  */
 
-static bfd_boolean
+static bool
 stab_function_type (void *p, int argcount,
-                   bfd_boolean varargs ATTRIBUTE_UNUSED)
+                   bool varargs ATTRIBUTE_UNUSED)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
   int i;
@@ -957,14 +967,11 @@ stab_function_type (void *p, int argcount,
 
          s = stab_pop_type (info);
 
-         buf = (char *) xmalloc (strlen (s) + 3);
+         buf = xmalloc (strlen (s) + 3);
          sprintf (buf, ":t%s", s);
          free (s);
 
-         if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
-           return FALSE;
-
-         free (buf);
+         return stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf);
        }
     }
 
@@ -974,7 +981,7 @@ stab_function_type (void *p, int argcount,
 
 /* Push a reference type.  */
 
-static bfd_boolean
+static bool
 stab_reference_type (void *p)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -986,11 +993,11 @@ stab_reference_type (void *p)
 
 /* Push a range type.  */
 
-static bfd_boolean
+static bool
 stab_range_type (void *p, bfd_signed_vma low, bfd_signed_vma high)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  bfd_boolean definition;
+  bool definition;
   unsigned int size;
   char *s, *buf;
 
@@ -998,29 +1005,24 @@ stab_range_type (void *p, bfd_signed_vma low, bfd_signed_vma high)
   size = info->type_stack->size;
 
   s = stab_pop_type (info);
-  buf = (char *) xmalloc (strlen (s) + 100);
+  buf = xmalloc (strlen (s) + 45);
   sprintf (buf, "r%s;%ld;%ld;", s, (long) low, (long) high);
   free (s);
 
-  if (! stab_push_string (info, buf, 0, definition, size))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_push_string (info, buf, 0, definition, size);
 }
 
 /* Push an array type.  */
 
-static bfd_boolean
+static bool
 stab_array_type (void *p, bfd_signed_vma low, bfd_signed_vma high,
-                bfd_boolean stringp)
+                bool stringp)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  bfd_boolean definition;
+  bool definition;
   unsigned int element_size;
   char *range, *element, *buf;
-  long index;
+  long tindex;
   unsigned int size;
 
   definition = info->type_stack->definition;
@@ -1030,24 +1032,21 @@ stab_array_type (void *p, bfd_signed_vma low, bfd_signed_vma high,
   element_size = info->type_stack->size;
   element = stab_pop_type (info);
 
-  buf = (char *) xmalloc (strlen (range) + strlen (element) + 100);
-
+  buf = xmalloc (strlen (range) + strlen (element) + 70);
+  char *out = buf;
   if (! stringp)
-    {
-      index = 0;
-      *buf = '\0';
-    }
+    tindex = 0;
   else
     {
       /* We need to define a type in order to include the string
          attribute.  */
-      index = info->type_index;
+      tindex = info->type_index;
       ++info->type_index;
-      definition = TRUE;
-      sprintf (buf, "%ld=@S;", index);
+      definition = true;
+      out += sprintf (out, "%ld=@S;", tindex);
     }
 
-  sprintf (buf + strlen (buf), "ar%s;%ld;%ld;%s",
+  sprintf (out, "ar%s;%ld;%ld;%s",
           range, (long) low, (long) high, element);
   free (range);
   free (element);
@@ -1056,62 +1055,49 @@ stab_array_type (void *p, bfd_signed_vma low, bfd_signed_vma high,
     size = 0;
   else
     size = element_size * ((high - low) + 1);
-  if (! stab_push_string (info, buf, index, definition, size))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_push_string (info, buf, tindex, definition, size);
 }
 
 /* Push a set type.  */
 
-static bfd_boolean
-stab_set_type (void *p, bfd_boolean bitstringp)
+static bool
+stab_set_type (void *p, bool bitstringp)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  bfd_boolean definition;
+  bool definition;
   char *s, *buf;
-  long index;
+  long tindex;
 
   definition = info->type_stack->definition;
 
   s = stab_pop_type (info);
-  buf = (char *) xmalloc (strlen (s) + 30);
-
+  buf = xmalloc (strlen (s) + 26);
+  char *out = buf;
   if (! bitstringp)
-    {
-      *buf = '\0';
-      index = 0;
-    }
+    tindex = 0;
   else
     {
       /* We need to define a type in order to include the string
          attribute.  */
-      index = info->type_index;
+      tindex = info->type_index;
       ++info->type_index;
-      definition = TRUE;
-      sprintf (buf, "%ld=@S;", index);
+      definition = true;
+      out += sprintf (out, "%ld=@S;", tindex);
     }
 
-  sprintf (buf + strlen (buf), "S%s", s);
+  sprintf (out, "S%s", s);
   free (s);
 
-  if (! stab_push_string (info, buf, index, definition, 0))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_push_string (info, buf, tindex, definition, 0);
 }
 
 /* Push an offset type.  */
 
-static bfd_boolean
+static bool
 stab_offset_type (void *p)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  bfd_boolean definition;
+  bool definition;
   char *target, *base, *buf;
 
   definition = info->type_stack->definition;
@@ -1120,27 +1106,22 @@ stab_offset_type (void *p)
   definition = definition || info->type_stack->definition;
   base = stab_pop_type (info);
 
-  buf = (char *) xmalloc (strlen (target) + strlen (base) + 3);
+  buf = xmalloc (strlen (target) + strlen (base) + 3);
   sprintf (buf, "@%s,%s", base, target);
   free (base);
   free (target);
 
-  if (! stab_push_string (info, buf, 0, definition, 0))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_push_string (info, buf, 0, definition, 0);
 }
 
 /* Push a method type.  */
 
-static bfd_boolean
-stab_method_type (void *p, bfd_boolean domainp, int argcount,
-                 bfd_boolean varargs)
+static bool
+stab_method_type (void *p, bool domainp, int argcount,
+                 bool varargs)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  bfd_boolean definition;
+  bool definition;
   char *domain, *return_type, *buf;
   char **args;
   int i;
@@ -1155,7 +1136,7 @@ stab_method_type (void *p, bfd_boolean domainp, int argcount,
   if (! domainp)
     {
       if (! stab_empty_type (p))
-       return FALSE;
+       return false;
     }
 
   definition = info->type_stack->definition;
@@ -1175,9 +1156,12 @@ stab_method_type (void *p, bfd_boolean domainp, int argcount,
        args = NULL;
       else
        {
-         args = (char **) xmalloc (1 * sizeof (*args));
+         args = xmalloc (1 * sizeof (*args));
          if (! stab_empty_type (p))
-           return FALSE;
+           {
+             free (args);
+             return false;
+           }
          definition = definition || info->type_stack->definition;
          args[0] = stab_pop_type (info);
          argcount = 1;
@@ -1185,7 +1169,7 @@ stab_method_type (void *p, bfd_boolean domainp, int argcount,
     }
   else
     {
-      args = (char **) xmalloc ((argcount + 1) * sizeof (*args));
+      args = xmalloc ((argcount + 1) * sizeof (*args));
       for (i = argcount - 1; i >= 0; i--)
        {
          definition = definition || info->type_stack->definition;
@@ -1194,7 +1178,12 @@ stab_method_type (void *p, bfd_boolean domainp, int argcount,
       if (! varargs)
        {
          if (! stab_empty_type (p))
-           return FALSE;
+           {
+             for (i = 0; i < argcount; i++)
+               free (args[i]);
+             free (args);
+             return false;
+           }
          definition = definition || info->type_stack->definition;
          args[argcount] = stab_pop_type (info);
          ++argcount;
@@ -1204,37 +1193,35 @@ stab_method_type (void *p, bfd_boolean domainp, int argcount,
   definition = definition || info->type_stack->definition;
   return_type = stab_pop_type (info);
 
-  len = strlen (domain) + strlen (return_type) + 10;
+  len = strlen (domain) + strlen (return_type) + 4 + argcount;
   for (i = 0; i < argcount; i++)
     len += strlen (args[i]);
 
-  buf = (char *) xmalloc (len);
-
-  sprintf (buf, "#%s,%s", domain, return_type);
+  buf = xmalloc (len);
+  char *out = buf;
+  *out++ = '#';
+  out = stpcpy (out, domain);
+  *out++ = ',';
+  out = stpcpy (out, return_type);
   free (domain);
   free (return_type);
   for (i = 0; i < argcount; i++)
     {
-      strcat (buf, ",");
-      strcat (buf, args[i]);
+      *out++ = ',';
+      out = stpcpy (out, args[i]);
       free (args[i]);
     }
-  strcat (buf, ";");
+  *out++ = ';';
+  *out = 0;
 
-  if (args != NULL)
-    free (args);
+  free (args);
 
-  if (! stab_push_string (info, buf, 0, definition, 0))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_push_string (info, buf, 0, definition, 0);
 }
 
 /* Push a const version of a type.  */
 
-static bfd_boolean
+static bool
 stab_const_type (void *p)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -1245,7 +1232,7 @@ stab_const_type (void *p)
 
 /* Push a volatile version of a type.  */
 
-static bfd_boolean
+static bool
 stab_volatile_type (void *p)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -1272,13 +1259,13 @@ stab_get_struct_index (struct stab_write_handle *info, const char *tag,
       while (id >= alloc)
        alloc *= 2;
       info->type_cache.struct_types =
-       (struct stab_tag *) xrealloc (info->type_cache.struct_types,
-                                     alloc * sizeof (struct stab_tag));
+       xrealloc (info->type_cache.struct_types,
+                 alloc * sizeof (*info->type_cache.struct_types));
       memset ((info->type_cache.struct_types
               + info->type_cache.struct_types_alloc),
              0,
              ((alloc - info->type_cache.struct_types_alloc)
-              * sizeof (struct stab_tag)));
+              * sizeof (*info->type_cache.struct_types)));
       info->type_cache.struct_types_alloc = alloc;
     }
 
@@ -1305,54 +1292,52 @@ stab_get_struct_index (struct stab_write_handle *info, const char *tag,
 /* Start outputting a struct.  We ignore the tag, and handle it in
    stab_tag.  */
 
-static bfd_boolean
+static bool
 stab_start_struct_type (void *p, const char *tag, unsigned int id,
-                       bfd_boolean structp, unsigned int size)
+                       bool structp, unsigned int size)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  long index;
-  bfd_boolean definition;
-  char *buf;
-
-  buf = (char *) xmalloc (40);
+  long tindex;
+  bool definition;
+  char buf[40];
+  char *out = buf;
 
   if (id == 0)
     {
-      index = 0;
-      *buf = '\0';
-      definition = FALSE;
+      tindex = 0;
+      definition = false;
     }
   else
     {
-      index = stab_get_struct_index (info, tag, id, DEBUG_KIND_ILLEGAL,
+      tindex = stab_get_struct_index (info, tag, id, DEBUG_KIND_ILLEGAL,
                                     &size);
-      if (index < 0)
-       return FALSE;
-      sprintf (buf, "%ld=", index);
-      definition = TRUE;
+      if (tindex < 0)
+       return false;
+      out += sprintf (out, "%ld=", tindex);
+      definition = true;
     }
 
-  sprintf (buf + strlen (buf), "%c%u",
+  sprintf (out, "%c%u",
           structp ? 's' : 'u',
           size);
 
-  if (! stab_push_string (info, buf, index, definition, size))
-    return FALSE;
+  if (!stab_push_string_dup (info, buf, tindex, definition, size))
+    return false;
 
-  info->type_stack->fields = (char *) xmalloc (1);
+  info->type_stack->fields = xmalloc (1);
   info->type_stack->fields[0] = '\0';
 
-  return TRUE;
+  return true;
 }
 
 /* Add a field to a struct.  */
 
-static bfd_boolean
+static bool
 stab_struct_field (void *p, const char *name, bfd_vma bitpos,
                   bfd_vma bitsize, enum debug_visibility visibility)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  bfd_boolean definition;
+  bool definition;
   unsigned int size;
   char *s, *n;
   const char *vis;
@@ -1363,12 +1348,14 @@ stab_struct_field (void *p, const char *name, bfd_vma bitpos,
 
   /* Add this field to the end of the current struct fields, which is
      currently on the top of the stack.  */
+  if (info->type_stack->fields == NULL)
+    {
+      free (s);
+      return false;
+    }
 
-  assert (info->type_stack->fields != NULL);
-  n = (char *) xmalloc (strlen (info->type_stack->fields)
-                       + strlen (name)
-                       + strlen (s)
-                       + 50);
+  n = xmalloc (strlen (info->type_stack->fields)
+              + strlen (name) + strlen (s) + 50);
 
   switch (visibility)
     {
@@ -1400,68 +1387,65 @@ stab_struct_field (void *p, const char *name, bfd_vma bitpos,
           (long) bitpos, (long) bitsize);
 
   free (info->type_stack->fields);
+  free (s);
   info->type_stack->fields = n;
 
   if (definition)
-    info->type_stack->definition = TRUE;
+    info->type_stack->definition = true;
 
-  return TRUE;
+  return true;
 }
 
 /* Finish up a struct.  */
 
-static bfd_boolean
+static bool
 stab_end_struct_type (void *p)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  bfd_boolean definition;
-  long index;
+  bool definition;
+  long tindex;
   unsigned int size;
   char *fields, *first, *buf;
 
-  assert (info->type_stack != NULL && info->type_stack->fields != NULL);
+  if (info->type_stack == NULL || info->type_stack->fields == NULL)
+    return false;
 
   definition = info->type_stack->definition;
-  index = info->type_stack->index;
+  tindex = info->type_stack->index;
   size = info->type_stack->size;
   fields = info->type_stack->fields;
   first = stab_pop_type (info);
 
-  buf = (char *) xmalloc (strlen (first) + strlen (fields) + 2);
+  buf = xmalloc (strlen (first) + strlen (fields) + 2);
   sprintf (buf, "%s%s;", first, fields);
   free (first);
   free (fields);
 
-  if (! stab_push_string (info, buf, index, definition, size))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_push_string (info, buf, tindex, definition, size);
 }
 
 /* Start outputting a class.  */
 
-static bfd_boolean
-stab_start_class_type (void *p, const char *tag, unsigned int id, bfd_boolean structp, unsigned int size, bfd_boolean vptr, bfd_boolean ownvptr)
+static bool
+stab_start_class_type (void *p, const char *tag, unsigned int id,
+                      bool structp, unsigned int size,
+                      bool vptr, bool ownvptr)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  bfd_boolean definition;
-  char *vstring;
+  bool definition = false;
+  char *vstring = NULL;
 
-  if (! vptr || ownvptr)
-    {
-      definition = FALSE;
-      vstring = NULL;
-    }
-  else
+  if (vptr && !ownvptr)
     {
       definition = info->type_stack->definition;
       vstring = stab_pop_type (info);
     }
 
   if (! stab_start_struct_type (p, tag, id, structp, size))
-    return FALSE;
+    {
+      free (vstring);
+      return false;
+    }
 
   if (vptr)
     {
@@ -1469,34 +1453,35 @@ stab_start_class_type (void *p, const char *tag, unsigned int id, bfd_boolean st
 
       if (ownvptr)
        {
-         assert (info->type_stack->index > 0);
-         vtable = (char *) xmalloc (20);
+         if (info->type_stack->index < 1)
+           return false;
+         vtable = xmalloc (23);
          sprintf (vtable, "~%%%ld", info->type_stack->index);
        }
       else
        {
-         vtable = (char *) xmalloc (strlen (vstring) + 3);
+         if (vstring == NULL)
+           return false;
+         vtable = xmalloc (strlen (vstring) + 3);
          sprintf (vtable, "~%%%s", vstring);
          free (vstring);
+         if (definition)
+           info->type_stack->definition = true;
        }
-
       info->type_stack->vtable = vtable;
     }
 
-  if (definition)
-    info->type_stack->definition = TRUE;
-
-  return TRUE;
+  return true;
 }
 
 /* Add a static member to the class on the type stack.  */
 
-static bfd_boolean
+static bool
 stab_class_static_member (void *p, const char *name, const char *physname,
                          enum debug_visibility visibility)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  bfd_boolean definition;
+  bool definition;
   char *s, *n;
   const char *vis;
 
@@ -1506,12 +1491,10 @@ stab_class_static_member (void *p, const char *name, const char *physname,
   /* Add this field to the end of the current struct fields, which is
      currently on the top of the stack.  */
 
-  assert (info->type_stack->fields != NULL);
-  n = (char *) xmalloc (strlen (info->type_stack->fields)
-                       + strlen (name)
-                       + strlen (s)
-                       + strlen (physname)
-                       + 10);
+  if (info->type_stack->fields == NULL)
+    return false;
+  n = xmalloc (strlen (info->type_stack->fields) + strlen (name)
+              + strlen (s) + strlen (physname) + 10);
 
   switch (visibility)
     {
@@ -1534,23 +1517,24 @@ stab_class_static_member (void *p, const char *name, const char *physname,
   sprintf (n, "%s%s:%s%s:%s;", info->type_stack->fields, name, vis, s,
           physname);
 
+  free (s);
   free (info->type_stack->fields);
   info->type_stack->fields = n;
 
   if (definition)
-    info->type_stack->definition = TRUE;
+    info->type_stack->definition = true;
 
-  return TRUE;
+  return true;
 }
 
 /* Add a base class to the class on the type stack.  */
 
-static bfd_boolean
-stab_class_baseclass (void *p, bfd_vma bitpos, bfd_boolean virtual,
+static bool
+stab_class_baseclass (void *p, bfd_vma bitpos, bool is_virtual,
                      enum debug_visibility visibility)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  bfd_boolean definition;
+  bool definition;
   char *s;
   char *buf;
   unsigned int c;
@@ -1561,8 +1545,8 @@ stab_class_baseclass (void *p, bfd_vma bitpos, bfd_boolean virtual,
 
   /* Build the base class specifier.  */
 
-  buf = (char *) xmalloc (strlen (s) + 25);
-  buf[0] = virtual ? '1' : '0';
+  buf = xmalloc (strlen (s) + 25);
+  buf[0] = is_virtual ? '1' : '0';
   switch (visibility)
     {
     default:
@@ -1586,7 +1570,11 @@ stab_class_baseclass (void *p, bfd_vma bitpos, bfd_boolean virtual,
 
   /* Add the new baseclass to the existing ones.  */
 
-  assert (info->type_stack != NULL && info->type_stack->fields != NULL);
+  if (info->type_stack == NULL || info->type_stack->fields == NULL)
+    {
+      free (buf);
+      return false;
+    }
 
   if (info->type_stack->baseclasses == NULL)
     c = 0;
@@ -1597,59 +1585,56 @@ stab_class_baseclass (void *p, bfd_vma bitpos, bfd_boolean virtual,
        ++c;
     }
 
-  baseclasses = (char **) xrealloc (info->type_stack->baseclasses,
-                                   (c + 2) * sizeof (*baseclasses));
+  baseclasses = xrealloc (info->type_stack->baseclasses,
+                         (c + 2) * sizeof (*baseclasses));
   baseclasses[c] = buf;
   baseclasses[c + 1] = NULL;
 
   info->type_stack->baseclasses = baseclasses;
 
   if (definition)
-    info->type_stack->definition = TRUE;
+    info->type_stack->definition = true;
 
-  return TRUE;
+  return true;
 }
 
 /* Start adding a method to the class on the type stack.  */
 
-static bfd_boolean
+static bool
 stab_class_start_method (void *p, const char *name)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
   char *m;
 
-  assert (info->type_stack != NULL && info->type_stack->fields != NULL);
+  if (info->type_stack == NULL || info->type_stack->fields == NULL)
+    return false;
 
   if (info->type_stack->methods == NULL)
     {
-      m = (char *) xmalloc (strlen (name) + 3);
+      m = xmalloc (strlen (name) + 3);
       *m = '\0';
     }
   else
-    {
-      m = (char *) xrealloc (info->type_stack->methods,
-                            (strlen (info->type_stack->methods)
-                             + strlen (name)
-                             + 4));
-    }
+    m = xrealloc (info->type_stack->methods,
+                 strlen (info->type_stack->methods) + strlen (name) + 3);
 
   sprintf (m + strlen (m), "%s::", name);
 
   info->type_stack->methods = m;
 
-  return TRUE;
+  return true;
 }
 
 /* Add a variant, either static or not, to the current method.  */
 
-static bfd_boolean
+static bool
 stab_class_method_var (struct stab_write_handle *info, const char *physname,
                       enum debug_visibility visibility,
-                      bfd_boolean staticp, bfd_boolean constp,
-                      bfd_boolean volatilep, bfd_vma voffset,
-                      bfd_boolean contextp)
+                      bool staticp, bool constp,
+                      bool volatilep, bfd_vma voffset,
+                      bool contextp)
 {
-  bfd_boolean definition;
+  bool definition;
   char *type;
   char *context = NULL;
   char visc, qualc, typec;
@@ -1663,7 +1648,12 @@ stab_class_method_var (struct stab_write_handle *info, const char *physname,
       context = stab_pop_type (info);
     }
 
-  assert (info->type_stack != NULL && info->type_stack->methods != NULL);
+  if (info->type_stack == NULL || info->type_stack->methods == NULL)
+    {
+      free (type);
+      free (context);
+      return false;
+    }
 
   switch (visibility)
     {
@@ -1705,77 +1695,77 @@ stab_class_method_var (struct stab_write_handle *info, const char *physname,
   else
     typec = '*';
 
+  size_t cur_len = strlen (info->type_stack->methods);
   info->type_stack->methods =
-    (char *) xrealloc (info->type_stack->methods,
-                      (strlen (info->type_stack->methods)
-                       + strlen (type)
-                       + strlen (physname)
-                       + (contextp ? strlen (context) : 0)
-                       + 40));
-
-  sprintf (info->type_stack->methods + strlen (info->type_stack->methods),
-          "%s:%s;%c%c%c", type, physname, visc, qualc, typec);
+    xrealloc (info->type_stack->methods, (cur_len
+                                         + strlen (type)
+                                         + strlen (physname)
+                                         + (contextp ? strlen (context) : 0)
+                                         + 40));
+
+  char *out = info->type_stack->methods + cur_len;
+  out += sprintf (out, "%s:%s;%c%c%c", type, physname, visc, qualc, typec);
   free (type);
 
   if (contextp)
     {
-      sprintf (info->type_stack->methods + strlen (info->type_stack->methods),
-              "%ld;%s;", (long) voffset, context);
+      sprintf (out, "%ld;%s;", (long) voffset, context);
       free (context);
     }
 
   if (definition)
-    info->type_stack->definition = TRUE;
+    info->type_stack->definition = true;
 
-  return TRUE;
+  return true;
 }
 
 /* Add a variant to the current method.  */
 
-static bfd_boolean
+static bool
 stab_class_method_variant (void *p, const char *physname,
                           enum debug_visibility visibility,
-                          bfd_boolean constp, bfd_boolean volatilep,
-                          bfd_vma voffset, bfd_boolean contextp)
+                          bool constp, bool volatilep,
+                          bfd_vma voffset, bool contextp)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
 
-  return stab_class_method_var (info, physname, visibility, FALSE, constp,
+  return stab_class_method_var (info, physname, visibility, false, constp,
                                volatilep, voffset, contextp);
 }
 
 /* Add a static variant to the current method.  */
 
-static bfd_boolean
+static bool
 stab_class_static_method_variant (void *p, const char *physname,
                                  enum debug_visibility visibility,
-                                 bfd_boolean constp, bfd_boolean volatilep)
+                                 bool constp, bool volatilep)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
 
-  return stab_class_method_var (info, physname, visibility, TRUE, constp,
-                               volatilep, 0, FALSE);
+  return stab_class_method_var (info, physname, visibility, true, constp,
+                               volatilep, 0, false);
 }
 
 /* Finish up a method.  */
 
-static bfd_boolean
+static bool
 stab_class_end_method (void *p)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
 
-  assert (info->type_stack != NULL && info->type_stack->methods != NULL);
+  if (info->type_stack == NULL || info->type_stack->methods == NULL)
+    return false;
 
   /* We allocated enough room on info->type_stack->methods to add the
      trailing semicolon.  */
   strcat (info->type_stack->methods, ";");
 
-  return TRUE;
+  return true;
 }
 
 /* Finish up a class.  */
 
-static bfd_boolean
+static bool
 stab_end_class_type (void *p)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -1783,7 +1773,10 @@ stab_end_class_type (void *p)
   unsigned int i = 0;
   char *buf;
 
-  assert (info->type_stack != NULL && info->type_stack->fields != NULL);
+  if (info->type_stack == NULL
+      || info->type_stack->string == NULL
+      || info->type_stack->fields == NULL)
+    return false;
 
   /* Work out the size we need to allocate for the class definition.  */
 
@@ -1803,38 +1796,38 @@ stab_end_class_type (void *p)
 
   /* Build the class definition.  */
 
-  buf = (char *) xmalloc (len);
+  buf = xmalloc (len);
 
-  strcpy (buf, info->type_stack->string);
+  char *out = stpcpy (buf, info->type_stack->string);
 
   if (info->type_stack->baseclasses != NULL)
     {
-      sprintf (buf + strlen (buf), "!%u,", i);
+      out += sprintf (out, "!%u,", i);
       for (i = 0; info->type_stack->baseclasses[i] != NULL; i++)
        {
-         strcat (buf, info->type_stack->baseclasses[i]);
+         out = stpcpy (out, info->type_stack->baseclasses[i]);
          free (info->type_stack->baseclasses[i]);
        }
       free (info->type_stack->baseclasses);
       info->type_stack->baseclasses = NULL;
     }
 
-  strcat (buf, info->type_stack->fields);
+  out = stpcpy (out, info->type_stack->fields);
   free (info->type_stack->fields);
   info->type_stack->fields = NULL;
 
   if (info->type_stack->methods != NULL)
     {
-      strcat (buf, info->type_stack->methods);
+      out = stpcpy (out, info->type_stack->methods);
       free (info->type_stack->methods);
       info->type_stack->methods = NULL;
     }
 
-  strcat (buf, ";");
+  out = stpcpy (out, ";");
 
   if (info->type_stack->vtable != NULL)
     {
-      strcat (buf, info->type_stack->vtable);
+      out = stpcpy (out, info->type_stack->vtable);
       free (info->type_stack->vtable);
       info->type_stack->vtable = NULL;
     }
@@ -1844,92 +1837,91 @@ stab_end_class_type (void *p)
   free (info->type_stack->string);
   info->type_stack->string = buf;
 
-  return TRUE;
+  return true;
 }
 
 /* Push a typedef which was previously defined.  */
 
-static bfd_boolean
+static bool
 stab_typedef_type (void *p, const char *name)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
   struct string_hash_entry *h;
 
-  h = string_hash_lookup (&info->typedef_hash, name, FALSE, FALSE);
-  assert (h != NULL && h->index > 0);
+  h = string_hash_lookup (&info->typedef_hash, name, false, false);
+  if (h == NULL || h->index < 1)
+    return false;
 
   return stab_push_defined_type (info, h->index, h->size);
 }
 
 /* Push a struct, union or class tag.  */
 
-static bfd_boolean
+static bool
 stab_tag_type (void *p, const char *name, unsigned int id,
               enum debug_type_kind kind)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  long index;
-  unsigned int size;
+  long tindex;
+  unsigned int size = 0;
 
-  index = stab_get_struct_index (info, name, id, kind, &size);
-  if (index < 0)
-    return FALSE;
+  tindex = stab_get_struct_index (info, name, id, kind, &size);
+  if (tindex < 0)
+    return false;
 
-  return stab_push_defined_type (info, index, size);
+  return stab_push_defined_type (info, tindex, size);
 }
 
 /* Define a typedef.  */
 
-static bfd_boolean
+static bool
 stab_typdef (void *p, const char *name)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
-  long index;
+  long tindex;
   unsigned int size;
   char *s, *buf;
   struct string_hash_entry *h;
 
-  index = info->type_stack->index;
+  tindex = info->type_stack->index;
   size = info->type_stack->size;
   s = stab_pop_type (info);
 
-  buf = (char *) xmalloc (strlen (name) + strlen (s) + 20);
+  buf = xmalloc (strlen (name) + strlen (s) + 20);
 
-  if (index > 0)
+  if (tindex > 0)
     sprintf (buf, "%s:t%s", name, s);
   else
     {
-      index = info->type_index;
+      tindex = info->type_index;
       ++info->type_index;
-      sprintf (buf, "%s:t%ld=%s", name, index, s);
+      sprintf (buf, "%s:t%ld=%s", name, tindex, s);
     }
 
   free (s);
 
-  if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
-    return FALSE;
+  if (!stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf))
+    return false;
 
-  free (buf);
-
-  h = string_hash_lookup (&info->typedef_hash, name, TRUE, FALSE);
+  h = string_hash_lookup (&info->typedef_hash, name, true, false);
   if (h == NULL)
     {
       non_fatal (_("string_hash_lookup failed: %s"),
                 bfd_errmsg (bfd_get_error ()));
-      return FALSE;
+      return false;
     }
 
   /* I don't think we care about redefinitions.  */
 
-  h->index = index;
+  h->index = tindex;
   h->size = size;
 
-  return TRUE;
+  return true;
 }
 
 /* Define a tag.  */
 
-static bfd_boolean
+static bool
 stab_tag (void *p, const char *tag)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -1937,60 +1929,45 @@ stab_tag (void *p, const char *tag)
 
   s = stab_pop_type (info);
 
-  buf = (char *) xmalloc (strlen (tag) + strlen (s) + 3);
+  buf = xmalloc (strlen (tag) + strlen (s) + 3);
 
   sprintf (buf, "%s:T%s", tag, s);
   free (s);
 
-  if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf);
 }
 
 /* Define an integer constant.  */
 
-static bfd_boolean
+static bool
 stab_int_constant (void *p, const char *name, bfd_vma val)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
   char *buf;
 
-  buf = (char *) xmalloc (strlen (name) + 20);
+  buf = xmalloc (strlen (name) + 20);
   sprintf (buf, "%s:c=i%ld", name, (long) val);
 
-  if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf);
 }
 
 /* Define a floating point constant.  */
 
-static bfd_boolean
+static bool
 stab_float_constant (void *p, const char *name, double val)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
   char *buf;
 
-  buf = (char *) xmalloc (strlen (name) + 20);
+  buf = xmalloc (strlen (name) + 20);
   sprintf (buf, "%s:c=f%g", name, val);
 
-  if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf);
 }
 
 /* Define a typed constant.  */
 
-static bfd_boolean
+static bool
 stab_typed_constant (void *p, const char *name, bfd_vma val)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -1998,21 +1975,16 @@ stab_typed_constant (void *p, const char *name, bfd_vma val)
 
   s = stab_pop_type (info);
 
-  buf = (char *) xmalloc (strlen (name) + strlen (s) + 20);
+  buf = xmalloc (strlen (name) + strlen (s) + 20);
   sprintf (buf, "%s:c=e%s,%ld", name, s, (long) val);
   free (s);
 
-  if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf);
 }
 
 /* Record a variable.  */
 
-static bfd_boolean
+static bool
 stab_variable (void *p, const char *name, enum debug_var_kind kind,
               bfd_vma val)
 {
@@ -2051,12 +2023,12 @@ stab_variable (void *p, const char *name, enum debug_var_kind kind,
       if (! ISDIGIT (*s))
        {
          char *n;
-         long index;
+         long tindex;
 
-         index = info->type_index;
+         tindex = info->type_index;
          ++info->type_index;
-         n = (char *) xmalloc (strlen (s) + 20);
-         sprintf (n, "%ld=%s", index, s);
+         n = xmalloc (strlen (s) + 20);
+         sprintf (n, "%ld=%s", tindex, s);
          free (s);
          s = n;
        }
@@ -2068,49 +2040,41 @@ stab_variable (void *p, const char *name, enum debug_var_kind kind,
       break;
     }
 
-  buf = (char *) xmalloc (strlen (name) + strlen (s) + 3);
+  buf = xmalloc (strlen (name) + strlen (s) + 3);
   sprintf (buf, "%s:%s%s", name, kindstr, s);
   free (s);
 
-  if (! stab_write_symbol (info, stab_type, 0, val, buf))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_write_symbol_and_free (info, stab_type, 0, val, buf);
 }
 
 /* Start outputting a function.  */
 
-static bfd_boolean
-stab_start_function (void *p, const char *name, bfd_boolean globalp)
+static bool
+stab_start_function (void *p, const char *name, bool globalp)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
   char *rettype, *buf;
 
-  assert (info->nesting == 0 && info->fun_offset == -1);
+  if (info->nesting != 0 || info->fun_offset != -1)
+    return false;
 
   rettype = stab_pop_type (info);
 
-  buf = (char *) xmalloc (strlen (name) + strlen (rettype) + 3);
+  buf = xmalloc (strlen (name) + strlen (rettype) + 3);
   sprintf (buf, "%s:%c%s", name,
           globalp ? 'F' : 'f',
           rettype);
+  free (rettype);
 
   /* We don't know the value now, so we set it in start_block.  */
   info->fun_offset = info->symbols_size;
 
-  if (! stab_write_symbol (info, N_FUN, 0, 0, buf))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_write_symbol_and_free (info, N_FUN, 0, 0, buf);
 }
 
 /* Output a function parameter.  */
 
-static bfd_boolean
+static bool
 stab_function_parameter (void *p, const char *name, enum debug_parm_kind kind, bfd_vma val)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -2146,21 +2110,16 @@ stab_function_parameter (void *p, const char *name, enum debug_parm_kind kind, b
       break;
     }
 
-  buf = (char *) xmalloc (strlen (name) + strlen (s) + 3);
+  buf = xmalloc (strlen (name) + strlen (s) + 3);
   sprintf (buf, "%s:%c%s", name, kindc, s);
   free (s);
 
-  if (! stab_write_symbol (info, stab_type, 0, val, buf))
-    return FALSE;
-
-  free (buf);
-
-  return TRUE;
+  return stab_write_symbol_and_free (info, stab_type, 0, val, buf);
 }
 
 /* Start a block.  */
 
-static bfd_boolean
+static bool
 stab_start_block (void *p, bfd_vma addr)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -2189,7 +2148,7 @@ stab_start_block (void *p, bfd_vma addr)
   if (info->nesting == 1)
     {
       info->fnaddr = addr;
-      return TRUE;
+      return true;
     }
 
   /* We have to output the LBRAC symbol after any variables which are
@@ -2201,19 +2160,19 @@ stab_start_block (void *p, bfd_vma addr)
     {
       if (! stab_write_symbol (info, N_LBRAC, 0, info->pending_lbrac,
                               (const char *) NULL))
-       return FALSE;
+       return false;
     }
 
   /* Remember the address and output it later.  */
 
   info->pending_lbrac = addr - info->fnaddr;
 
-  return TRUE;
+  return true;
 }
 
 /* End a block.  */
 
-static bfd_boolean
+static bool
 stab_end_block (void *p, bfd_vma addr)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
@@ -2226,17 +2185,18 @@ stab_end_block (void *p, bfd_vma addr)
     {
       if (! stab_write_symbol (info, N_LBRAC, 0, info->pending_lbrac,
                               (const char *) NULL))
-       return FALSE;
+       return false;
       info->pending_lbrac = (bfd_vma) -1;
     }
 
-  assert (info->nesting > 0);
+  if (info->nesting < 1)
+    return false;
 
   --info->nesting;
 
   /* We ignore the outermost block.  */
   if (info->nesting == 0)
-    return TRUE;
+    return true;
 
   return stab_write_symbol (info, N_RBRAC, 0, addr - info->fnaddr,
                            (const char *) NULL);
@@ -2244,28 +2204,29 @@ stab_end_block (void *p, bfd_vma addr)
 
 /* End a function.  */
 
-static bfd_boolean
+static bool
 stab_end_function (void *p ATTRIBUTE_UNUSED)
 {
-  return TRUE;
+  return true;
 }
 
 /* Output a line number.  */
 
-static bfd_boolean
+static bool
 stab_lineno (void *p, const char *file, unsigned long lineno, bfd_vma addr)
 {
   struct stab_write_handle *info = (struct stab_write_handle *) p;
 
-  assert (info->lineno_filename != NULL);
+  if (info->lineno_filename == NULL)
+    return false;
 
   if (addr > info->last_text_address)
     info->last_text_address = addr;
 
-  if (strcmp (file, info->lineno_filename) != 0)
+  if (filename_cmp (file, info->lineno_filename) != 0)
     {
       if (! stab_write_symbol (info, N_SOL, 0, addr, file))
-       return FALSE;
+       return false;
       info->lineno_filename = file;
     }