This is the mail archive of the
newlib@sources.redhat.com
mailing list for the newlib project.
Fix XScale's memset() function
- From: Nick Clifton <nickc at cambridge dot redhat dot com>
- To: newlib at sources dot redhat dot com
- Date: 17 Jan 2002 16:57:58 +0000
- Subject: Fix XScale's memset() function
Hi Guys,
I am applying the patch below to fix a bug found in the hand written
assembler implementation of the memset() function when len == 1 and
the destination address is not word aligned. Under these
circumstances the code would go into an (almost) infinite loop,
happily writing over all of memory in the process.
Detected and tested by running the libstdc++-v3 testsuite.
Cheers
Nick
Index: newlib/libc/machine/xscale/memset.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/machine/xscale/memset.c,v
retrieving revision 1.1
diff -c -3 -p -w -r1.1 memset.c
*** memset.c 2000/11/30 01:57:27 1.1
--- memset.c 2002/01/17 16:55:56
*************** memset (void *dst, int c, size_t len)
*** 24,29 ****
--- 25,37 ----
movs r3, %2
sub %2, %2, #1
bne 0b
+ # At this point we know that %2 == len == -1 (since the SUB has already taken
+ # place). If we fall through to the 1: label (as the code used to do), the
+ # CMP will detect this negative value and branch to the 2: label. This will
+ # test %2 again, but this time against 0. The test will fail and the loop
+ # at 2: will go on for (almost) ever. Hence the explicit branch to the end
+ # of the hand written assembly code.
+ b 4f
1:
cmp %2, #0x3
bls 2f
*************** memset (void *dst, int c, size_t len)
*** 63,79 ****
2:
movs r3, %2
sub %2, %2, #1
! beq 1f
0:
movs r3, %2
sub %2, %2, #1
strb %1, [%0], #1
bne 0b
! 1:"
: "=&r" (dummy), "=&r" (c), "=&r" (len)
: "0" (dst), "1" (c), "2" (len)
: "memory", "r3", "r4", "r5", "lr");
return dst;
}
--- 71,88 ----
2:
movs r3, %2
sub %2, %2, #1
! beq 4f
0:
movs r3, %2
sub %2, %2, #1
strb %1, [%0], #1
bne 0b
! 4:"
: "=&r" (dummy), "=&r" (c), "=&r" (len)
: "0" (dst), "1" (c), "2" (len)
: "memory", "r3", "r4", "r5", "lr");
+
return dst;
}