while working on an optimized version of strnlen, some string tests fail
Nam-goo Lee
devnglee@gmail.com
Fri Dec 2 05:24:00 GMT 2016
This is my current 'make check' result.
XPASS: elf/tst-protected1a
XPASS: elf/tst-protected1b
FAIL: malloc/tst-malloc-thread-fail
UNSUPPORTED: math/test-nearbyint-except-2
FAIL: nptl/tst-cancel24-static
FAIL: posix/tst-getaddrinfo5
Summary of test results:
3 FAIL
2432 PASS
1 UNSUPPORTED
43 XFAIL
2 XPASS
malloc/tst-malloc-thread-fail.out says "Timed out: killed the child process".
Is it possible that this test failure relates to something with my
test environment, rather than my implementation?
I'm testing on an ODROID-XU4 board.
nptl/tst-cancel24-static.out says "Didn't expect signal from child:
got `Segmentation fault'"
and this failure is mentioned at
<https://sourceware.org/glibc/wiki/Release/2.24#Build_and_test_issues>.
(I'm running the test case on the 2.24 version branch).
posix/tst-getaddrinfo5 seems to fail because my test board does not
have an internet connection.
Is it okay to ignore tests listed as UNSUPPORTED, XFAIL, and XPASS?
2016-11-18 3:52 GMT+09:00 Adhemerval Zanella <adhemerval.zanella@linaro.org>:
>
>
> On 17/11/2016 16:27, Nam-goo Lee wrote:
>> Hi.
>>
>> I'm working on an optimized version of strnlen function for arm.
>> But following tests fail, and I'm stuck here finding the reasons for
>> the failure.
>>
>> FAIL: string/stratcliff
>> FAIL: string/test-stpncpy
>> FAIL: string/test-strncpy
>> Summary of test results:
>> 3 FAIL
>> 57 PASS
>>
>> I'm surprised to see that tests for functions other than strnlen fail.
>> I'd really appreciate to get some hints on what the 'stratcliff' test does,
>> and the reasons for the failure.
>> Attached my code.
>>
>> Thanks.
>>
>
> Hi,
>
> ARM uses default string/str{n,p}cpy.c code and strncpy code has:
>
> 26 char *
> 27 STRNCPY (char *s1, const char *s2, size_t n)
> 28 {
> 29 size_t size = __strnlen (s2, n);
>
> So if your optimized strnlen does not provide the expected correct result
> the code will potentially fail. It might the case where it is stressing
> a case that test-strnlen does not issue. Either way, you need to a full
> clean make check to make sure the implementation is ready for upstream review.
-------------- next part --------------
#include <sysdep.h>
ENTRY (__strnlen)
@ r0 : STR
@ r1 : MAXLEN
.balign 64
cbz r1, 99f @ Check whether MAXLEN is 0
sfi_breg r0, \
ldrb r2, [\B] @ Reads a cache line
cbz r2, 98f
@ No double-word operations if MAXLEN < 8
cmp r1, #8
bcs .Ldword
mov r3, r0 @ Save STR
1: subs r1, r1, #1 @ Look for more characters?
beq 2f
sfi_breg r0, \
ldrb r2, [\B, #1]!
@ r0 : Addr of r2
@ r1 : Remaining number of bytes to search
@ r2 : Data
@ r3 : Saved STR
cmp r2, #0 @ Is it '\0'?
bne 1b
sub r0, r0, r3
DO_RET(lr)
2: add r0, r0, #1
sub r0, r0, r3
DO_RET(lr)
98: mov r1, r2
99: mov r0, r1
DO_RET(lr)
.Ldword:
push {r4}
@ Check whether STR + MAXLEN overflows to pass strnlen (s, -1) test.
adds r1, r0, r1
it cs
mvncs r1, #0
ands r4, r0, #7 @ r4: offset
bne .Lnot_aligned
mov r4, r0 @ Save STR
sfi_breg r0, \
ldrd r2, r3, [\B], #8
.Lmain_restart:
#ifdef ARCH_HAS_T2
movw ip, #0x0101
sfi_pld r0, #32
movt ip, #0x0101
#else
ldr ip, =0x01010101
sfi_pld r0, #32
#endif
.Lmain_loop:
@ r0 : (addr of r2) + 8
@ r1 : END_PTR (string/strnlen.c)
@ r2 : lower word
@ r3 : higher word
@ r4 : saved STR
@ ip : 0x01010101
uqsub8 r2, ip, r2
uqsub8 r3, ip, r3
sfi_pld r0, #64
orrs r3, r3, r2
bne .Lfound
cmp r0, r1
bcs .Lmaxlen
sfi_breg r0, \
ldrd r2, r3, [\B], #8
uqsub8 r2, ip, r2
uqsub8 r3, ip, r3
sfi_pld r0, #128
orrs r3, r3, r2
bne .Lfound
cmp r0, r1
bcs .Lmaxlen
sfi_breg r0, \
ldrd r2, r3, [\B], #8
uqsub8 r2, ip, r2
uqsub8 r3, ip, r3
sfi_pld r0, #192
orrs r3, r3, r2
bne .Lfound
cmp r0, r1
bcs .Lmaxlen
sfi_breg r0, \
ldrd r2, r3, [\B], #8
uqsub8 r2, ip, r2
uqsub8 r3, ip, r3
orrs r3, r3, r2
bne .Lfound
cmp r0, r1
it cc
sfi_breg r0, \
ldrdcc r2, r3, [\B], #8
bcc .Lmain_loop
@ END_PTR reached
.Lmaxlen:
sub r0, r1, r4
pop {r4}
DO_RET(lr)
.Lfound:
@ Found something. Disambiguate between first and second words.
@ Adjust r0 to point to the word containing the match.
@ Adjust r2 to the found bits for the word containing the match.
sub r0, r0, #4
cmp r2, #0
ite eq
moveq r2, r3
subne r0, r0, #4
#ifdef __ARMEL__
rev r2, r2
#endif
clz r2, r2
add r0, r0, r2, lsr #3
cmp r0, r1
it hi
movhi r0, r1
sub r0, r0, r4
pop {r4}
DO_RET(lr)
.Lnot_aligned:
@ r0 : STR
@ r1 : END_PTR (check string/strnlen.c)
@ r4 : offset
cmp r4, #4
it cs @ Starting byte is at r3
subcs r4, r4, #4
rsb r4, r4, #4
mov ip, r4, lsl #3 @ Byte to bit conversion
mvn r4, #0
#ifdef __ARMEB__
mov ip, r4, lsl ip
#else
mov ip, r4, lsr ip
#endif
mov r4, r0 @ Save STR
bic r0, r0, #7
sfi_breg r0, \
ldrd r2, r3, [\B], #8
it cs
movcs r2, r3
orr r2, r2, ip @ Fill in bytes before STR with 0xff
itt cs
movcs r3, r2
mvncs r2, #0
b .Lmain_restart
END (__strnlen)
libc_hidden_def (__strnlen)
weak_alias (__strnlen, strnlen)
libc_hidden_def (strnlen)
More information about the Libc-help
mailing list