+2008-02-20 Nick Clifton <nickc@redhat.com>
+
+ PR 868
+ * libbfd.c (bfd_realloc_or_free): New function. Performs like
+ bfd_realloc, but if the (re)allocation fails, the pointer is
+ freed.
+ * libbfd-in.h: Prototype.
+ * libbfd.h: Regenerate.
+ * bfdio.c (bfd_bwrite): Use the new function.
+ (bfd_seek): Likewise.
+ * bfdwin.c:(bfd_get_file_window): Likewise.
+ * elf-strtab.c (_bfd_elf_strtab_add): Likewise.
+ * elf32-ppc.c (ppc_elf_relax_section): Likewise.
+ * elf32-xtensa.c (vsprintf_msg): Likewise.
+ * mach-o.c (bfd_mach_o_core_fetch_environment): Likewise.
+ * stabs.c (_bfd_link_seciton_stabs): Likewise.
+ * vms-misc.c (_bfd_vms_get_record): Likewise.
+ * vms-tir.c (check_section): Likewise.
+ * vms.c (vms_new_section_hook): Likewise.
+ * elf32-arm.c (elf32_arm_section_map_add): Check that the
+ allocation of sec_data->map succeeded before using it.
+ * elflink.c (elf_link_output_sym): Do not overwrite finfo->
+ symshndxbuf until it is known that the reallocation succeeded.
+
2008-02-20 Diogo de Carvalho Kraemer <diogo@kraemer.eng.br>
Nick Clifton <nickc@redhat.com>
/* Low-level I/O routines for BFDs.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Written by Cygnus Support.
newsize = (bim->size + 127) & ~(bfd_size_type) 127;
if (newsize > oldsize)
{
- bim->buffer = bfd_realloc (bim->buffer, newsize);
- if (bim->buffer == 0)
+ bim->buffer = bfd_realloc_or_free (bim->buffer, newsize);
+ if (bim->buffer == NULL)
{
bim->size = 0;
return 0;
newsize = (bim->size + 127) & ~(bfd_size_type) 127;
if (newsize > oldsize)
{
- bim->buffer = bfd_realloc (bim->buffer, newsize);
- if (bim->buffer == 0)
+ bim->buffer = bfd_realloc_or_free (bim->buffer, newsize);
+ if (bim->buffer == NULL)
{
bim->size = 0;
return -1;
/* Support for memory-mapped windows into a BFD.
- Copyright 1995, 1996, 2001, 2002, 2003, 2005, 2007
+ Copyright 1995, 1996, 2001, 2002, 2003, 2005, 2007, 2008
Free Software Foundation, Inc.
Written by Cygnus Support.
if (debug_windows)
fprintf (stderr, "\n\t%s(%6ld)",
i->data ? "realloc" : " malloc", (long) size_to_alloc);
- i->data = bfd_realloc (i->data, size_to_alloc);
+ i->data = bfd_realloc_or_free (i->data, size_to_alloc);
if (debug_windows)
fprintf (stderr, "\t-> %p\n", i->data);
- i->refcount = 1;
if (i->data == NULL)
{
if (size_to_alloc == 0)
return TRUE;
return FALSE;
}
+ i->refcount = 1;
if (bfd_seek (abfd, offset, SEEK_SET) != 0)
return FALSE;
i->size = bfd_bread (i->data, size, abfd);
if (tmp == NULL)
{
free (table->dirs);
+ free (table);
return NULL;
}
table->dirs = tmp;
/* ELF strtab with GC and suffix merging support.
- Copyright 2001, 2002, 2003, 2005, 2006, 2007
+ Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Written by Jakub Jelinek <jakub@redhat.com>.
{
bfd_size_type amt = sizeof (struct elf_strtab_hash_entry *);
tab->alloced *= 2;
- tab->array = bfd_realloc (tab->array, tab->alloced * amt);
+ tab->array = bfd_realloc_or_free (tab->array, tab->alloced * amt);
if (tab->array == NULL)
return (bfd_size_type) -1;
}
if (sec_data->mapcount > sec_data->mapsize)
{
sec_data->mapsize *= 2;
- sec_data->map = bfd_realloc (sec_data->map, sec_data->mapsize
- * sizeof (elf32_arm_section_map));
+ sec_data->map = bfd_realloc_or_free (sec_data->map, sec_data->mapsize
+ * sizeof (elf32_arm_section_map));
+ }
+
+ if (sec_data->map)
+ {
+ sec_data->map[newidx].vma = vma;
+ sec_data->map[newidx].type = type;
}
-
- sec_data->map[newidx].vma = vma;
- sec_data->map[newidx].type = type;
}
}
while (fixups);
- contents = bfd_realloc (contents, trampoff);
+ contents = bfd_realloc_or_free (contents, trampoff);
if (contents == NULL)
goto error_return;
/* Xtensa-specific support for 32-bit ELF.
- Copyright 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
len = orig_len + strlen (fmt) + arglen + 20;
if (len > alloc_size)
{
- message = (char *) bfd_realloc (message, len);
+ message = (char *) bfd_realloc_or_free (message, len);
alloc_size = len;
}
- if (!is_append)
- memcpy (message, origmsg, orig_len);
- vsprintf (message + orig_len, fmt, ap);
+ if (message != NULL)
+ {
+ if (!is_append)
+ memcpy (message, origmsg, orig_len);
+ vsprintf (message + orig_len, fmt, ap);
+ }
VA_CLOSE (ap);
return message;
}
bfd_size_type amt;
amt = finfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx);
- finfo->symshndxbuf = destshndx = bfd_realloc (destshndx, amt * 2);
+ destshndx = bfd_realloc (destshndx, amt * 2);
if (destshndx == NULL)
return FALSE;
+ finfo->symshndxbuf = destshndx;
memset ((char *) destshndx + amt, 0, amt);
finfo->shndxbuf_size *= 2;
}
(bfd_size_type);
extern void *bfd_realloc
(void *, bfd_size_type);
+extern void *bfd_realloc_or_free
+ (void *, bfd_size_type);
extern void *bfd_zmalloc
(bfd_size_type);
extern void *bfd_malloc2
/* Assorted BFD support routines, only used internally.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2007
+ 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
Free Software Foundation, Inc.
Written by Cygnus Support.
return ret;
}
+/* Reallocate memory using realloc.
+ If this fails the pointer is freed before returning. */
+
+void *
+bfd_realloc_or_free (void *ptr, bfd_size_type size)
+{
+ size_t amount = (size_t) size;
+ void *ret;
+
+ if (size != amount)
+ ret = NULL;
+ else if (ptr == NULL)
+ ret = malloc (amount);
+ else
+ ret = realloc (ptr, amount);
+
+ if (ret == NULL)
+ {
+ if (amount > 0)
+ bfd_set_error (bfd_error_no_memory);
+
+ if (ptr != NULL)
+ free (ptr);
+ }
+
+ return ret;
+}
+
/* Allocate memory using malloc and clear it. */
void *
(bfd_size_type);
extern void *bfd_realloc
(void *, bfd_size_type);
+extern void *bfd_realloc_or_free
+ (void *, bfd_size_type);
extern void *bfd_zmalloc
(bfd_size_type);
extern void *bfd_malloc2
/* Mach-O support for BFD.
- Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
if (size > (end - start))
size = (end - start);
- buf = bfd_realloc (buf, size);
-
+ buf = bfd_realloc_or_free (buf, size);
+ if (buf == NULL)
+ return -1;
+
bfd_seek (abfd, end - size, SEEK_SET);
nread = bfd_bread (buf, size, abfd);
if (nread != size)
- return -1;
+ {
+ free (buf);
+ return -1;
+ }
for (offset = 4; offset <= size; offset += 4)
{
*rlen = top - bottom;
memcpy (*rbuf, buf + size - *rlen, *rlen);
+ free (buf);
return 0;
}
}
size *= 2;
}
+
+ free (buf);
}
}
if (num_chars >= buf_len)
{
buf_len += 32 * 1024;
- symb = bfd_realloc (symb, buf_len);
+ symb = bfd_realloc_or_free (symb, buf_len);
if (symb == NULL)
goto error_return;
symb_rover = symb + num_chars;
goto error_return;
t->sum_chars = sum_chars;
t->num_chars = num_chars;
- t->symb = bfd_realloc (symb, num_chars); /* Trim data down. */
+ t->symb = symb = bfd_realloc_or_free (symb, num_chars); /* Trim data down. */
t->next = incl_entry->totals;
incl_entry->totals = t;
}
/* vms-misc.c -- Miscellaneous functions for VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008 Free Software Foundation, Inc.
Written by Klaus K"ampf (kkaempf@rmi.de)
if (PRIV (rec_length) > PRIV (buf_size))
{
- PRIV (vms_buf) = bfd_realloc (vms_buf,
+ PRIV (vms_buf) = bfd_realloc_or_free (vms_buf,
(bfd_size_type) PRIV (rec_length));
vms_buf = PRIV (vms_buf);
if (vms_buf == 0)
/* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008
Free Software Foundation, Inc.
TIR record handling functions
if (offset + size > PRIV (image_section)->size)
{
PRIV (image_section)->contents
- = bfd_realloc (PRIV (image_section)->contents, offset + size);
- if (PRIV (image_section)->contents == 0)
+ = bfd_realloc_or_free (PRIV (image_section)->contents, offset + size);
+ if (PRIV (image_section)->contents == NULL)
{
(*_bfd_error_handler) (_("No Mem !"));
return -1;
amt = idx + 1;
amt *= sizeof (asection *);
- PRIV (sections) = bfd_realloc (PRIV (sections), amt);
- if (PRIV (sections) == 0)
+ PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt);
+ if (PRIV (sections) == NULL)
return -1;
while (PRIV (section_count) <= idx)
/* vms.c -- BFD back-end for VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007 Free Software Foundation, Inc.
+ 2006, 2007, 2008 Free Software Foundation, Inc.
Written by Klaus K"ampf (kkaempf@rmi.de)
{
bfd_size_type amt = section_count;
amt *= sizeof (asection *);
- PRIV (sections) = bfd_realloc (PRIV (sections), amt);
+ PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt);
if (PRIV (sections) == NULL)
return FALSE;
PRIV (section_count) = section_count;