aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/slibc/internals.h15
-rw-r--r--src/malloc.c15
-rw-r--r--src/slibc-human/escape.c4
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)