diff mbox series

[uclibc-ng-devel] Re: Bug in memset on ARM

Message ID 164975927733.1938924.415448935756459053@helium.openadk.org
State Superseded
Headers show
Series [uclibc-ng-devel] Re: Bug in memset on ARM | expand

Commit Message

tombannink@gmail.com April 12, 2022, 10:27 a.m. UTC
From 0a45e40834eeb8fc42f74645be715ca14432a767 Mon Sep 17 00:00:00 2001
From: Tom Bannink <tombannink@gmail.com>
Date: Tue, 12 Apr 2022 11:15:41 +0200
Subject: [PATCH] Fix bug in ARM memset implementation

The ARM implementation of memset has a bug when the fill-value is negative or outside the
[0, 255] range. To reproduce:

    char array[256];
    memset(array, -5, 256);

This is supposed to fill the array with int8 values -5, -5, -5, ... . On ARM, this does
not work because the implementation assumes the high bytes of the fill-value argument are
already zero. However in this test case they are filled with 1-bits. The aarch64 and x86_64
implementations do not have this problem: they first convert the fill-value to an unsigned
byte following the specification of memset.

With GCC one can use  `memset(ptr, (-5 & 0xFF), size)` as a workaround, but for clang
users that does not work: clang optimizes the `& 0xFF` away because it assumes that
memset will do it.
---
 libc/string/arm/memset.S | 2 ++
 1 file changed, 2 insertions(+)

Comments

Peter Korsgaard April 12, 2022, 1:18 p.m. UTC | #1
>>>>> "tombannink" == tombannink  <tombannink@gmail.com> writes:

 > From 0a45e40834eeb8fc42f74645be715ca14432a767 Mon Sep 17 00:00:00 2001
 > From: Tom Bannink <tombannink@gmail.com>
 > Date: Tue, 12 Apr 2022 11:15:41 +0200
 > Subject: [PATCH] Fix bug in ARM memset implementation

 > The ARM implementation of memset has a bug when the fill-value is negative or outside the
 > [0, 255] range. To reproduce:

Thanks!

 > +++ b/libc/string/arm/memset.S
 > @@ -32,6 +32,7 @@ memset:
 >  	cmp	r2, #8		@ at least 8 bytes to do?
 >  	bcc	2f
 
 > +	uxtb	r1, r1

uxtb is an ARMv6+ instruction, maybe use and instead for compatibility?

https://developer.arm.com/documentation/dui0489/i/arm-and-thumb-instructions/uxtb
diff mbox series

Patch

diff --git a/libc/string/arm/memset.S b/libc/string/arm/memset.S
index 412270f50..f4b30b3dc 100644
--- a/libc/string/arm/memset.S
+++ b/libc/string/arm/memset.S
@@ -32,6 +32,7 @@  memset:
 	cmp	r2, #8		@ at least 8 bytes to do?
 	bcc	2f
 
+	uxtb	r1, r1
 	lsl	r3, r1, #8
 	orr	r1, r3
 	lsl	r3, r1, #16
@@ -68,6 +69,7 @@  memset:
 	mov	a4, a1
 	cmp	a3, $8		@ at least 8 bytes to do?
 	blo	2f
+	uxtb	a2, a2
 	orr	a2, a2, a2, lsl $8
 	orr	a2, a2, a2, lsl $16
 1: