diff options
-rw-r--r-- | include/slibc/internals.h | 15 | ||||
-rw-r--r-- | src/malloc.c | 15 | ||||
-rw-r--r-- | src/slibc-human/escape.c | 4 |
3 files changed, 22 insertions, 12 deletions
diff --git a/include/slibc/internals.h b/include/slibc/internals.h index 099e2e7..b3f6235 100644 --- a/include/slibc/internals.h +++ b/include/slibc/internals.h @@ -18,9 +18,24 @@ #ifndef _SLIBC_INTERNALS_H #define _SLIBC_INTERNALS_H +#include <errno.h> + + #define _(msg) msg +#define OVERFLOW(op, a, b, res, errnum, failrc) \ + do \ + if (__builtin_##op##_overflow(a, b, res)) \ + return errno = (errnum), (failrc); \ + while (0) + + +#define MEM_OVERFLOW(op, a, b, res) \ + OVERFLOW(op, a, b, res, ENOMEM, NULL) + + + #endif diff --git a/src/malloc.c b/src/malloc.c index 28824e9..719e713 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -16,6 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <stdlib.h> +#include <slibc/internals.h> #include <stddef.h> #include <slibc-alloc.h> #include <strings.h> @@ -59,8 +60,7 @@ static void* unaligned_malloc(size_t size) if (size == 0) return NULL; - if (__builtin_uaddl_overflow(2 * sizeof(size_t), size, &full_size)) - return errno = ENOMEM, NULL; + MEM_OVERFLOW(uaddl, 2 * sizeof(size_t), size, &full_size); ptr = mmap(NULL, full_size, (PROT_READ | PROT_WRITE), (MAP_PRIVATE | MAP_ANONYMOUS), -1, 0); @@ -115,9 +115,7 @@ void* calloc(size_t elem_count, size_t elem_size) void* ptr; size_t size; - if (__builtin_umull_overflow(elem_count, elem_size, &size)) - return errno = ENOMEM, NULL; - + MEM_OVERFLOW(umull, elem_count, elem_size, &size)); ptr = MALLOC(size); if (ptr != NULL) explicit_bzero(ptr, size); @@ -276,8 +274,7 @@ void* memalign(size_t boundary, size_t size) if (!boundary || (__builtin_ffsl((long int)boundary) != boundary)) /* `size_t` mat not be wider than `long int`. */ return errno = EINVAL, NULL; - if (__builtin_uaddl_overflow(boundary - 1, size, &full_size)) - return errno = ENOMEM, NULL; + MEM_OVERFLOW(uaddl, boundary - 1, size, &full_size); ptr = unaligned_malloc(full_size); if (ptr == NULL) @@ -367,9 +364,7 @@ void* pvalloc(size_t size) if (full_size % boundary != 0) rounding = boundary - (full_size % boundary); - if (__builtin_uaddl_overflow(size, rounding, &full_size)) - return errno = ENOMEM, NULL; - + MEM_OVERFLOW(uaddl, size, rounding, &full_size); return memalign(boundary, full_size); } diff --git a/src/slibc-human/escape.c b/src/slibc-human/escape.c index a7de84b..56cf794 100644 --- a/src/slibc-human/escape.c +++ b/src/slibc-human/escape.c @@ -16,6 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <slib-human.h> +#include <slibc/internals.h> #include <stdlib.h> #include <string.h> #include <errno.h> @@ -80,8 +81,7 @@ char* escape(const char* restrict str, char quote) return strdup(str); len = strlen(str) * sizeof(char); - if (__builtin_uaddl_overflow(len, extra * sizeof(char), &size)) - return errno = ENOMEM, NULL; + MEM_OVERFLOW(uaddl, len, extra * sizeof(char), &size); w = rc = malloc(size); if (rc == NULL) |