This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Statically identified memory leaks in ld


Using a static analysis tool "Clouseau" built as part of
my research, I have identified a number of potential memory leaks 
in ld and the libraries it uses.  The tool assumes a linear model of
memory to automatically identifies potential leaks, but the 
process of fixing them is manual.  I have put together and 
enclosed a patch against bfd/libiberty/ld checked out yesterday 
from the CVS repository that fixes most of the leaks identified 
while building "ld" on a redhat linux machine.  There are others
in other binutils tools, but I have not yet created a patch to fix them.

I tried not to change interfaces (except in ldfile_add_library_path)
where it seemed like the right thing to do.  In some cases I
only added a comment where a leak would be generated.   In places
where leaks are documented in the code, I have left them there.
After applying the patch, I ran the testsuite and it reported no
unexpected failures.

Two of these problems are more important than just a memory
leak because they could could cause memory corruption.
1) aout.h has some code that allocates memory with "bfd_alloc" 
    and can free it with "free".  This would seem to be a problem.
2) _bfd_elf_slurp_version_tables has code that frees memory only 
    when it is NULL.

2003-03-24  David Heine  <dlheine at suif dot stanford,edu>

	* bfd/aoutx.h : Do not free memory allocated with bfd_alloc
	* bfd/dwarf2.c : Fix leaks
	* bfd/elf-eh-frame.c : same
	* bfd/elf.c : Fix leaks and NULL free
	* bfd/elflink.h : Fix leaks
	* bfd/format.c : same
	* bfd/linker.c : same
	* bfd/opncls.c : same
	* bfd/simple.c : same
	* ld/ldfile.c : same
	* ld/ldlang.c : same
	* ld/ldmain.c : same
	* ld/ldmisc.c : same
	* ld/lexsup.c : same
	* libiberty/cp-demangle.c : same
	* libiberty/make-relative-prefix.c : same
	* libiberty/partition.c : same



Index: bfd/aoutx.h
===================================================================
RCS file: /cvs/src/src/bfd/aoutx.h,v
retrieving revision 1.39
diff -c -r1.39 aoutx.h
*** bfd/aoutx.h	31 Dec 2002 07:29:25 -0000	1.39
--- bfd/aoutx.h	24 Mar 2003 17:59:37 -0000
***************
*** 3073,3079 ****
    if (! NAME(aout,link_hash_table_init) (ret, abfd,
  					 NAME(aout,link_hash_newfunc)))
      {
!       free (ret);
        return (struct bfd_link_hash_table *) NULL;
      }
    return &ret->root;
--- 3073,3082 ----
    if (! NAME(aout,link_hash_table_init) (ret, abfd,
  					 NAME(aout,link_hash_newfunc)))
      {
!       /* Can not free the result of bfd_alloc().  Either use bfd_malloc()
! 	 or it must leak.  A free of "ret" could result in
! 	 memory corruption here.
! 	 free (ret); */
        return (struct bfd_link_hash_table *) NULL;
      }
    return &ret->root;
Index: bfd/dwarf2.c
===================================================================
RCS file: /cvs/src/src/bfd/dwarf2.c,v
retrieving revision 1.42
diff -c -r1.42 dwarf2.c
*** bfd/dwarf2.c	12 Dec 2002 10:26:01 -0000	1.42
--- bfd/dwarf2.c	24 Mar 2003 17:59:37 -0000
***************
*** 939,944 ****
--- 939,946 ----
        if (dirname == NULL)
  	return filename;
        else
+ 	/* Concat returns fresh memory. The returned value will
+ 	   leak. */
  	return (char*) concat (dirname, "/", filename, NULL);
      }
  }
Index: bfd/elf-eh-frame.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-eh-frame.c,v
retrieving revision 1.22
diff -c -r1.22 elf-eh-frame.c
*** bfd/elf-eh-frame.c	6 Feb 2003 23:01:04 -0000	1.22
--- bfd/elf-eh-frame.c	24 Mar 2003 17:59:37 -0000
***************
*** 1125,1130 ****
--- 1125,1131 ----
    bfd_byte *contents;
    asection *eh_frame_sec;
    bfd_size_type size;
+   bfd_boolean retval;
  
    htab = elf_hash_table (info);
    hdr_info = &htab->eh_info;
***************
*** 1141,1147 ****
  
    eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
    if (eh_frame_sec == NULL)
