summaryrefslogtreecommitdiff
path: root/src/gmalloc.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2013-11-06 21:31:04 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2013-11-06 21:31:04 -0800
commitaea07e2c6e54733804d0be54e97d44fcb3df63dd (patch)
tree1f84e37d28aa136603322428a81c2f0046bf9844 /src/gmalloc.c
parente6e4db3cac4630fc83e4bc520f99823572c3e592 (diff)
downloademacs-aea07e2c6e54733804d0be54e97d44fcb3df63dd.tar.gz
Port to C11 aligned_alloc, and fix some integer overflows.
* configure.ac (GMALLOC_OBJ): Initialize to empty if !system_malloc and doug_lea_malloc. (aligned_alloc): Test for existence if !GMALLOC_OBJ and not darwin. (posix_memalign): Test for existence only if !GMALLOC_OBJ and not darwin and !aligned_alloc. * src/alloc.c (USE_ALIGNED_ALLOC): New symbol. (USE_POSIX_MEMALIGN): Remove. All uses replaced with USE_ALIGNED_ALLOC, and use of posix_memalign replaced with aligned_alloc. (aligned_alloc): New function, defined or declared as needed. * src/conf_post.h (HAVE_POSIX_MEMALIGN) [DARWIN_OS]: Don't undef; configure.ac now does this. * src/gmalloc.c (aligned_alloc) [MSDOS]: New decl. (calloc, aligned_alloc): Check for integer overflow. (aligned_alloc): Rename from memalign. All uses changed. (memalign): New function, an alias for aligned_alloc.
Diffstat (limited to 'src/gmalloc.c')
-rw-r--r--src/gmalloc.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/src/gmalloc.c b/src/gmalloc.c
index bc1d85ac5fb..fc728eeea7e 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -58,6 +58,7 @@ extern void free (void *ptr);
/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */
#ifdef MSDOS
+extern void *aligned_alloc (size_t, size_t);
extern void *memalign (size_t, size_t);
extern int posix_memalign (void **, size_t, size_t);
#endif
@@ -143,11 +144,11 @@ struct list
/* Free list headers for each fragment size. */
extern struct list _fraghead[];
-/* List of blocks allocated with `memalign' (or `valloc'). */
+/* List of blocks allocated with aligned_alloc and friends. */
struct alignlist
{
struct alignlist *next;
- void *aligned; /* The address that memaligned returned. */
+ void *aligned; /* The address that aligned_alloc returned. */
void *exact; /* The address that malloc returned. */
};
extern struct alignlist *_aligned_blocks;
@@ -977,7 +978,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
/* Debugging hook for free. */
void (*__free_hook) (void *__ptr);
-/* List of blocks allocated by memalign. */
+/* List of blocks allocated by aligned_alloc. */
struct alignlist *_aligned_blocks = NULL;
/* Return memory to the heap.
@@ -1487,13 +1488,20 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
/* Allocate an array of NMEMB elements each SIZE bytes long.
The entire array is initialized to zeros. */
void *
-calloc (register size_t nmemb, register size_t size)
+calloc (size_t nmemb, size_t size)
{
- register void *result = malloc (nmemb * size);
+ void *result;
+ size_t bytes = nmemb * size;
- if (result != NULL)
- (void) memset (result, 0, nmemb * size);
+ if (size != 0 && bytes / size != nmemb)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+ result = malloc (bytes);
+ if (result)
+ memset (result, 0, bytes);
return result;
}
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
@@ -1559,7 +1567,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. *
void *(*__memalign_hook) (size_t size, size_t alignment);
void *
-memalign (size_t alignment, size_t size)
+aligned_alloc (size_t alignment, size_t size)
{
void *result;
size_t adj, lastadj;
@@ -1570,6 +1578,11 @@ memalign (size_t alignment, size_t size)
/* Allocate a block with enough extra space to pad the block with up to
(ALIGNMENT - 1) bytes if necessary. */
+ if (- size < alignment)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
result = malloc (size + alignment - 1);
if (result == NULL)
return NULL;
@@ -1631,6 +1644,15 @@ memalign (size_t alignment, size_t size)
return result;
}
+/* An obsolete alias for aligned_alloc, for any old libraries that use
+ this alias. */
+
+void *
+memalign (size_t alignment, size_t size)
+{
+ return aligned_alloc (alignment, size);
+}
+
int
posix_memalign (void **memptr, size_t alignment, size_t size)
{
@@ -1641,7 +1663,7 @@ posix_memalign (void **memptr, size_t alignment, size_t size)
|| (alignment & (alignment - 1)) != 0)
return EINVAL;
- mem = memalign (alignment, size);
+ mem = aligned_alloc (alignment, size);
if (mem == NULL)
return ENOMEM;
@@ -1686,7 +1708,7 @@ valloc (size_t size)
if (pagesize == 0)
pagesize = getpagesize ();
- return memalign (pagesize, size);
+ return aligned_alloc (pagesize, size);
}
#ifdef GC_MCHECK