diff options
-rw-r--r-- | include/nasmlib.h | 2 | ||||
-rw-r--r-- | nasmlib/alloc.c | 47 |
2 files changed, 42 insertions, 7 deletions
diff --git a/include/nasmlib.h b/include/nasmlib.h index eb3a637d..2e2519f5 100644 --- a/include/nasmlib.h +++ b/include/nasmlib.h @@ -109,7 +109,7 @@ static inline size_t nasm_last_string_size(void) #define nasm_assert_pointer(p) ((void)sizeof(*(p))) #define nasm_new(p) ((p) = nasm_zalloc(sizeof(*(p)))) -#define nasm_newn(p,n) ((p) = nasm_calloc(sizeof(*(p)),(n))) +#define nasm_newn(p,n) ((p) = nasm_calloc((n), sizeof(*(p)))) /* * This is broken on platforms where there are pointers which don't * match void * in their internal layout. It unfortunately also diff --git a/nasmlib/alloc.c b/nasmlib/alloc.c index 4e0ff9fe..b0d623a2 100644 --- a/nasmlib/alloc.c +++ b/nasmlib/alloc.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2018 The NASM Authors - All Rights Reserved + * Copyright 1996-2019 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -65,22 +65,57 @@ no_return nasm_alloc_failed(void) void *nasm_malloc(size_t size) { - return validate_ptr(malloc(size)); + void *p; + +again: + p = malloc(size); + + if (unlikely(!p)) { + if (!size) { + size = 1; + goto again; + } + nasm_alloc_failed(); + } + return p; } -void *nasm_calloc(size_t size, size_t nelem) +void *nasm_calloc(size_t nelem, size_t size) { - return validate_ptr(calloc(size, nelem)); + void *p; + +again: + p = calloc(nelem, size); + + if (unlikely(!p)) { + if (!nelem || !size) { + nelem = size = 1; + goto again; + } + nasm_alloc_failed(); + } + + return p; } void *nasm_zalloc(size_t size) { - return validate_ptr(calloc(1, size)); + return nasm_calloc(size, 1); } +/* + * Unlike the system realloc, we do *not* allow size == 0 to be + * the equivalent to free(); we guarantee returning a non-NULL pointer. + * + * The check for calling malloc() is theoretically redundant, but be + * paranoid about the system library... + */ void *nasm_realloc(void *q, size_t size) { - return validate_ptr(q ? realloc(q, size) : malloc(size)); + if (unlikely(!size)) + size = 1; + q = q ? realloc(q, size) : malloc(size); + return validate_ptr(q); } void nasm_free(void *q) |