!     return FALSE;
  
    memset (contents, 0, EH_FRAME_HDR_SIZE);
    contents[0] = 1;				/* Version  */
--- 1142,1151 ----
  
    eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
    if (eh_frame_sec == NULL)
!     {
!       free (contents);
!       return FALSE;
!     }
  
    memset (contents, 0, EH_FRAME_HDR_SIZE);
    contents[0] = 1;				/* Version  */
***************
*** 1177,1183 ****
  	}
      }
  
!   return bfd_set_section_contents (abfd, sec->output_section,
  				   contents, (file_ptr) sec->output_offset,
                                     sec->_cooked_size);
  }
--- 1181,1189 ----
  	}
      }
  
!   retval = bfd_set_section_contents (abfd, sec->output_section,
  				   contents, (file_ptr) sec->output_offset,
                                     sec->_cooked_size);
+   free (contents);
+   return retval;
  }
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.180
diff -c -r1.180 elf.c
*** bfd/elf.c	24 Feb 2003 18:07:22 -0000	1.180
--- bfd/elf.c	24 Mar 2003 17:59:37 -0000
***************
*** 5068,5074 ****
  	      amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
  	      map = (struct elf_segment_map *) bfd_alloc (obfd, amt);
  	      if (map == NULL)
! 		return FALSE;
  
  	      /* Initialise the fields of the segment map.  Set the physical
  		 physical address to the LMA of the first section that has
--- 5068,5077 ----
  	      amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
  	      map = (struct elf_segment_map *) bfd_alloc (obfd, amt);
  	      if (map == NULL)
! 		{
! 		  free (sections);
! 		  return FALSE;
! 		}
  
  	      /* Initialise the fields of the segment map.  Set the physical
  		 physical address to the LMA of the first section that has
***************
*** 5303,5309 ****
    amt = (bfd_size_type) (1 + symcount) * bed->s->sizeof_sym;
    outbound_syms = bfd_alloc (abfd, amt);
    if (outbound_syms == NULL)
!     return FALSE;
    symtab_hdr->contents = (PTR) outbound_syms;
  
    outbound_shndx = NULL;
--- 5306,5315 ----
    amt = (bfd_size_type) (1 + symcount) * bed->s->sizeof_sym;
    outbound_syms = bfd_alloc (abfd, amt);
    if (outbound_syms == NULL)
!     {
!       _bfd_stringtab_free (stt);
!       return FALSE;
!     }
    symtab_hdr->contents = (PTR) outbound_syms;
  
    outbound_shndx = NULL;
***************
*** 5313,5319 ****
        amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
        outbound_shndx = bfd_zalloc (abfd, amt);
        if (outbound_shndx == NULL)
! 	return FALSE;
        symtab_shndx_hdr->contents = outbound_shndx;
        symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
        symtab_shndx_hdr->sh_size = amt;
--- 5319,5328 ----
        amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
        outbound_shndx = bfd_zalloc (abfd, amt);
        if (outbound_shndx == NULL)
! 	{
! 	  _bfd_stringtab_free (stt);
! 	  return FALSE;
! 	}
        symtab_shndx_hdr->contents = outbound_shndx;
        symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
        symtab_shndx_hdr->sh_size = amt;
***************
*** 5357,5363 ****
  							    syms[idx]->name,
  							    TRUE, FALSE);
  	  if (sym.st_name == (unsigned long) -1)
! 	    return FALSE;
  	}
  
        type_ptr = elf_symbol_from (abfd, syms[idx]);
--- 5366,5375 ----
  							    syms[idx]->name,
  							    TRUE, FALSE);
  	  if (sym.st_name == (unsigned long) -1)
! 	    {
! 	      _bfd_stringtab_free (stt);
! 	      return FALSE;
! 	    }
  	}
  
        type_ptr = elf_symbol_from (abfd, syms[idx]);
***************
*** 5446,5451 ****
--- 5458,5464 ----
  					  syms[idx]->name ? syms[idx]->name : "<Local sym>",
  					  sec->name);
  		      bfd_set_error (bfd_error_invalid_operation);      
+ 		      _bfd_stringtab_free (stt);
  		      return FALSE;
  		    }
    
***************
*** 5906,5912 ****
    return TRUE;
  
   error_return:
!   if (contents == NULL)
      free (contents);
    return FALSE;
  }
--- 5919,5925 ----
    return TRUE;
  
   error_return:
!   if (contents != NULL)
      free (contents);
    return FALSE;
  }
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.209
diff -c -r1.209 elflink.h
*** bfd/elflink.h	6 Mar 2003 15:47:23 -0000	1.209
--- bfd/elflink.h	24 Mar 2003 17:59:38 -0000
***************
*** 4849,4854 ****
--- 4849,4856 ----
  	  }
        }
  
+   free (sort);
+ 
    *psec = reldyn;
    return ret;
  }
Index: bfd/format.c
===================================================================
RCS file: /cvs/src/src/bfd/format.c,v
retrieving revision 1.12
diff -c -r1.12 format.c
*** bfd/format.c	14 Feb 2003 11:16:09 -0000	1.12
--- bfd/format.c	24 Mar 2003 17:59:38 -0000
***************
*** 163,169 ****
    if (!abfd->target_defaulted)
      {
        if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)	/* rewind! */
