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:
parent
d908d8a1ee
commit
ea3caf96e6
@ -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 */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user