libdrgn: work around "undefined reference to '__muloti4'" when using Clang

Older versions of Clang generate a call to __muloti4() for
__builtin_mul_overflow() with mixed signed and unsigned types. However,
Clang doesn't link to compiler-rt by default. Work around it by making
all of our calls to __builtin_mul_overflow() use unsigned types only.

1: https://bugs.llvm.org/show_bug.cgi?id=16404
This commit is contained in:
Omar Sandoval 2019-03-29 23:43:21 -07:00
parent 75c3679147
commit 2dd14ad522
3 changed files with 10 additions and 10 deletions

View File

@ -27,17 +27,17 @@ static DrgnType *DrgnType_new(enum drgn_qualifiers qualifiers, size_t nmemb,
size_t size)
{
DrgnType *type_obj;
Py_ssize_t nitems;
size_t bytes;
if (__builtin_mul_overflow(nmemb, size, &nitems) ||
__builtin_add_overflow(nitems, sizeof(struct drgn_type), &nitems) ||
__builtin_add_overflow(nitems, DrgnType_type.tp_itemsize - 1,
&nitems)) {
if (__builtin_mul_overflow(nmemb, size, &bytes) ||
__builtin_add_overflow(bytes, sizeof(struct drgn_type), &bytes) ||
__builtin_add_overflow(bytes, sizeof(void *) - 1, &bytes) ||
bytes / sizeof(void *) > PY_SSIZE_T_MAX - sizeof(DrgnType)) {
PyErr_NoMemory();
return NULL;
}
nitems /= DrgnType_type.tp_itemsize;
type_obj = (DrgnType *)DrgnType_type.tp_alloc(&DrgnType_type, nitems);
type_obj = (DrgnType *)DrgnType_type.tp_alloc(&DrgnType_type,
bytes / sizeof(void *));
if (!type_obj)
return NULL;
type_obj->qualifiers = qualifiers;

View File

@ -542,12 +542,12 @@ static struct drgn_error *parse_nt_file(const char *desc, size_t descsz,
if (is_64_bit) {
if (!read_u64(&p, end, bswap, &count) ||
!read_u64(&p, end, bswap, &page_size) ||
__builtin_mul_overflow(count, 24, &paths_offset))
__builtin_mul_overflow(count, 24U, &paths_offset))
goto invalid;
} else {
if (!read_u32_into_u64(&p, end, bswap, &count) ||
!read_u32_into_u64(&p, end, bswap, &page_size) ||
__builtin_mul_overflow(count, 12, &paths_offset))
__builtin_mul_overflow(count, 12U, &paths_offset))
goto invalid;
}

View File

@ -648,7 +648,7 @@ struct drgn_error *drgn_type_bit_size(struct drgn_type *type, uint64_t *ret)
err = drgn_type_sizeof(type, ret);
if (err)
return err;
if (__builtin_mul_overflow(*ret, 8, ret)) {
if (__builtin_mul_overflow(*ret, 8U, ret)) {
return drgn_error_create(DRGN_ERROR_OVERFLOW,
"type bit size is too large");
}