! 	return FALSE;
  
        right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
  
--- 163,173 ----
    if (!abfd->target_defaulted)
      {
        if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)	/* rewind! */
! 	{
! 	  if (matching)
! 	    free ((PTR) matching_vector);
! 	  return FALSE;
! 	}
  
        right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
  
***************
*** 214,220 ****
        abfd->xvec = *target;	/* Change BFD's target temporarily.  */
  
        if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
! 	return FALSE;
  
        /* If _bfd_check_format neglects to set bfd_error, assume
  	 bfd_error_wrong_format.  We didn't used to even pay any
--- 218,228 ----
        abfd->xvec = *target;	/* Change BFD's target temporarily.  */
  
        if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
! 	{
! 	  if (matching)
! 	    free ((PTR) matching_vector);
! 	  return FALSE;
! 	}
  
        /* If _bfd_check_format neglects to set bfd_error, assume
  	 bfd_error_wrong_format.  We didn't used to even pay any
Index: bfd/linker.c
===================================================================
RCS file: /cvs/src/src/bfd/linker.c,v
retrieving revision 1.29
diff -c -r1.29 linker.c
*** bfd/linker.c	20 Dec 2002 22:41:13 -0000	1.29
--- bfd/linker.c	24 Mar 2003 17:59:38 -0000
***************
*** 2082,2088 ****
  							relocs,
  							symbols);
  		  if (reloc_count < 0)
! 		    return FALSE;
  		  BFD_ASSERT ((unsigned long) reloc_count
  			      == input_section->reloc_count);
  		  o->reloc_count += reloc_count;
--- 2082,2091 ----
  							relocs,
  							symbols);
  		  if (reloc_count < 0)
! 		    {
! 		      free (relocs);
! 		      return FALSE;
! 		    }
  		  BFD_ASSERT ((unsigned long) reloc_count
  			      == input_section->reloc_count);
  		  o->reloc_count += reloc_count;
Index: bfd/opncls.c
===================================================================
RCS file: /cvs/src/src/bfd/opncls.c,v
retrieving revision 1.14
diff -c -r1.14 opncls.c
*** bfd/opncls.c	31 Jan 2003 10:04:16 -0000	1.14
--- bfd/opncls.c	24 Mar 2003 17:59:38 -0000
***************
*** 931,938 ****
  
    basename = get_debug_link_info (abfd, & crc32);
  
!   if (basename == NULL || strlen (basename) < 1)
      return NULL;
  
    dir = xstrdup (abfd->filename);
    BFD_ASSERT (strlen (dir) != 0);
--- 931,943 ----
  
    basename = get_debug_link_info (abfd, & crc32);
  
!   if (basename == NULL)
      return NULL;
+   if (strlen (basename) < 1)
+     {
+       free (basename);
+       return NULL;
+     }
  
    dir = xstrdup (abfd->filename);
    BFD_ASSERT (strlen (dir) != 0);
Index: bfd/simple.c
===================================================================
RCS file: /cvs/src/src/bfd/simple.c,v
retrieving revision 1.5
diff -c -r1.5 simple.c
*** bfd/simple.c	30 Nov 2002 08:39:40 -0000	1.5
--- bfd/simple.c	24 Mar 2003 17:59:38 -0000
***************
*** 208,212 ****
--- 208,214 ----
  
    bfd_link_hash_table_free (abfd, link_info.hash);
  
+   free (symbol_table);
+ 
    return contents;
  }
Index: ld/ldfile.c
===================================================================
RCS file: /cvs/src/src/ld/ldfile.c,v
retrieving revision 1.27
diff -c -r1.27 ldfile.c
*** ld/ldfile.c	19 Mar 2003 09:56:06 -0000	1.27
--- ld/ldfile.c	24 Mar 2003 17:59:38 -0000
***************
*** 78,103 ****
       bfd_boolean cmdline;
  {
    search_dirs_type *new;
  
    if (!cmdline && config.only_cmd_line_lib_dirs)
      return;
  
    new = (search_dirs_type *) xmalloc (sizeof (search_dirs_type));
    new->next = NULL;
-   new->name = name;
    new->cmdline = cmdline;
    *search_tail_ptr = new;
    search_tail_ptr = &new->next;
  
    /* If a directory is marked as honoring sysroot, prepend the sysroot path
       now.  */
