From 515ef31dec50185cc5d8a6f88b51832bfd259e87 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 20 Feb 2008 17:42:36 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 24 ++++++++++++++++++++++++ bfd/bfdio.c | 10 +++++----- bfd/bfdwin.c | 6 +++--- bfd/dwarf2.c | 1 + bfd/elf-strtab.c | 4 ++-- bfd/elf32-arm.c | 13 ++++++++----- bfd/elf32-ppc.c | 2 +- bfd/elf32-xtensa.c | 13 ++++++++----- bfd/elflink.c | 3 ++- bfd/libbfd-in.h | 2 ++ bfd/libbfd.c | 30 +++++++++++++++++++++++++++++- bfd/libbfd.h | 2 ++ bfd/mach-o.c | 16 ++++++++++++---- bfd/stabs.c | 4 ++-- bfd/vms-misc.c | 4 ++-- bfd/vms-tir.c | 10 +++++----- bfd/vms.c | 4 ++-- 17 files changed, 110 insertions(+), 38 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9a456482880..a9d7988393c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,27 @@ +2008-02-20 Nick Clifton + + 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 Nick Clifton diff --git a/bfd/bfdio.c b/bfd/bfdio.c index 080cd947f81..d8aa1de9992 100644 --- a/bfd/bfdio.c +++ b/bfd/bfdio.c @@ -1,7 +1,7 @@ /* 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. @@ -174,8 +174,8 @@ bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd) 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; @@ -298,8 +298,8 @@ bfd_seek (bfd *abfd, file_ptr position, int direction) 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; diff --git a/bfd/bfdwin.c b/bfd/bfdwin.c index a44265efa75..dfe89cb45c3 100644 --- a/bfd/bfdwin.c +++ b/bfd/bfdwin.c @@ -1,5 +1,5 @@ /* 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. @@ -224,16 +224,16 @@ bfd_get_file_window (bfd *abfd, 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); diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index 7ad218e6a0f..830b747108a 100644 --- a/bfd/dwarf2.c +++ b/bfd/dwarf2.c @@ -1255,6 +1255,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash) if (tmp == NULL) { free (table->dirs); + free (table); return NULL; } table->dirs = tmp; diff --git a/bfd/elf-strtab.c b/bfd/elf-strtab.c index 018c42cbc1f..f5013d15e4a 100644 --- a/bfd/elf-strtab.c +++ b/bfd/elf-strtab.c @@ -1,5 +1,5 @@ /* 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 . @@ -166,7 +166,7 @@ _bfd_elf_strtab_add (struct elf_strtab_hash *tab, { 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; } diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 7218ba8c3c9..6f66a7150df 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -2948,12 +2948,15 @@ elf32_arm_section_map_add (asection *sec, char type, bfd_vma vma) 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; } diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index a301638eac5..0e215932de1 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -5540,7 +5540,7 @@ ppc_elf_relax_section (bfd *abfd, } while (fixups); - contents = bfd_realloc (contents, trampoff); + contents = bfd_realloc_or_free (contents, trampoff); if (contents == NULL) goto error_return; diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 05ee9dfcf38..ec6d4636e2a 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -1,5 +1,5 @@ /* 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. @@ -1758,12 +1758,15 @@ vsprint_msg (const char *origmsg, const char *fmt, int arglen, ...) 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; } diff --git a/bfd/elflink.c b/bfd/elflink.c index a00634be52b..ab19be255a6 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -8180,9 +8180,10 @@ elf_link_output_sym (struct elf_final_link_info *finfo, 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; } diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index ec11bd5d6b0..f57d450a4fb 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -99,6 +99,8 @@ extern void *bfd_malloc (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 diff --git a/bfd/libbfd.c b/bfd/libbfd.c index bf49a2e1db1..a225397c3e7 100644 --- a/bfd/libbfd.c +++ b/bfd/libbfd.c @@ -1,6 +1,6 @@ /* 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. @@ -265,6 +265,34 @@ bfd_realloc2 (void *ptr, bfd_size_type nmemb, bfd_size_type size) 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 * diff --git a/bfd/libbfd.h b/bfd/libbfd.h index cb6544a009a..cfc364f2435 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -104,6 +104,8 @@ extern void *bfd_malloc (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 diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 166dd6551ec..bde89b04034 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -1,5 +1,5 @@ /* 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. @@ -1923,13 +1923,18 @@ bfd_mach_o_core_fetch_environment (bfd *abfd, 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) { @@ -1952,6 +1957,7 @@ bfd_mach_o_core_fetch_environment (bfd *abfd, *rlen = top - bottom; memcpy (*rbuf, buf + size - *rlen, *rlen); + free (buf); return 0; } } @@ -1961,6 +1967,8 @@ bfd_mach_o_core_fetch_environment (bfd *abfd, size *= 2; } + + free (buf); } } diff --git a/bfd/stabs.c b/bfd/stabs.c index a9fe409f1ec..72e312cc520 100644 --- a/bfd/stabs.c +++ b/bfd/stabs.c @@ -337,7 +337,7 @@ _bfd_link_section_stabs (bfd *abfd, 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; @@ -393,7 +393,7 @@ _bfd_link_section_stabs (bfd *abfd, 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; } diff --git a/bfd/vms-misc.c b/bfd/vms-misc.c index 98fbb0e2997..87f7ce8088b 100644 --- a/bfd/vms-misc.c +++ b/bfd/vms-misc.c @@ -1,7 +1,7 @@ /* 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) @@ -349,7 +349,7 @@ _bfd_vms_get_record (bfd * abfd) 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) diff --git a/bfd/vms-tir.c b/bfd/vms-tir.c index de20d4f5362..e6ec6ebcc37 100644 --- a/bfd/vms-tir.c +++ b/bfd/vms-tir.c @@ -1,6 +1,6 @@ /* 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 @@ -51,8 +51,8 @@ check_section (bfd * abfd, int size) 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; @@ -833,8 +833,8 @@ alloc_section (bfd * abfd, unsigned int idx) 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) diff --git a/bfd/vms.c b/bfd/vms.c index bb5ab118c72..1944c1ee067 100644 --- a/bfd/vms.c +++ b/bfd/vms.c @@ -1,7 +1,7 @@ /* 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) @@ -476,7 +476,7 @@ vms_new_section_hook (bfd * abfd, asection *section) { 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; -- 2.30.2