On Wed, Sep 24, 2008 at 4:17 PM, Tobias Poschwatta <[EMAIL PROTECTED]> wrote: > On Wed, Sep 24, 2008 at 01:33:52PM -0700, Khem Raj wrote: >> I can not reproduce it on a eabi system and there has been few changes >> in this file. I do not have oabi system to test against. Can you try >> same on eabi system ? > > Unfortunately, I don't have an eabi system to test. However, I had a > closer look in gdb. This is what I found: > > I order to debug the strncmp function, I had to create another test > program, because in the first version strncmp was inlined and the code > somehow reduced to 'printf("%d", 0);'. The new test program is: > > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > > int main(int argc, char **argv) > { > const char *s1 = "aa"; > const char *s2 = "ab"; > printf("%s <=> %s => %d\n", s1, s2, strncmp(s1, s2, -1)); > exit(0); > } > > > readelf -s now shows a reference to strncmp. > > Using gdb to disassemble strncmp gives: > > (gdb) disass strncmp > Dump of assembler code for function strncmp: > 0x400398e0 <strncmp+0>: cmp r2, #0 ; 0x0 > 0x400398e4 <strncmp+4>: moveq r0, #0 ; 0x0 > 0x400398e8 <strncmp+8>: moveq pc, lr > 0x400398ec <strncmp+12>: subs r2, r2, #1 ; 0x1 > 0x400398f0 <strncmp+16>: add r12, r0, r2 > 0x400398f4 <strncmp+20>: ldrb r2, [r0], #1 > 0x400398f8 <strncmp+24>: ldrb r3, [r1], #1 > 0x400398fc <strncmp+28>: cmp r12, r0 > 0x40039900 <strncmp+32>: cmpcs r2, #1 ; 0x1 > 0x40039904 <strncmp+36>: cmpcs r2, r3 > 0x40039908 <strncmp+40>: beq 0x400398f4 <strncmp+20> > 0x4003990c <strncmp+44>: sub r0, r2, r3 > 0x40039910 <strncmp+48>: mov pc, lr > End of assembler dump. > > This matches the non-thumb version in libc/string/arm/strncmp.S > (__USE_BX__ undefined). > > When reaching the strncmp, the parameters r0, r1 and r2 have the > expected values: > > Breakpoint 1, 0x400398e0 in strncmp () from /ffp/lib/libc.so.0 > > (gdb) x/4c $r0 > 0x84e4 <_fini+20>: 97 'a' 97 'a' 0 '\0' 0 '\0' > (gdb) x/4c $r1 > 0x84e8 <_fini+24>: 97 'a' 98 'b' 0 '\0' 0 '\0' > (gdb) p $r2 > $13 = 4294967295 > > Now, stepping through the function with 'si' doesn't loop at > 0x40039908 <strncmp+40>: beq 0x400398f4 <strncmp+20> > but continues although r2 == r3 == 'a'. > > At line > 0x400398f0 <strncmp+16>: add r12, r0, r2 > register r12 (ip) is set to r0 + r2. Because r2 is UINT_MAX - 1 at > this point, r12 ends up being r0 - 2. > > The comparison > 0x400398fc <strncmp+28>: cmp r12, r0 > clears carry, so the two cmpcs are not executed, zero is not set, > and the branch not taken. > > Unless I got this completely wrong, this looks like a bug.
You analysis looks ok. The current implementation assumes that size parameter will not overflow. I dont see an easy way to fix the current implementation. I think it would be better to use a C algorithm. > > Tobias > > > > > > > > > > > > > > _______________________________________________ uClibc mailing list uClibc@uclibc.org http://busybox.net/cgi-bin/mailman/listinfo/uclibc