!   if (new->name[0] == '=')
      {
!       new->name = concat (ld_sysroot, &new->name[1], NULL);
        new->sysrooted = TRUE;
      }
    else
!     new->sysrooted = FALSE;
  }
  
  /* Try to open a BFD for a lang_input_statement.  */
--- 78,106 ----
       bfd_boolean cmdline;
  {
    search_dirs_type *new;
+   char *newname;
  
    if (!cmdline && config.only_cmd_line_lib_dirs)
      return;
  
    new = (search_dirs_type *) xmalloc (sizeof (search_dirs_type));
    new->next = NULL;
    new->cmdline = cmdline;
    *search_tail_ptr = new;
    search_tail_ptr = &new->next;
  
    /* If a directory is marked as honoring sysroot, prepend the sysroot path
       now.  */
!   if (name[0] == '=')
      {
!       new->name = concat (ld_sysroot, name+1, NULL);
        new->sysrooted = TRUE;
      }
    else
!     {
!       new->name = xstrdup(name);
!       new->sysrooted = FALSE;
!     }
  }
  
  /* Try to open a BFD for a lang_input_statement.  */
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.110
diff -c -r1.110 ldlang.c
*** ld/ldlang.c	3 Mar 2003 20:00:35 -0000	1.110
--- ld/ldlang.c	24 Mar 2003 17:59:38 -0000
***************
*** 5276,5281 ****
--- 5276,5282 ----
        || (lang_elf_version_info && lang_elf_version_info->name[0] == '\0'))
      {
        einfo (_("%X%P: anonymous version tag cannot be combined with other version tags\n"));
+       /* Leak of version. */
        return;
      }
  
Index: ld/ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.64
diff -c -r1.64 ldmain.c
*** ld/ldmain.c	3 Mar 2003 20:01:02 -0000	1.64
--- ld/ldmain.c	24 Mar 2003 17:59:38 -0000
***************
*** 663,684 ****
  
    dir = make_relative_prefix (program_name, BINDIR, SCRIPTDIR);
    if (dir && check_for_scripts_dir (dir))
!     /* Success.  Don't free dir.  */
!     return;
  
    if (dir)
      free (dir);
  
    dir = make_relative_prefix (program_name, TOOLBINDIR, SCRIPTDIR);
    if (dir && check_for_scripts_dir (dir))
!     /* Success.  Don't free dir.  */
!     return;
  
    if (dir)
      free (dir);
  
    if (check_for_scripts_dir (SCRIPTDIR))
-     /* We've been installed normally.  */
      return;
  
    /* Look for "ldscripts" in the dir where our binary is.  */
--- 663,687 ----
  
    dir = make_relative_prefix (program_name, BINDIR, SCRIPTDIR);
    if (dir && check_for_scripts_dir (dir))
!     {
!       free(dir);
!       return;
!     }
  
    if (dir)
      free (dir);
  
    dir = make_relative_prefix (program_name, TOOLBINDIR, SCRIPTDIR);
    if (dir && check_for_scripts_dir (dir))
!     {
!       free (dir);
!       return;
!     }
  
    if (dir)
      free (dir);
  
    if (check_for_scripts_dir (SCRIPTDIR))
      return;
  
    /* Look for "ldscripts" in the dir where our binary is.  */
***************
*** 706,718 ****
    dir[dirlen] = '\0';
  
    if (check_for_scripts_dir (dir))
!     /* Don't free dir.  */
!     return;
  
    /* Look for "ldscripts" in <the dir where our binary is>/../lib.  */
    strcpy (dir + dirlen, "/../lib");
    if (check_for_scripts_dir (dir))
