aboutsummaryrefslogtreecommitdiff
path: root/bfd/libbfd.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2021-05-04 14:29:04 +0100
committerNick Clifton <nickc@redhat.com>2021-05-04 14:29:04 +0100
commitbd6d8601f304d03ecdebe1b1a7d48666845a91aa (patch)
tree5880baf07238e954bd33f97c546dbabb3070dc7f /bfd/libbfd.c
parenta8d6316b67d52eaa1b7b311084ddff71a66f7cc0 (diff)
downloadfsf-binutils-gdb-bd6d8601f304d03ecdebe1b1a7d48666845a91aa.zip
fsf-binutils-gdb-bd6d8601f304d03ecdebe1b1a7d48666845a91aa.tar.gz
fsf-binutils-gdb-bd6d8601f304d03ecdebe1b1a7d48666845a91aa.tar.bz2
Define bfd_realloc(ptr,0) to return allocated memory, whilst bfd_realloc_or_free(ptr,0) frees ptr.
* libbfd.c (bfd_malloc): Provide some documenation. Treat a size of 0 as 1. (bfd_realloc): Likewise. (bfd_zmalloc): Likewise. (bfd_realloc_or_free): Provide some documentation. Treat a size of 0 as a request to free. * libbfd-in.h (bfd_realloc): Remove prototype. (bfd_realloc_or_free): Remove prototype. (bfd_zmalloc): Remove prototype. * libbfd.h: Regenerate.
Diffstat (limited to 'bfd/libbfd.c')
-rw-r--r--bfd/libbfd.c107
1 files changed, 96 insertions, 11 deletions
diff --git a/bfd/libbfd.c b/bfd/libbfd.c
index 52c9245..892f291 100644
--- a/bfd/libbfd.c
+++ b/bfd/libbfd.c
@@ -258,6 +258,20 @@ _bfd_dummy_target (bfd *ignore_abfd ATTRIBUTE_UNUSED)
#define SSIZE_MAX ((size_t) -1 >> 1)
#endif
+/*
+INTERNAL_FUNCTION
+ bfd_malloc
+
+SYNOPSIS
+ extern void * bfd_malloc (bfd_size_type SIZE) ATTRIBUTE_HIDDEN;
+
+DESCRIPTION
+ Returns a pointer to an allocated block of memory that is at least
+ SIZE bytes long. If SIZE is 0 then it will be treated as if it were
+ 1. If SIZE is too big then NULL will be returned.
+
+ Returns NULL upon error and sets bfd_error.
+*/
void *
bfd_malloc (bfd_size_type size)
{
@@ -272,13 +286,36 @@ bfd_malloc (bfd_size_type size)
return NULL;
}
- ptr = malloc (sz);
- if (ptr == NULL && sz != 0)
+ ptr = malloc (sz ? sz : 1);
+ if (ptr == NULL)
bfd_set_error (bfd_error_no_memory);
return ptr;
}
+/*
+INTERNAL_FUNCTION
+ bfd_realloc
+
+SYNOPSIS
+ extern void * bfd_realloc (void * MEM, bfd_size_type SIZE) ATTRIBUTE_HIDDEN;
+
+DESCRIPTION
+ Returns a pointer to an allocated block of memory that is at least
+ SIZE bytes long. If SIZE is 0 then it will be treated as if it were
+ 1. If SIZE is too big then NULL will be returned.
+
+ If MEM is not NULL then it must point to an allocated block of memory.
+ If this block is large enough then MEM may be used as the return
+ value for this function, but this is not guaranteed.
+
+ If MEM is not returned then the first N bytes in the returned block
+ will be identical to the first N bytes in region pointed to by MEM,
+ where N is the lessor of SIZE and the length of the region of memory
+ currently addressed by MEM.
+
+ Returns NULL upon error and sets bfd_error.
+*/
void *
bfd_realloc (void *ptr, bfd_size_type size)
{
@@ -296,37 +333,85 @@ bfd_realloc (void *ptr, bfd_size_type size)
return NULL;
}
- ret = realloc (ptr, sz);
+ /* The behaviour of realloc(0) is implementation defined,
+ but for this function we always allocate memory. */
+ ret = realloc (ptr, sz ? sz : 1);
- if (ret == NULL && sz != 0)
+ if (ret == NULL)
bfd_set_error (bfd_error_no_memory);
return ret;
}
-/* Reallocate memory using realloc.
- If this fails the pointer is freed before returning. */
+/*
+INTERNAL_FUNCTION
+ bfd_realloc_or_free
+
+SYNOPSIS
+ extern void * bfd_realloc_or_free (void * MEM, bfd_size_type SIZE) ATTRIBUTE_HIDDEN;
+DESCRIPTION
+ Returns a pointer to an allocated block of memory that is at least
+ SIZE bytes long. If SIZE is 0 then no memory will be allocated,
+ MEM will be freed, and NULL will be returned. This will not cause
+ bfd_error to be set.
+
+ If SIZE is too big then NULL will be returned and bfd_error will be
+ set.
+
+ If MEM is not NULL then it must point to an allocated block of memory.
+ If this block is large enough then MEM may be used as the return
+ value for this function, but this is not guaranteed.
+
+ If MEM is not returned then the first N bytes in the returned block
+ will be identical to the first N bytes in region pointed to by MEM,
+ where N is the lessor of SIZE and the length of the region of memory
+ currently addressed by MEM.
+*/
void *
bfd_realloc_or_free (void *ptr, bfd_size_type size)
{
- void *ret = bfd_realloc (ptr, size);
+ void *ret;
- if (ret == NULL && size > 0)
+ /* The behaviour of realloc(0) is implementation defined, but
+ for this function we treat it is always freeing the memory. */
+ if (size == 0)
+ {
+ free (ptr);
+ return NULL;
+ }
+
+ ret = bfd_realloc (ptr, size);
+ if (ret == NULL)
free (ptr);
return ret;
}
-/* Allocate memory using malloc and clear it. */
+/*
+INTERNAL_FUNCTION
+ bfd_zmalloc
+SYNOPSIS
+ extern void * bfd_zmalloc (bfd_size_type SIZE) ATTRIBUTE_HIDDEN;
+
+DESCRIPTION
+ Returns a pointer to an allocated block of memory that is at least
+ SIZE bytes long. If SIZE is 0 then it will be treated as if it were
+ 1. If SIZE is too big then NULL will be returned.
+
+ Returns NULL upon error and sets bfd_error.
+
+ If NULL is not returned then the allocated block of memory will
+ have been cleared.
+*/
void *
bfd_zmalloc (bfd_size_type size)
{
void *ptr = bfd_malloc (size);
- if (ptr != NULL && size > 0)
- memset (ptr, 0, (size_t) size);
+ if (ptr != NULL)
+ memset (ptr, 0, size ? (size_t) size : 1);
return ptr;
}