Fix XScale's memset() function
Nick Clifton
nickc@cambridge.redhat.com
Thu Jan 17 08:59:00 GMT 2002
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;
}
More information about the Newlib
mailing list