!     return;
  
    /* Well, we tried.  */
    free (dir);
--- 709,726 ----
    dir[dirlen] = '\0';
  
    if (check_for_scripts_dir (dir))
!     {
!       free (dir);
!       return;
!     }
  
    /* Look for "ldscripts" in <the dir where our binary is>/../lib.  */
    strcpy (dir + dirlen, "/../lib");
    if (check_for_scripts_dir (dir))
!     {
!       free (dir);
!       return;
!     }
  
    /* Well, we tried.  */
    free (dir);
***************
*** 820,825 ****
--- 828,834 ----
    if (link_info.strip != strip_none)
      einfo (_("%P: `-retain-symbols-file' overrides `-s' and `-S'\n"));
  
+   free (buf);
    link_info.strip = strip_some;
  }
  
Index: ld/ldmisc.c
===================================================================
RCS file: /cvs/src/src/ld/ldmisc.c,v
retrieving revision 1.14
diff -c -r1.14 ldmisc.c
*** ld/ldmisc.c	30 Nov 2002 08:39:45 -0000	1.14
--- ld/ldmisc.c	24 Mar 2003 17:59:38 -0000
***************
*** 328,333 ****
--- 328,336 ----
  		      fprintf (fp, ":%u", linenumber);
  		  }
  
+ 		if (asymbols != NULL && entry == NULL)
+ 		  free (asymbols);
+ 
  		if (discard_last)
  		  {
  		    last_bfd = NULL;
Index: ld/lexsup.c
===================================================================
RCS file: /cvs/src/src/ld/lexsup.c,v
retrieving revision 1.60
diff -c -r1.60 lexsup.c
*** ld/lexsup.c	28 Feb 2003 01:32:30 -0000	1.60
--- ld/lexsup.c	24 Mar 2003 17:59:38 -0000
***************
*** 1116,1121 ****
--- 1116,1123 ----
  	case 'Y':
  	  if (strncmp (optarg, "P,", 2) == 0)
  	    optarg += 2;
+ 	  if (default_dirlist != NULL)
+ 	    free (default_dirlist);
  	  default_dirlist = xstrdup (optarg);
  	  break;
  	case 'y':
***************
*** 1193,1200 ****
      lang_leave_group ();
  
    if (default_dirlist != NULL)
!     set_default_dirlist (default_dirlist);
! 
  }
  
  /* Add the (colon-separated) elements of DIRLIST_PTR to the
--- 1195,1204 ----
      lang_leave_group ();
  
    if (default_dirlist != NULL)
!     {
!       set_default_dirlist (default_dirlist);
!       free (default_dirlist);
!     }
  }
  
  /* Add the (colon-separated) elements of DIRLIST_PTR to the
Index: libiberty/cp-demangle.c
===================================================================
RCS file: /cvs/src/src/libiberty/cp-demangle.c,v
retrieving revision 1.27
diff -c -r1.27 cp-demangle.c
*** libiberty/cp-demangle.c	20 Sep 2002 13:45:20 -0000	1.27
--- libiberty/cp-demangle.c	24 Mar 2003 17:59:39 -0000
***************
*** 225,230 ****
--- 225,242 ----
      }                                                                   \
    while (0)
  
+ #define CLEANUP_IF_ERROR(EXPR)                                          \
+   do                                                                    \
+     {                                                                   \
+       status_t s = EXPR;                                                \
+       if (!STATUS_NO_ERROR (s))                                         \
+         {                                                               \
+           error_status = s;                                             \
+           goto err_return;                                              \
+         }                                                               \
+     }                                                                   \
+   while (0)
+ 
  static status_t int_to_dyn_string 
    PARAMS ((int, dyn_string_t));
  static string_list_t string_list_new
***************
*** 422,428 ****
    if (s == NULL)
      return NULL;
    if (!dyn_string_init ((dyn_string_t) s, length))
!     return NULL;
    return s;
  }  
  
--- 434,443 ----
    if (s == NULL)
      return NULL;
    if (!dyn_string_init ((dyn_string_t) s, length))
!     {
!       free (s);
!       return NULL;
!     }
    return s;
  }  
  
***************
*** 826,837 ****
    dm->template_arg_lists = NULL;
    dm->last_source_name = dyn_string_new (0);
    if (dm->last_source_name == NULL)
!     return NULL;
    dm->substitutions = (struct substitution_def *)
      malloc (dm->substitutions_allocated * sizeof (struct substitution_def));
    if (dm->substitutions == NULL)
      {
        dyn_string_delete (dm->last_source_name);
        return NULL;
      }
    dm->style = style;
--- 841,856 ----
    dm->template_arg_lists = NULL;
    dm->last_source_name = dyn_string_new (0);
    if (dm->last_source_name == NULL)
!     {
!       free (dm);
!       return NULL;
!     }
    dm->substitutions = (struct substitution_def *)
      malloc (dm->substitutions_allocated * sizeof (struct substitution_def));
    if (dm->substitutions == NULL)
      {
        dyn_string_delete (dm->last_source_name);
+       free (dm);
        return NULL;
      }
    dm->style = style;
***************
*** 2986,2994 ****
    int first = 1;
    dyn_string_t old_last_source_name;
    template_arg_list_t arg_list = template_arg_list_new ();
  
    if (arg_list == NULL)
!     return STATUS_ALLOCATION_FAILED;
  
    /* Preserve the most recently demangled source name.  */
    old_last_source_name = dm->last_source_name;
