From 623764d507bf56228a98af0f2e28d9f70e802034 Mon Sep 17 00:00:00 2001 From: Chen Wang Date: Fri, 6 May 2022 09:26:23 +0800 Subject: [PATCH] continue sync for mem* try best to sync with RVI upstream, till now it still works - __memset_chk - memcmp but moving forward, when I tried to replace memcpy(), crash happen again. --- libc/Android.bp | 9 +- .../dynamic_function_dispatch.cpp | 45 +++++++ libc/arch-riscv64/generic/bionic/memcmp.S | 115 ++++++++++++++++++ libc/arch-riscv64/generic/bionic/memcmp.c | 8 -- libc/arch-riscv64/generic/bionic/memset.c | 10 -- libc/arch-riscv64/generic/bionic/memset_chk.c | 13 ++ libc/arch-riscv64/static_function_dispatch.S | 37 ++++++ 7 files changed, 218 insertions(+), 19 deletions(-) create mode 100644 libc/arch-riscv64/dynamic_function_dispatch.cpp create mode 100644 libc/arch-riscv64/generic/bionic/memcmp.S delete mode 100644 libc/arch-riscv64/generic/bionic/memcmp.c create mode 100644 libc/arch-riscv64/generic/bionic/memset_chk.c create mode 100644 libc/arch-riscv64/static_function_dispatch.S diff --git a/libc/Android.bp b/libc/Android.bp index cf1c49f4e..a81796eaf 100644 --- a/libc/Android.bp +++ b/libc/Android.bp @@ -906,7 +906,8 @@ cc_library_static { riscv64: { srcs: [ - "arch-riscv64/generic/bionic/memcmp.c", + "arch-riscv64/generic/bionic/memcmp.S", + "arch-riscv64/generic/bionic/memset_chk.c", "arch-riscv64/generic/bionic/memset.c", "arch-riscv64/generic/bionic/memcpy.c", "arch-riscv64/bionic/__bionic_clone.S", @@ -1540,6 +1541,9 @@ cc_library_static { arm64: { srcs: ["arch-arm64/static_function_dispatch.S"], }, + riscv64: { + srcs: ["arch-riscv64/static_function_dispatch.S"], + }, }, } @@ -1565,6 +1569,9 @@ cc_library_static { arm64: { srcs: ["arch-arm64/dynamic_function_dispatch.cpp"], }, + riscv64: { + srcs: ["arch-riscv64/dynamic_function_dispatch.cpp"], + }, }, } diff --git a/libc/arch-riscv64/dynamic_function_dispatch.cpp b/libc/arch-riscv64/dynamic_function_dispatch.cpp new file mode 100644 index 000000000..86c07a27d --- /dev/null +++ b/libc/arch-riscv64/dynamic_function_dispatch.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include + +extern "C" { + +typedef int memcmp_func(const void* __lhs, const void* __rhs, size_t __n); +DEFINE_IFUNC_FOR(memcmp) { + RETURN_FUNC(memcmp_func, memcmp_generic); +} + +typedef void* __memset_chk_func(void *s, int c, size_t n, size_t n2); +DEFINE_IFUNC_FOR(__memset_chk) { + RETURN_FUNC(__memset_chk_func, __memset_chk_generic); +} + +} // extern "C" diff --git a/libc/arch-riscv64/generic/bionic/memcmp.S b/libc/arch-riscv64/generic/bionic/memcmp.S new file mode 100644 index 000000000..94ec4c40f --- /dev/null +++ b/libc/arch-riscv64/generic/bionic/memcmp.S @@ -0,0 +1,115 @@ +// Prototype: int memcmp (const char *s1, const char *s2, int n). + +#include + +ENTRY(memcmp_generic) + addi a2, a2, -8 + bltz a2, .L_less_than_8 + ld a4, 0(a0) + ld a5, 0(a1) + sub t1, a4, a5 + bnez t1, .L_ret + + addi a2, a2, -8 + bgtz a2, .L_more_than_16 + + add a0, a0, a2 + add a1, a1, a2 + ld a4, 8(a0) + ld a5, 8(a1) + sub t1, a4, a5 + j .L_ret +.L_more_than_16: + ld a4, 8(a0) + ld a5, 8(a1) + sub t1, a4, a5 + bnez t1, .L_ret + + addi a2, a2, -16 + addi a0, a0, 16 + addi a1, a1, 16 + bltz a2, .L_last_bytes + + addi a3, a2, -96 + bltz a3, .L_loop16 + + andi a3, a0, 15 + add a2, a2, a3 + sub a0, a0, a3 + sub a1, a1, a3 +.L_loop16: + ld a4, 0(a0) + ld a5, 0(a1) + addi a2, a2, -16 + ld a6, 8(a0) + ld a7, 8(a1) + addi a0, a0, 16 + addi a1, a1, 16 + sltz t1, a2 + sub t2, a4, a5 + sub t3, a6, a7 + or t1, t1, t2 + or t1, t1, t3 + beqz t1, .L_loop16 + + sub t1, a4, a5 + bnez t1, .L_ret + sub t1, a6, a7 + mv a4, a6 + mv a5, a7 + bnez t1, .L_ret + +.L_last_bytes: + add a0, a0, a2 + add a1, a1, a2 + ld a4, 0(a0) + ld a5, 0(a1) + sub t1, a4, a5 + bnez t1, .L_ret + ld a4, 8(a0) + ld a5, 8(a1) + sub t1, a4, a5 +.L_ret: + li t2, 0 +.L_ret_loop: + srl a6, a4, t2 + andi a6, a6, 0xff + srl a7, a5, t2 + andi a7, a7, 0xff + sub a0, a6, a7 + bnez a0, .L_ret_val + addi t2, t2, 8 + addi t3, t2, -64 + bltz t3, .L_ret_loop +.L_ret_val: + ret + +.L_less_than_8: + addi a2, a2, 4 + bltz a2, .L_less_than_4 + lw a4, 0(a0) + lw a5, 0(a1) + sub t1, a4, a5 + bnez t1, .L_ret + addi a0, a0, 4 + addi a1, a1, 4 + addi a2, a2, -4 +.L_less_than_4: + addi a2, a2, 4 + beqz a2, .L_ret_0 +.L_byte_loop: + lbu a4, 0(a0) + lbu a5, 0(a1) + addi a0, a0, 1 + addi a1, a1, 1 + addi a2, a2, -1 + sub t1, a4, a5 + bnez t1, .L_ret_valb + bgtz a2, .L_byte_loop +.L_ret_valb: + mv a0, t1 + ret +.L_ret_0: + li a0, 0 + ret +END(memcmp_generic) diff --git a/libc/arch-riscv64/generic/bionic/memcmp.c b/libc/arch-riscv64/generic/bionic/memcmp.c deleted file mode 100644 index e71027a06..000000000 --- a/libc/arch-riscv64/generic/bionic/memcmp.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int memcmp(const void *vl, const void *vr, size_t n) -{ - const unsigned char *l=vl, *r=vr; - for (; n && *l == *r; n--, l++, r++); - return n ? *l-*r : 0; -} \ No newline at end of file diff --git a/libc/arch-riscv64/generic/bionic/memset.c b/libc/arch-riscv64/generic/bionic/memset.c index bd5cd92be..e490845e5 100644 --- a/libc/arch-riscv64/generic/bionic/memset.c +++ b/libc/arch-riscv64/generic/bionic/memset.c @@ -37,13 +37,3 @@ void *memset(void *dest, int c, size_t n) return dest; } - -extern void* __memset_chk_fail(); -void * -__memset_chk (void *dstpp, int c, unsigned long len, unsigned long dstlen) -{ - if (dstlen < len) - __memset_chk_fail (); - - return memset (dstpp, c, len); -} diff --git a/libc/arch-riscv64/generic/bionic/memset_chk.c b/libc/arch-riscv64/generic/bionic/memset_chk.c new file mode 100644 index 000000000..4fa74fc30 --- /dev/null +++ b/libc/arch-riscv64/generic/bionic/memset_chk.c @@ -0,0 +1,13 @@ +#include + +void *memset(void * s, int c, unsigned long n); + +extern void* __memset_chk_fail(); +void * +__memset_chk_generic (void *dstpp, int c, unsigned long len, unsigned long dstlen) +{ + if (dstlen < len) + __memset_chk_fail (); + + return memset (dstpp, c, len); +} diff --git a/libc/arch-riscv64/static_function_dispatch.S b/libc/arch-riscv64/static_function_dispatch.S new file mode 100644 index 000000000..c6a5dded2 --- /dev/null +++ b/libc/arch-riscv64/static_function_dispatch.S @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#define FUNCTION_DELEGATE(name, impl) \ +ENTRY(name); \ + call t0,impl; \ +END(name) + +FUNCTION_DELEGATE(__memset_chk, __memset_chk_generic) +FUNCTION_DELEGATE(memcmp, memcmp_generic) -- Gitee