From 3cfb52aab2548df635e9672218cc433e14922fd3 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Wed, 18 Feb 2015 21:29:13 -0800 Subject: [PATCH] Add GNU extensions mempcpy and wmemcpy. Used by elfutils. On the bright side, they stopped using __mempcpy. Bug: 18374026 Change-Id: Id29bbe6ef1c5ed5a171bb6c32182f129d8332abb --- libc/Android.mk | 2 ++ libc/bionic/mempcpy.cpp | 33 +++++++++++++++++++++++++++++++++ libc/bionic/wmempcpy.cpp | 33 +++++++++++++++++++++++++++++++++ libc/include/string.h | 3 +++ libc/include/wchar.h | 3 +++ tests/string_test.cpp | 5 +++++ tests/wchar_test.cpp | 5 +++++ 7 files changed, 84 insertions(+) create mode 100644 libc/bionic/mempcpy.cpp create mode 100644 libc/bionic/wmempcpy.cpp diff --git a/libc/Android.mk b/libc/Android.mk index 7dc7cbf28..9dd386411 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -143,6 +143,7 @@ libc_bionic_ndk_src_files := \ bionic/mbrtoc16.cpp \ bionic/mbrtoc32.cpp \ bionic/mbstate.cpp \ + bionic/mempcpy.cpp \ bionic/mkdir.cpp \ bionic/mkfifo.cpp \ bionic/mknod.cpp \ @@ -214,6 +215,7 @@ libc_bionic_ndk_src_files := \ bionic/wait.cpp \ bionic/wchar.cpp \ bionic/wctype.cpp \ + bionic/wmempcpy.cpp \ libc_bionic_src_files := diff --git a/libc/bionic/mempcpy.cpp b/libc/bionic/mempcpy.cpp new file mode 100644 index 000000000..b7b72f737 --- /dev/null +++ b/libc/bionic/mempcpy.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2015 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 + +void* mempcpy(void* dst, const void* src, size_t n) { + return reinterpret_cast(memcpy(dst, src, n)) + n; +} diff --git a/libc/bionic/wmempcpy.cpp b/libc/bionic/wmempcpy.cpp new file mode 100644 index 000000000..54ebf8662 --- /dev/null +++ b/libc/bionic/wmempcpy.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2015 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 + +wchar_t* wmempcpy(wchar_t* dst, const wchar_t* src, size_t n) { + return wmemcpy(dst, src, n) + n; +} diff --git a/libc/include/string.h b/libc/include/string.h index d67928c0f..fffe1362c 100644 --- a/libc/include/string.h +++ b/libc/include/string.h @@ -44,6 +44,9 @@ extern void* memchr(const void *, int, size_t) __purefunc; extern void* memrchr(const void *, int, size_t) __purefunc; extern int memcmp(const void *, const void *, size_t) __purefunc; extern void* memcpy(void* __restrict, const void* __restrict, size_t); +#if defined(__USE_GNU) +extern void* mempcpy(void* __restrict, const void* __restrict, size_t); +#endif extern void* memmove(void *, const void *, size_t); extern void* memset(void *, int, size_t); extern void* memmem(const void *, size_t, const void *, size_t) __purefunc; diff --git a/libc/include/wchar.h b/libc/include/wchar.h index cfd22992b..ea6aca03c 100644 --- a/libc/include/wchar.h +++ b/libc/include/wchar.h @@ -151,6 +151,9 @@ extern int wcwidth(wchar_t); extern wchar_t *wmemchr(const wchar_t *, wchar_t, size_t); extern int wmemcmp(const wchar_t *, const wchar_t *, size_t); extern wchar_t *wmemcpy(wchar_t *, const wchar_t *, size_t); +#if defined(__USE_GNU) +extern wchar_t *wmempcpy(wchar_t *, const wchar_t *, size_t); +#endif extern wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t); extern wchar_t *wmemset(wchar_t *, wchar_t, size_t); extern int wprintf(const wchar_t *, ...); diff --git a/tests/string_test.cpp b/tests/string_test.cpp index 66cf848c9..1d63c7668 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -1395,3 +1395,8 @@ TEST(string, strnlen_147048) { EXPECT_EQ(0U, strnlen(heap_src, 1024*1024*1024)); delete[] heap_src; } + +TEST(string, mempcpy) { + char dst[6]; + ASSERT_EQ(&dst[4], reinterpret_cast(mempcpy(dst, "hello", 4))); +} diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp index a1d150117..e86d56dc0 100644 --- a/tests/wchar_test.cpp +++ b/tests/wchar_test.cpp @@ -667,3 +667,8 @@ TEST(wchar, wcstoull_l_EINVAL) { wcstoull_l(L"123", NULL, 37, LC_GLOBAL_LOCALE); ASSERT_EQ(EINVAL, errno); } + +TEST(wchar, wmempcpy) { + wchar_t dst[6]; + ASSERT_EQ(&dst[4], wmempcpy(dst, L"hello", 4)); +}