--- 3005,3017 ----
    int first = 1;
    dyn_string_t old_last_source_name;
    template_arg_list_t arg_list = template_arg_list_new ();
+   status_t error_status = STATUS_OK;
+ 
  
    if (arg_list == NULL)
!     {
!       return STATUS_ALLOCATION_FAILED;
!     }
  
    /* Preserve the most recently demangled source name.  */
    old_last_source_name = dm->last_source_name;
***************
*** 2997,3006 ****
    DEMANGLE_TRACE ("template-args", dm);
  
    if (dm->last_source_name == NULL)
!     return STATUS_ALLOCATION_FAILED;
  
!   RETURN_IF_ERROR (demangle_char (dm, 'I'));
!   RETURN_IF_ERROR (result_open_template_list (dm));
    do
      {
        string_list_t arg;
--- 3020,3032 ----
    DEMANGLE_TRACE ("template-args", dm);
  
    if (dm->last_source_name == NULL)
!     {
!       template_arg_list_delete (arg_list);
!       return STATUS_ALLOCATION_FAILED;
!     }
  
!   CLEANUP_IF_ERROR (demangle_char (dm, 'I'));
!   CLEANUP_IF_ERROR (result_open_template_list (dm));
    do
      {
        string_list_t arg;
***************
*** 3008,3029 ****
        if (first)
  	first = 0;
        else
! 	RETURN_IF_ERROR (result_add (dm, ", "));
  
        /* Capture the template arg.  */
!       RETURN_IF_ERROR (result_push (dm));
!       RETURN_IF_ERROR (demangle_template_arg (dm));
        arg = result_pop (dm);
  
        /* Emit it in the demangled name.  */
!       RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
  
        /* Save it for use in expanding <template-param>s.  */
        template_arg_list_add_arg (arg_list, arg);
      }
    while (peek_char (dm) != 'E');
    /* Append the '>'.  */
!   RETURN_IF_ERROR (result_close_template_list (dm));
  
    /* Consume the 'E'.  */
    advance_char (dm);
--- 3034,3055 ----
        if (first)
  	first = 0;
        else
! 	CLEANUP_IF_ERROR (result_add (dm, ", "));
  
        /* Capture the template arg.  */
!       CLEANUP_IF_ERROR (result_push (dm));
!       CLEANUP_IF_ERROR (demangle_template_arg (dm));
        arg = result_pop (dm);
  
        /* Emit it in the demangled name.  */
!       CLEANUP_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
  
        /* Save it for use in expanding <template-param>s.  */
        template_arg_list_add_arg (arg_list, arg);
      }
    while (peek_char (dm) != 'E');
    /* Append the '>'.  */
!   CLEANUP_IF_ERROR (result_close_template_list (dm));
  
    /* Consume the 'E'.  */
    advance_char (dm);
***************
*** 3038,3043 ****
--- 3064,3075 ----
    push_template_arg_list (dm, arg_list);
  
    return STATUS_OK;
