diff options
author | Lucas De Marchi <lucas.demarchi@intel.com> | 2015-02-10 10:41:47 -0200 |
---|---|---|
committer | Lucas De Marchi <lucas.demarchi@intel.com> | 2015-02-10 10:43:44 -0200 |
commit | aac5f4514f71d04ac3dcb8b923209781895d7ff2 (patch) | |
tree | 48292b9079a0e8989d94aa0cf0c5806b965cbdd9 /shared | |
parent | 14c3244f04002380d94903b661b93185c158077b (diff) | |
download | kmod-aac5f4514f71d04ac3dcb8b923209781895d7ff2.tar.gz kmod-aac5f4514f71d04ac3dcb8b923209781895d7ff2.tar.bz2 kmod-aac5f4514f71d04ac3dcb8b923209781895d7ff2.zip |
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.
Diffstat (limited to 'shared')
-rw-r--r-- | shared/util.h | 16 |
1 files changed, 16 insertions, 0 deletions
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 @@ static inline void freep(void *p) { 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; +} |