misc: Replace uses of __builtin_*_overflow() with <misc/math_extras.h>.

Use the new math_extras functions instead of calling builtins directly.

Change a few local variables to size_t after checking that all uses of
the variable actually expects a size_t.

Signed-off-by: Jakob Olesen <jolesen@fb.com>
diff --git a/include/toolchain/xcc.h b/include/toolchain/xcc.h
index cdf317c..c93abb2 100644
--- a/include/toolchain/xcc.h
+++ b/include/toolchain/xcc.h
@@ -40,16 +40,4 @@
 #define __builtin_unreachable() do { __ASSERT(false, "Unreachable code"); } \
 	while (true)
 
-/* TODO: XCC doesn't define the below macros which are useful for checking
- * overflows. This needs to be fixed.
- */
-#define __builtin_add_overflow(a, b, output) \
-	({ *output = (a) + (b); false; })
-#define __builtin_mul_overflow(a, b, output) \
-	({ *output = (a) * (b); false; })
-#define __builtin_umul_overflow(a, b, output) \
-	({ *output = (a) * (b); false; })
-#define __builtin_umulll_overflow(a, b, output) \
-	({ *output = (a) * (b); false; })
-
 #endif
diff --git a/kernel/include/syscall_handler.h b/kernel/include/syscall_handler.h
index 5ce4564..ab2449d 100644
--- a/kernel/include/syscall_handler.h
+++ b/kernel/include/syscall_handler.h
@@ -13,6 +13,7 @@
 #ifndef _ASMLANGUAGE
 #include <kernel.h>
 #include <misc/printk.h>
+#include <misc/math_extras.h>
 #include <kernel_internal.h>
 #include <stdbool.h>
 
