shared: add helper function to add and check for overflow
Use _builtin_uaddll_overflow/_builtin_uaddl_overflow when available,
abstracting the type to use it with uint64_t.
Otherwise fallback to the implementation as added in 67466f2 ("Prevent
offset + size overflow.").
This also adds the tests for this new helper in the testsuite.
diff --git a/shared/util.h b/shared/util.h
index 4c59705..6f602d3 100644
--- a/shared/util.h
+++ b/shared/util.h
@@ -1,5 +1,6 @@
#pragma once
+#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -72,3 +73,18 @@
free(*(void**) p);
}
#define _cleanup_free_ _cleanup_(freep)
+
+static inline bool addu64_overflow(uint64_t a, uint64_t b, uint64_t *res)
+{
+#if (HAVE___BUILTIN_UADDL_OVERFLOW && HAVE___BUILTIN_UADDLL_OVERFLOW)
+#if __SIZEOF_LONG__ == 8
+ return __builtin_uaddl_overflow(a, b, res);
+#elif __SIZEOF_LONG_LONG__ == 8
+ return __builtin_uaddll_overflow(a, b, res);
+#else
+#error "sizeof(long long) != 8"
+#endif
+#endif
+ *res = a + b;
+ return ULLONG_MAX - a < b;
+}