diff --git a/libc/Android.mk b/libc/Android.mk index d8c8f63ac..e2608710b 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -256,7 +256,6 @@ libc_upstream_freebsd_src_files := \ upstream-freebsd/lib/libc/string/wcstok.c \ upstream-freebsd/lib/libc/string/wmemchr.c \ upstream-freebsd/lib/libc/string/wmemcpy.c \ - upstream-freebsd/lib/libc/string/wmemmove.c \ upstream-freebsd/lib/libc/string/wmemset.c \ libc_upstream_netbsd_src_files := \ diff --git a/libc/arch-arm/arm.mk b/libc/arch-arm/arm.mk index c509b8366..7c423ab89 100644 --- a/libc/arch-arm/arm.mk +++ b/libc/arch-arm/arm.mk @@ -24,6 +24,7 @@ libc_common_src_files_arm += \ upstream-freebsd/lib/libc/string/wcslen.c \ upstream-freebsd/lib/libc/string/wcsrchr.c \ upstream-freebsd/lib/libc/string/wmemcmp.c \ + upstream-freebsd/lib/libc/string/wmemmove.c \ upstream-openbsd/lib/libc/string/bcopy.c \ upstream-openbsd/lib/libc/string/stpcpy.c \ upstream-openbsd/lib/libc/string/stpncpy.c \ diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk index 93b0b0b27..cd8b6ea09 100644 --- a/libc/arch-arm64/arm64.mk +++ b/libc/arch-arm64/arm64.mk @@ -14,7 +14,6 @@ libc_common_src_files_arm64 := \ upstream-freebsd/lib/libc/string/wcslen.c \ upstream-freebsd/lib/libc/string/wcsrchr.c \ upstream-freebsd/lib/libc/string/wmemcmp.c \ - upstream-openbsd/lib/libc/string/bcopy.c \ upstream-openbsd/lib/libc/string/stpcpy.c \ upstream-openbsd/lib/libc/string/stpncpy.c \ upstream-openbsd/lib/libc/string/strcat.c \ diff --git a/libc/arch-arm64/generic/bionic/bcopy.S b/libc/arch-arm64/generic/bionic/bcopy.S new file mode 100644 index 000000000..7079e8b8d --- /dev/null +++ b/libc/arch-arm64/generic/bionic/bcopy.S @@ -0,0 +1,30 @@ +/* Copyright (c) 2014, Linaro Limited + 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. + * Neither the name of the Linaro nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + 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 + HOLDER 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. +*/ + +#define BCOPY +#include "memmove.S" +#undef BCOPY diff --git a/libc/arch-arm64/generic/bionic/memmove.S b/libc/arch-arm64/generic/bionic/memmove.S index d6ecb868b..a27c79e4d 100644 --- a/libc/arch-arm64/generic/bionic/memmove.S +++ b/libc/arch-arm64/generic/bionic/memmove.S @@ -29,13 +29,19 @@ * * ARMv8-a, AArch64 * Unaligned accesses + * wchar_t is 4 bytes */ #include /* Parameters and result. */ +#ifdef BCOPY +#define dstin x1 +#define src x0 +#else #define dstin x0 #define src x1 +#endif #define count x2 #define tmp1 x3 #define tmp1w w3 @@ -54,7 +60,14 @@ #define D_l x13 #define D_h x14 +#ifdef BCOPY +ENTRY(bcopy) +#elif defined(WMEMMOVE) +ENTRY(wmemmove) + lsl count, count, #2 +#else ENTRY(memmove) +#endif cmp dstin, src b.lo .Ldownwards add tmp1, src, count @@ -316,4 +329,10 @@ ENTRY(memmove) tst count, #0x3f b.ne .Ltail63down ret +#ifdef BCOPY +END(bcopy) +#elif defined(WMEMMOVE) +END(wmemmove) +#else END(memmove) +#endif diff --git a/libc/arch-arm64/generic/bionic/wmemmove.S b/libc/arch-arm64/generic/bionic/wmemmove.S new file mode 100644 index 000000000..e4f67f759 --- /dev/null +++ b/libc/arch-arm64/generic/bionic/wmemmove.S @@ -0,0 +1,30 @@ +/* Copyright (c) 2014, Linaro Limited + 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. + * Neither the name of the Linaro nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + 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 + HOLDER 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. +*/ + +#define WMEMMOVE +#include "memmove.S" +#undef WMEMMOVE diff --git a/libc/arch-arm64/generic/generic.mk b/libc/arch-arm64/generic/generic.mk index 14920a695..2ecc90ebb 100644 --- a/libc/arch-arm64/generic/generic.mk +++ b/libc/arch-arm64/generic/generic.mk @@ -1,4 +1,5 @@ libc_bionic_src_files_arm64 += \ + arch-arm64/generic/bionic/bcopy.S \ arch-arm64/generic/bionic/memcmp.S \ arch-arm64/generic/bionic/memcpy.S \ arch-arm64/generic/bionic/memmove.S \ @@ -7,3 +8,4 @@ libc_bionic_src_files_arm64 += \ arch-arm64/generic/bionic/strlen.S \ arch-arm64/generic/bionic/strncmp.S \ arch-arm64/generic/bionic/strnlen.S \ + arch-arm64/generic/bionic/wmemmove.S diff --git a/libc/arch-mips/mips.mk b/libc/arch-mips/mips.mk index 2c87a9ee3..0244712c4 100644 --- a/libc/arch-mips/mips.mk +++ b/libc/arch-mips/mips.mk @@ -26,6 +26,7 @@ libc_common_src_files_mips += \ upstream-freebsd/lib/libc/string/wcslen.c \ upstream-freebsd/lib/libc/string/wcsrchr.c \ upstream-freebsd/lib/libc/string/wmemcmp.c \ + upstream-freebsd/lib/libc/string/wmemmove.c \ upstream-openbsd/lib/libc/string/bcopy.c \ upstream-openbsd/lib/libc/string/stpcpy.c \ upstream-openbsd/lib/libc/string/stpncpy.c \ diff --git a/libc/arch-mips64/mips64.mk b/libc/arch-mips64/mips64.mk index 26390a648..575910470 100644 --- a/libc/arch-mips64/mips64.mk +++ b/libc/arch-mips64/mips64.mk @@ -16,6 +16,7 @@ libc_common_src_files_mips64 := \ upstream-freebsd/lib/libc/string/wcslen.c \ upstream-freebsd/lib/libc/string/wcsrchr.c \ upstream-freebsd/lib/libc/string/wmemcmp.c \ + upstream-freebsd/lib/libc/string/wmemmove.c \ upstream-openbsd/lib/libc/string/bcopy.c \ upstream-openbsd/lib/libc/string/stpcpy.c \ upstream-openbsd/lib/libc/string/stpncpy.c \ diff --git a/libc/arch-x86/x86.mk b/libc/arch-x86/x86.mk index aa183cb83..d13a93435 100644 --- a/libc/arch-x86/x86.mk +++ b/libc/arch-x86/x86.mk @@ -12,6 +12,7 @@ libc_common_src_files_x86 += \ bionic/__memset_chk.cpp \ bionic/__strcpy_chk.cpp \ bionic/__strcat_chk.cpp \ + upstream-freebsd/lib/libc/string/wmemmove.c \ # These are shared by all the 32-bit targets, but not the 64-bit ones. diff --git a/libc/arch-x86_64/x86_64.mk b/libc/arch-x86_64/x86_64.mk index e3c2562bb..c54cdb891 100644 --- a/libc/arch-x86_64/x86_64.mk +++ b/libc/arch-x86_64/x86_64.mk @@ -14,6 +14,7 @@ libc_common_src_files_x86_64 := \ upstream-freebsd/lib/libc/string/wcslen.c \ upstream-freebsd/lib/libc/string/wcsrchr.c \ upstream-freebsd/lib/libc/string/wmemcmp.c \ + upstream-freebsd/lib/libc/string/wmemmove.c \ upstream-openbsd/lib/libc/string/strlcat.c \ upstream-openbsd/lib/libc/string/strlcpy.c \ diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp index 50b860893..5fa5bf992 100644 --- a/tests/wchar_test.cpp +++ b/tests/wchar_test.cpp @@ -442,3 +442,14 @@ TEST(wchar, wcsftime) { EXPECT_EQ(24U, wcsftime(buf, sizeof(buf), L"%c", &t)); EXPECT_STREQ(L"Sun Mar 10 00:00:00 2100", buf); } + +TEST(wchar, wmemmove) { + const wchar_t const_wstr[] = L"This is a test of something or other....."; + wchar_t* wstr = new wchar_t[sizeof(const_wstr)]; + + wmemmove(wstr, const_wstr, sizeof(const_wstr)/sizeof(wchar_t)); + EXPECT_STREQ(const_wstr, wstr); + + wmemmove(wstr+5, wstr, sizeof(const_wstr)/sizeof(wchar_t) - 5); + EXPECT_STREQ(L"This This is a test of something or other.", wstr); +}