@@ -353,9 +354,9 @@
 #define Z_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, write) \
 	({ \
 		u32_t product; \
-		Z_SYSCALL_VERIFY_MSG(!__builtin_umul_overflow((u32_t)(nmemb), \
-							      (u32_t)(size), \
-							      &product), \
+		Z_SYSCALL_VERIFY_MSG(!u32_mul_overflow((u32_t)(nmemb), \
+						       (u32_t)(size), \
+						       &product), \
 				     "%ux%u array is too large", \
 				     (u32_t)(nmemb), (u32_t)(size)) ||  \
 			Z_SYSCALL_MEMORY(ptr, product, write); \
diff --git a/kernel/mempool.c b/kernel/mempool.c
index a611e4b..f124447 100644
--- a/kernel/mempool.c
+++ b/kernel/mempool.c
@@ -10,6 +10,7 @@
 #include <init.h>
 #include <string.h>
 #include <misc/__assert.h>
+#include <misc/math_extras.h>
 #include <stdbool.h>
 
 /* Linker-defined symbols bound the static pool structs */
@@ -144,8 +145,7 @@
 	 * get a block large enough to hold an initial (hidden) block
 	 * descriptor, as well as the space the caller requested
 	 */
-	if (__builtin_add_overflow(size, sizeof(struct k_mem_block_id),
-				   &size)) {
+	if (size_add_overflow(size, sizeof(struct k_mem_block_id), &size)) {
 		return NULL;
 	}
 	if (k_mem_pool_alloc(pool, &block, size, K_NO_WAIT) != 0) {
@@ -193,7 +193,7 @@
 	void *ret;
 	size_t bounds;
 
-	if (__builtin_mul_overflow(nmemb, size, &bounds)) {
+	if (size_mul_overflow(nmemb, size, &bounds)) {
 		return NULL;
 	}
 
diff --git a/kernel/msg_q.c b/kernel/msg_q.c
index b796e74..1ab3fdc 100644
--- a/kernel/msg_q.c
+++ b/kernel/msg_q.c
@@ -18,6 +18,7 @@
 #include <string.h>
 #include <wait_q.h>
 #include <misc/dlist.h>
+#include <misc/math_extras.h>
 #include <init.h>
 #include <syscall_handler.h>
 #include <kernel_internal.h>
@@ -73,8 +74,7 @@
 	int ret;
 	size_t total_size;
 
-	if (__builtin_umul_overflow((unsigned int)msg_size, max_msgs,
-				    (unsigned int *)&total_size)) {
+	if (size_mul_overflow(msg_size, max_msgs, &total_size)) {
 		ret = -EINVAL;
 	} else {
 		buffer = z_thread_malloc(total_size);
diff --git a/kernel/poll.c b/kernel/poll.c
index 682ee79..2c7cb8a 100644
--- a/kernel/poll.c
+++ b/kernel/poll.c
@@ -264,7 +264,7 @@
 	int ret;
 	k_spinlock_key_t key;
 	struct k_poll_event *events_copy = NULL;
-	unsigned int bounds;
+	u32_t bounds;
 
 	/* Validate the events buffer and make a copy of it in an
 	 * allocated kernel-side buffer.
@@ -273,11 +273,10 @@
 		ret = -EINVAL;
 		goto out;
 	}
-	if (Z_SYSCALL_VERIFY_MSG(
-		!__builtin_umul_overflow(num_events,
-					sizeof(struct k_poll_event),
-					&bounds),
-					"num_events too large")) {
+	if (Z_SYSCALL_VERIFY_MSG(!u32_mul_overflow(num_events,
+						   sizeof(struct k_poll_event),
+						   &bounds),
+				 "num_events too large")) {
 		ret = -EINVAL;
 		goto out;
 	}
diff --git a/kernel/thread.c b/kernel/thread.c
index 8bfce82..03ac8f1 100644
--- a/kernel/thread.c
+++ b/kernel/thread.c
@@ -19,6 +19,7 @@
 #include <spinlock.h>
 #include <kernel_structs.h>
 #include <misc/printk.h>
+#include <misc/math_extras.h>
 #include <sys_clock.h>
 #include <drivers/system_timer.h>
 #include <ksched.h>
@@ -475,9 +476,8 @@
 	/* Verify that the stack size passed in is OK by computing the total
 	 * size and comparing it with the size value in the object metadata
 	 */
-	Z_OOPS(Z_SYSCALL_VERIFY_MSG(!__builtin_uadd_overflow(K_THREAD_STACK_RESERVED,
-							     stack_size,
-							     &total_size),
+	Z_OOPS(Z_SYSCALL_VERIFY_MSG(!u32_add_overflow(K_THREAD_STACK_RESERVED,
+						      stack_size, &total_size),
 				    "stack size overflow (%u+%u)", stack_size,
 				    K_THREAD_STACK_RESERVED));
 
diff --git a/kernel/userspace.c b/kernel/userspace.c
index 40aa8fb..a159544 100644
--- a/kernel/userspace.c
+++ b/kernel/userspace.c
@@ -7,6 +7,7 @@
 
 #include <kernel.h>
 #include <string.h>
+#include <misc/math_extras.h>
 #include <misc/printk.h>
 #include <misc/rb.h>
 #include <kernel_structs.h>
@@ -672,7 +673,7 @@
 
 char *z_user_string_alloc_copy(const char *src, size_t maxlen)
 {
-	unsigned long actual_len;
+	size_t actual_len;
 	int err;
 	char *ret = NULL;
 
@@ -682,10 +683,10 @@
 	}
 	if (actual_len == maxlen) {
 		/* Not NULL terminated */
-		printk("string too long %p (%lu)\n", src, actual_len);
+		printk("string too long %p (%zu)\n", src, actual_len);
 		goto out;
 	}
-	if (__builtin_uaddl_overflow(actual_len, 1, &actual_len)) {
+	if (size_add_overflow(actual_len, 1, &actual_len)) {
 		printk("overflow\n");
 		goto out;
 	}
@@ -705,7 +706,7 @@
 
 int z_user_string_copy(char *dst, const char *src, size_t maxlen)
 {
-	unsigned long actual_len;
+	size_t actual_len;
 	int ret, err;
 
 	actual_len = z_user_string_nlen(src, maxlen, &err);
@@ -715,11 +716,11 @@
 	}
 	if (actual_len == maxlen) {
 		/* Not NULL terminated */
-		printk("string too long %p (%lu)\n", src, actual_len);
+		printk("string too long %p (%zu)\n", src, actual_len);
 		ret = EINVAL;
 		goto out;
 	}
-	if (__builtin_uaddl_overflow(actual_len, 1, &actual_len)) {
+	if (size_add_overflow(actual_len, 1, &actual_len)) {
 		printk("overflow\n");
 		ret = EINVAL;
 		goto out;
diff --git a/lib/libc/minimal/source/stdlib/malloc.c b/lib/libc/minimal/source/stdlib/malloc.c
index 2ec25b1..ae8efbc 100644
--- a/lib/libc/minimal/source/stdlib/malloc.c
+++ b/lib/libc/minimal/source/stdlib/malloc.c
@@ -8,6 +8,7 @@
 #include <zephyr.h>
 #include <init.h>
 #include <errno.h>
+#include <misc/math_extras.h>
 #include <misc/mempool.h>
 #include <string.h>
 #include <app_memory/app_memdomain.h>
@@ -66,23 +67,11 @@
 	sys_mem_pool_free(ptr);
 }
 
-static bool size_t_mul_overflow(size_t a, size_t b, size_t *res)
-{
-#if __SIZEOF_SIZE_T__ == 4
-	return __builtin_umul_overflow((unsigned int)a, (unsigned int)b,
-				       (unsigned int *)res);
-#else /* __SIZEOF_SIZE_T__ == 8 */
-	return __builtin_umulll_overflow((unsigned long long)a,
-					 (unsigned long long)b,
-					 (unsigned long long *)res);
-#endif
-}
-
 void *calloc(size_t nmemb, size_t size)
 {
 	void *ret;
 
-	if (size_t_mul_overflow(nmemb, size, &size)) {
+	if (size_mul_overflow(nmemb, size, &size)) {
 		errno = ENOMEM;
 		return NULL;
 	}
@@ -144,7 +133,7 @@
 
 void *reallocarray(void *ptr, size_t nmemb, size_t size)
 {
-	if (size_t_mul_overflow(nmemb, size, &size)) {
+	if (size_mul_overflow(nmemb, size, &size)) {
 		errno = ENOMEM;
 		return NULL;
 	}
diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c
index 5ce0b35..2f1ce3e 100644
--- a/subsys/net/lib/sockets/sockets.c
+++ b/subsys/net/lib/sockets/sockets.c
@@ -17,6 +17,7 @@
 #include <net/socket.h>
 #include <syscall_handler.h>
 #include <misc/fdtable.h>
+#include <misc/math_extras.h>
 
 #include "sockets_internal.h"
 
@@ -1037,12 +1038,11 @@
 Z_SYSCALL_HANDLER(zsock_poll, fds, nfds, timeout)
 {
 	struct zsock_pollfd *fds_copy;
-	unsigned int fds_size;
+	size_t fds_size;
 	int ret;
 
 	/* Copy fds array from user mode */
-	if (__builtin_umul_overflow(nfds, sizeof(struct zsock_pollfd),
-				    &fds_size)) {
+	if (size_mul_overflow(nfds, sizeof(struct zsock_pollfd), &fds_size)) {
 		errno = EFAULT;
 		return -1;
 	}