This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
  }
   


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]