mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-05 15:09:31 +03:00
Use checked unsigned multiplication extension of GCC/Clang
Most processors have carry flags which they set on addition overflow, so it is a good idea to access them whenever possible. Most of them also have widening multiply instructions that can be used to detect overflow of the non-widening version. Both GCC and Clang offer a way to detect an overflow for security critical applications. Reference: https://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins
This commit is contained in:
parent
46b11fa0a4
commit
8dba36bcec
1 changed files with 11 additions and 0 deletions
|
@ -117,6 +117,9 @@ bool _mi_page_is_valid(mi_page_t* page);
|
||||||
#define mi_likely(x) (x)
|
#define mi_likely(x) (x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __has_builtin
|
||||||
|
#define __has_builtin(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#define mi_decl_noinline __declspec(noinline)
|
#define mi_decl_noinline __declspec(noinline)
|
||||||
|
@ -149,9 +152,17 @@ bool _mi_page_is_valid(mi_page_t* page);
|
||||||
// Overflow detecting multiply
|
// Overflow detecting multiply
|
||||||
#define MI_MUL_NO_OVERFLOW ((size_t)1 << (4*sizeof(size_t))) // sqrt(SIZE_MAX)
|
#define MI_MUL_NO_OVERFLOW ((size_t)1 << (4*sizeof(size_t))) // sqrt(SIZE_MAX)
|
||||||
static inline bool mi_mul_overflow(size_t size, size_t count, size_t* total) {
|
static inline bool mi_mul_overflow(size_t size, size_t count, size_t* total) {
|
||||||
|
#if __has_builtin(__builtin_umul_overflow) || __GNUC__ >= 5
|
||||||
|
#if (MI_INTPTR_SIZE == 4)
|
||||||
|
return __builtin_umul_overflow(size, count, total);
|
||||||
|
#else
|
||||||
|
return __builtin_umull_overflow(size, count, total);
|
||||||
|
#endif
|
||||||
|
#else /* __builtin_umul_overflow is unavailable */
|
||||||
*total = size * count;
|
*total = size * count;
|
||||||
return ((size >= MI_MUL_NO_OVERFLOW || count >= MI_MUL_NO_OVERFLOW)
|
return ((size >= MI_MUL_NO_OVERFLOW || count >= MI_MUL_NO_OVERFLOW)
|
||||||
&& size > 0 && (SIZE_MAX / size) < count);
|
&& size > 0 && (SIZE_MAX / size) < count);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Align a byte size to a size in _machine words_,
|
// Align a byte size to a size in _machine words_,
|
||||||
|
|
Loading…
Add table
Reference in a new issue