mirror of
https://github.com/php/php-src.git
synced 2024-09-24 11:27:28 +00:00
Add ARM optimized versions of safe_address()
The function safe_address() uses inline assembler to detect overflow in size/offset calculations, as detecting this in plain C is a lot more work.
This commit is contained in:
parent
72a728872b
commit
d0e0a51c4c
@ -2494,6 +2494,46 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
return res;
|
||||
}
|
||||
|
||||
#elif defined(__GNUC__) && defined(__arm__)
|
||||
|
||||
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
{
|
||||
size_t res;
|
||||
unsigned long overflow;
|
||||
|
||||
__asm__ ("umull %0,%1,%2,%3\n\tadds %0,%4\n\tadc %1,%1"
|
||||
: "=&r"(res), "=&r"(overflow)
|
||||
: "r"(nmemb),
|
||||
"r"(size),
|
||||
"r"(offset));
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#elif defined(__GNUC__) && defined(__aarch64__)
|
||||
|
||||
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
{
|
||||
size_t res;
|
||||
unsigned long overflow;
|
||||
|
||||
__asm__ ("mul %0,%2,%3\n\tumulh %1,%2,%3\n\tadds %0,%0,%4\n\tadc %1,%1,%1"
|
||||
: "=&r"(res), "=&r"(overflow)
|
||||
: "r"(nmemb),
|
||||
"r"(size),
|
||||
"r"(offset));
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#elif SIZEOF_SIZE_T == 4 && defined(HAVE_ZEND_LONG64)
|
||||
|
||||
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
|
Loading…
Reference in New Issue
Block a user