Fix a broken corner case of strlen()/strnlen() on aarch64eb

Previously a string such as "\x1\x1\x1\x1\x1\x1\x1" would count as
0 instead of 7 on BE.
This commit is contained in:
jakllsch 2020-09-05 20:24:43 +00:00
parent d908d8a1ee
commit ea3caf96e6

View File

@ -1,4 +1,4 @@
/* $NetBSD: strlen.S,v 1.3 2018/08/01 17:09:26 ryo Exp $ */ /* $NetBSD: strlen.S,v 1.4 2020/09/05 20:24:43 jakllsch Exp $ */
/*- /*-
* Copyright (c) 2014 The NetBSD Foundation, Inc. * Copyright (c) 2014 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include <machine/asm.h> #include <machine/asm.h>
RCSID("$NetBSD: strlen.S,v 1.3 2018/08/01 17:09:26 ryo Exp $") RCSID("$NetBSD: strlen.S,v 1.4 2020/09/05 20:24:43 jakllsch Exp $")
#ifdef STRNLEN #ifdef STRNLEN
#define FUNCNAME strnlen #define FUNCNAME strnlen
@ -96,9 +96,15 @@ ENTRY(FUNCNAME)
/* /*
* We know there is a NUL in this dword. Use clz to find it. * We know there is a NUL in this dword. Use clz to find it.
*/ */
#ifdef __AARCH64EL__ #ifdef __AARCH64EB__
rev x6, x6 /* convert to BE */ /* avoid BE problem due to carry propagation if last non-NUL is \x01 */
ldr x7, [x4, #-8] /* reload dword */
rev x7, x7 /* byte swap */
sub x6, x7, x11 /* a = X - 1 */
orr x7, x7, #MASK8_0x7f /* b = X | 0x7f */
bic x6, x6, x7 /* a & ~b */
#endif #endif
rev x6, x6 /* convert to BE */
clz x6, x6 /* find null byte */ clz x6, x6 /* find null byte */
add x0, x0, x6, lsr #3 /* add offset to the length */ add x0, x0, x6, lsr #3 /* add offset to the length */