diff mbox series

[kvm-unit-tests,v2] arm64: Fix compiling with ancient compiler

Message ID 20220203151344.437113-1-drjones@redhat.com (mailing list archive)
State New, archived
Headers show
Series [kvm-unit-tests,v2] arm64: Fix compiling with ancient compiler | expand

Commit Message

Andrew Jones Feb. 3, 2022, 3:13 p.m. UTC
When compiling with an ancient compiler (gcc-4.8.5-36.el7_6.2.aarch64)
the build fails with

  lib/libcflat.a(alloc.o): In function `mult_overflow':
  /home/drjones/kvm-unit-tests/lib/alloc.c:19: undefined reference to `__multi3'

According to kernel commit fb8722735f50 ("arm64: support __int128 on
gcc 5+") gcc older than 5 will emit __multi3 for __int128 multiplication.
To fix this, let's just use check_mul_overflow(), which does overflow
checking with GCC7.1+ and nothing for older gcc. We lose the fallback
for older gcc, but oh, well, the heavily negative diffstat is just too
tempting to go for another solution.

While we're cleaning up lib/alloc.c with the function deletion also take
the opportunity to clean up the include style and add an SPDX header.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 lib/alloc.c | 41 ++++++-----------------------------------
 1 file changed, 6 insertions(+), 35 deletions(-)

Comments

Thomas Huth Feb. 4, 2022, 4:51 p.m. UTC | #1
On 03/02/2022 16.13, Andrew Jones wrote:
> When compiling with an ancient compiler (gcc-4.8.5-36.el7_6.2.aarch64)
> the build fails with
> 
>    lib/libcflat.a(alloc.o): In function `mult_overflow':
>    /home/drjones/kvm-unit-tests/lib/alloc.c:19: undefined reference to `__multi3'
> 
> According to kernel commit fb8722735f50 ("arm64: support __int128 on
> gcc 5+") gcc older than 5 will emit __multi3 for __int128 multiplication.
> To fix this, let's just use check_mul_overflow(), which does overflow
> checking with GCC7.1+ and nothing for older gcc. We lose the fallback
> for older gcc, but oh, well, the heavily negative diffstat is just too
> tempting to go for another solution.

Sounds ok to me, too.

Reviewed-by: Thomas Huth <thuth@redhat.com>
Andrew Jones Feb. 9, 2022, 10:18 a.m. UTC | #2
On Thu, Feb 03, 2022 at 04:13:44PM +0100, Andrew Jones wrote:
> When compiling with an ancient compiler (gcc-4.8.5-36.el7_6.2.aarch64)
> the build fails with
> 
>   lib/libcflat.a(alloc.o): In function `mult_overflow':
>   /home/drjones/kvm-unit-tests/lib/alloc.c:19: undefined reference to `__multi3'
> 
> According to kernel commit fb8722735f50 ("arm64: support __int128 on
> gcc 5+") gcc older than 5 will emit __multi3 for __int128 multiplication.
> To fix this, let's just use check_mul_overflow(), which does overflow
> checking with GCC7.1+ and nothing for older gcc. We lose the fallback
> for older gcc, but oh, well, the heavily negative diffstat is just too
> tempting to go for another solution.
> 
> While we're cleaning up lib/alloc.c with the function deletion also take
> the opportunity to clean up the include style and add an SPDX header.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
>  lib/alloc.c | 41 ++++++-----------------------------------
>  1 file changed, 6 insertions(+), 35 deletions(-)
>

Applied to misc/queue
https://gitlab.com/rhdrjones/kvm-unit-tests/-/commits/misc/queue

Thanks,
drew
diff mbox series

Patch

diff --git a/lib/alloc.c b/lib/alloc.c
index f4266f5d064e..51d774ddf5df 100644
--- a/lib/alloc.c
+++ b/lib/alloc.c
@@ -1,48 +1,19 @@ 
-#include "alloc.h"
-#include "asm/page.h"
-#include "bitops.h"
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include <alloc.h>
+#include <bitops.h>
+#include <asm/page.h>
+#include <linux/compiler.h>
 
 void *malloc(size_t size)
 {
 	return memalign(sizeof(long), size);
 }
 
-static bool mult_overflow(size_t a, size_t b)
-{
-#if BITS_PER_LONG == 32
-	/* 32 bit system, easy case: just use u64 */
-	return (u64)a * (u64)b >= (1ULL << 32);
-#else
-#ifdef __SIZEOF_INT128__
-	/* if __int128 is available use it (like the u64 case above) */
-	unsigned __int128 res = a;
-	res *= b;
-	res >>= 64;
-	return res != 0;
-#else
-	u64 tmp;
-
-	if ((a >> 32) && (b >> 32))
-		return true;
-	if (!(a >> 32) && !(b >> 32))
-		return false;
-	tmp = (u32)a;
-	tmp *= (u32)b;
-	tmp >>= 32;
-	if (a < b)
-		tmp += a * (b >> 32);
-	else
-		tmp += b * (a >> 32);
-	return tmp >> 32;
-#endif /* __SIZEOF_INT128__ */
-#endif /* BITS_PER_LONG == 32 */
-}
-
 void *calloc(size_t nmemb, size_t size)
 {
 	void *ptr;
 
-	assert(!mult_overflow(nmemb, size));
+	assert(!check_mul_overflow(nmemb, size));
 	ptr = malloc(nmemb * size);
 	if (ptr)
 		memset(ptr, 0, nmemb * size);