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