libc: remove __size_mul_overflow
We should just be able to use __builtin_umull_overflow now, which expects unsigned long parameters. We don't need __builtin_umul_overflow (which expects unsigned ints) because Bionic is LP64 or ILP32, so for ILP32 sizeof(size_t) == sizeof(unsigned long), so __builtin_umull_overflow will work for either ILP32 or LP64. Test: mm Change-Id: I872491731bca05e561767f8bfeda4c6704e10ccb Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
This commit is contained in:
parent
0be8f184c2
commit
ceed466d60
2 changed files with 7 additions and 22 deletions
|
@ -99,8 +99,8 @@ char* __fgets_chk(char* dst, int supplied_size, FILE* stream, size_t dst_len_fro
|
|||
}
|
||||
|
||||
size_t __fread_chk(void* buf, size_t size, size_t count, FILE* stream, size_t buf_size) {
|
||||
size_t total;
|
||||
if (__predict_false(__size_mul_overflow(size, count, &total))) {
|
||||
unsigned long total;
|
||||
if (__predict_false(__builtin_umull_overflow(size, count, &total))) {
|
||||
// overflow: trigger the error path in fread
|
||||
return fread(buf, size, count, stream);
|
||||
}
|
||||
|
@ -109,8 +109,8 @@ size_t __fread_chk(void* buf, size_t size, size_t count, FILE* stream, size_t bu
|
|||
}
|
||||
|
||||
size_t __fwrite_chk(const void* buf, size_t size, size_t count, FILE* stream, size_t buf_size) {
|
||||
size_t total;
|
||||
if (__predict_false(__size_mul_overflow(size, count, &total))) {
|
||||
unsigned long total;
|
||||
if (__predict_false(__builtin_umull_overflow(size, count, &total))) {
|
||||
// overflow: trigger the error path in fwrite
|
||||
return fwrite(buf, size, count, stream);
|
||||
}
|
||||
|
|
|
@ -320,27 +320,12 @@
|
|||
/* Used to rename functions so that the compiler emits a call to 'x' rather than the function this was applied to. */
|
||||
#define __RENAME(x) __asm__(#x)
|
||||
|
||||
#if __has_builtin(__builtin_umul_overflow) || __GNUC__ >= 5
|
||||
#if defined(__LP64__)
|
||||
#define __size_mul_overflow(a, b, result) __builtin_umull_overflow(a, b, result)
|
||||
#else
|
||||
#define __size_mul_overflow(a, b, result) __builtin_umul_overflow(a, b, result)
|
||||
#endif
|
||||
#else
|
||||
extern inline __always_inline __attribute__((gnu_inline))
|
||||
int __size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b, __SIZE_TYPE__ *result) {
|
||||
*result = a * b;
|
||||
static const __SIZE_TYPE__ mul_no_overflow = 1UL << (sizeof(__SIZE_TYPE__) * 4);
|
||||
return (a >= mul_no_overflow || b >= mul_no_overflow) && a > 0 && (__SIZE_TYPE__)-1 / a < b;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Used when we need to check for overflow when multiplying x and y. This
|
||||
* should only be used where __size_mul_overflow can not work, because it makes
|
||||
* assumptions that __size_mul_overflow doesn't (x and y are positive, ...),
|
||||
* should only be used where __builtin_umull_overflow can not work, because it makes
|
||||
* assumptions that __builtin_umull_overflow doesn't (x and y are positive, ...),
|
||||
* *and* doesn't make use of compiler intrinsics, so it's probably slower than
|
||||
* __size_mul_overflow.
|
||||
* __builtin_umull_overflow.
|
||||
*/
|
||||
#define __unsafe_check_mul_overflow(x, y) ((__SIZE_TYPE__)-1 / (x) < (y))
|
||||
|
||||
|
|
Loading…
Reference in a new issue