+ 
+ err_return:
+   if (arg_list != NULL)
+     template_arg_list_delete(arg_list);
+   return error_status;
+ 
  }
  
  /* This function, which does not correspond to a production in the
***************
*** 3578,3584 ****
  	{
  	  dyn_string_t demangled = (dyn_string_t) result_pop (dm);
  	  if (!dyn_string_copy (result, demangled))
! 	    return STATUS_ALLOCATION_FAILED;
  	  dyn_string_delete (demangled);
  	}
        
--- 3610,3620 ----
  	{
  	  dyn_string_t demangled = (dyn_string_t) result_pop (dm);
  	  if (!dyn_string_copy (result, demangled))
! 	    {
! 	      dyn_string_delete (demangled);
! 	      demangling_delete (dm);
! 	      return STATUS_ALLOCATION_FAILED;
! 	    }
  	  dyn_string_delete (demangled);
  	}
        
***************
*** 3628,3634 ****
  	 it into RESULT.  */
        dyn_string_t demangled = (dyn_string_t) result_pop (dm);
        if (!dyn_string_copy (result, demangled))
! 	return STATUS_ALLOCATION_FAILED;
        dyn_string_delete (demangled);
      }
  
--- 3664,3674 ----
  	 it into RESULT.  */
        dyn_string_t demangled = (dyn_string_t) result_pop (dm);
        if (!dyn_string_copy (result, demangled))
! 	{
! 	  dyn_string_delete (demangled);
! 	  demangling_delete (dm);
! 	  return STATUS_ALLOCATION_FAILED;
! 	}
        dyn_string_delete (demangled);
      }
  
***************
*** 3898,3904 ****
  	  /* There are no more arrays. Copy the rest of the symbol, or
  	     simply return the original symbol if no changes were made. */
  	  if (next == cplus_demangled)
! 	    return cplus_demangled;
  
            dyn_string_append_cstr (demangled, next);
  	  next = end;
--- 3938,3949 ----
  	  /* There are no more arrays. Copy the rest of the symbol, or
  	     simply return the original symbol if no changes were made. */
  	  if (next == cplus_demangled)
! 	    {
! 	      /* Demangled must be NULL here so it need to be freed. */
! 	      if (demangled)
! 		dyn_string_delete (demangled);
! 	      return cplus_demangled;
! 	    }
  
            dyn_string_append_cstr (demangled, next);
  	  next = end;
Index: libiberty/make-relative-prefix.c
===================================================================
RCS file: /cvs/src/src/libiberty/make-relative-prefix.c,v
retrieving revision 1.4
diff -c -r1.4 make-relative-prefix.c
*** libiberty/make-relative-prefix.c	20 Feb 2003 22:13:32 -0000	1.4
--- libiberty/make-relative-prefix.c	24 Mar 2003 17:59:39 -0000
***************
*** 301,310 ****
      return NULL;
  
    prog_dirs = split_directories (full_progname, &prog_num);
-   bin_dirs = split_directories (bin_prefix, &bin_num);
    free (full_progname);
!   if (bin_dirs == NULL || prog_dirs == NULL)
      return NULL;
  
    /* Remove the program name from comparison of directory names.  */
    prog_num--;
--- 301,315 ----
      return NULL;
  
    prog_dirs = split_directories (full_progname, &prog_num);
    free (full_progname);
!   if (prog_dirs == NULL)
      return NULL;
+   bin_dirs = split_directories (bin_prefix, &bin_num);
+   if (bin_dirs == NULL)
+     {
+       free_split_directories (prog_dirs);
+       return NULL;
+     }
  
    /* Remove the program name from comparison of directory names.  */
    prog_num--;
***************
*** 367,373 ****
  
    ret = (char *) malloc (needed_len);
    if (ret == NULL)
!     return NULL;
  
    /* Build up the pathnames in argv[0].  */
    *ret = '\0';
--- 372,383 ----
  
    ret = (char *) malloc (needed_len);
    if (ret == NULL)
!     {
!       free_split_directories (prog_dirs);
!       free_split_directories (bin_dirs);
!       free_split_directories (prefix_dirs);
!       return NULL;
!     }
  
    /* Build up the pathnames in argv[0].  */
    *ret = '\0';
Index: libiberty/partition.c
===================================================================
RCS file: /cvs/src/src/libiberty/partition.c,v
retrieving revision 1.4
diff -c -r1.4 partition.c
*** libiberty/partition.c	16 May 2001 21:04:30 -0000	1.4
--- libiberty/partition.c	24 Mar 2003 17:59:39 -0000
***************
*** 186,191 ****
--- 186,192 ----
        }
    fputc (']', fp);
  
+   free (class_elements);
    free (done);
  }
  



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]