Skip to content

Commit 2dd14ad

Browse files
committed
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
1 parent 75c3679 commit 2dd14ad

File tree

3 files changed

+10
-10
lines changed

3 files changed

+10
-10
lines changed

_drgn/type.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@ static DrgnType *DrgnType_new(enum drgn_qualifiers qualifiers, size_t nmemb,
2727
size_t size)
2828
{
2929
DrgnType *type_obj;
30-
Py_ssize_t nitems;
30+
size_t bytes;
3131

32-
if (__builtin_mul_overflow(nmemb, size, &nitems) ||
33-
__builtin_add_overflow(nitems, sizeof(struct drgn_type), &nitems) ||
34-
__builtin_add_overflow(nitems, DrgnType_type.tp_itemsize - 1,
35-
&nitems)) {
32+
if (__builtin_mul_overflow(nmemb, size, &bytes) ||
33+
__builtin_add_overflow(bytes, sizeof(struct drgn_type), &bytes) ||
34+
__builtin_add_overflow(bytes, sizeof(void *) - 1, &bytes) ||
35+
bytes / sizeof(void *) > PY_SSIZE_T_MAX - sizeof(DrgnType)) {
3636
PyErr_NoMemory();
3737
return NULL;
3838
}
39-
nitems /= DrgnType_type.tp_itemsize;
40-
type_obj = (DrgnType *)DrgnType_type.tp_alloc(&DrgnType_type, nitems);
39+
type_obj = (DrgnType *)DrgnType_type.tp_alloc(&DrgnType_type,
40+
bytes / sizeof(void *));
4141
if (!type_obj)
4242
return NULL;
4343
type_obj->qualifiers = qualifiers;

libdrgn/program.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,12 +542,12 @@ static struct drgn_error *parse_nt_file(const char *desc, size_t descsz,
542542
if (is_64_bit) {
543543
if (!read_u64(&p, end, bswap, &count) ||
544544
!read_u64(&p, end, bswap, &page_size) ||
545-
__builtin_mul_overflow(count, 24, &paths_offset))
545+
__builtin_mul_overflow(count, 24U, &paths_offset))
546546
goto invalid;
547547
} else {
548548
if (!read_u32_into_u64(&p, end, bswap, &count) ||
549549
!read_u32_into_u64(&p, end, bswap, &page_size) ||
550-
__builtin_mul_overflow(count, 12, &paths_offset))
550+
__builtin_mul_overflow(count, 12U, &paths_offset))
551551
goto invalid;
552552
}
553553

libdrgn/type.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ struct drgn_error *drgn_type_bit_size(struct drgn_type *type, uint64_t *ret)
648648
err = drgn_type_sizeof(type, ret);
649649
if (err)
650650
return err;
651-
if (__builtin_mul_overflow(*ret, 8, ret)) {
651+
if (__builtin_mul_overflow(*ret, 8U, ret)) {
652652
return drgn_error_create(DRGN_ERROR_OVERFLOW,
653653
"type bit size is too large");
654654
}

0 commit comments

Comments
 (0)