diff mbox series

[1/2] arm: Implement memcpy ifunc selection in C

Message ID 1507324554-2612-1-git-send-email-adhemerval.zanella@linaro.org
State Superseded
Headers show
Series [1/2] arm: Implement memcpy ifunc selection in C | expand

Commit Message

Adhemerval Zanella Oct. 6, 2017, 9:15 p.m. UTC
This patch refactor ARM memcpy ifunc selector to a C implementation.
No functional change is expected, including ifunc resolution rules.

To avoid build issues with mainline GCC which set no default gnu
indirect function support for ARM (--enable-gnu-indirect-function)
two fixes are added:

  1. The new macro arm_libc_ifunc_hidden_def is redefined using
     direct asm assembly directives instead of function attributes.
     This avoid the incompatbile types for a symbol and its alias.

  2. A new macro NO_MEM_INTERAL_SYM_HACKS is added on symbol-hacks
     and defined on arm ifunc objects.  It avoids the symbol
     definition loop because compiler might emit the hacks for first
     fix before the ifunc function definition itself.

Checked on armv7-linux-gnueabihf and with a build for arm-linux-gnueabi,
arm-linux-gnueabihf with and without multiarch support and with both
GCC 7.1 and GCC mainline.

	* sysdeps/arm/arm-ifunc.h: New file.
	* sysdeps/arm/armv7/multiarch/ifunc-memcpy.h: Likewise.
	* sysdeps/arm/armv7/multiarch/memcpy.c: Likewise.
	* sysdeps/arm/armv7/multiarch/memcpy_arm.S: Likewise.
	* sysdeps/arm/armv7/multiarch/rtld-memcpy.S: Likewise.
	* sysdeps/arm/armv7/multiarch/Makefile [$(subdir) = string]
	(sysdep_routines): Add memcpy_arm.
	(CFLAGS-.os): New rule.
	* sysdeps/arm/armv7/multiarch/memcpy.S: Remove file.
	* sysdeps/generic/symbol-hacks.h: Use mem* alias hacks if not
	defined NO_MEM_INTERAL_SYM_HACKS.
---
 ChangeLog                                  | 12 +++++
 sysdeps/arm/arm-ifunc.h                    | 47 ++++++++++++++++++
 sysdeps/arm/armv7/multiarch/Makefile       |  8 +++-
 sysdeps/arm/armv7/multiarch/ifunc-memcpy.h | 37 +++++++++++++++
 sysdeps/arm/armv7/multiarch/memcpy.S       | 76 ------------------------------
 sysdeps/arm/armv7/multiarch/memcpy.c       | 33 +++++++++++++
 sysdeps/arm/armv7/multiarch/memcpy_arm.S   |  6 +++
 sysdeps/arm/armv7/multiarch/rtld-memcpy.S  |  1 +
 sysdeps/generic/symbol-hacks.h             |  3 +-
 9 files changed, 145 insertions(+), 78 deletions(-)
 create mode 100644 sysdeps/arm/arm-ifunc.h
 create mode 100644 sysdeps/arm/armv7/multiarch/ifunc-memcpy.h
 delete mode 100644 sysdeps/arm/armv7/multiarch/memcpy.S
 create mode 100644 sysdeps/arm/armv7/multiarch/memcpy.c
 create mode 100644 sysdeps/arm/armv7/multiarch/memcpy_arm.S
 create mode 100644 sysdeps/arm/armv7/multiarch/rtld-memcpy.S

-- 
2.7.4

Comments

Joseph Myers Oct. 6, 2017, 11:05 p.m. UTC | #1
On Fri, 6 Oct 2017, Adhemerval Zanella wrote:

> This patch refactor ARM memcpy ifunc selector to a C implementation.

> No functional change is expected, including ifunc resolution rules.

> 

> To avoid build issues with mainline GCC which set no default gnu

> indirect function support for ARM (--enable-gnu-indirect-function)

> two fixes are added:

> 

>   1. The new macro arm_libc_ifunc_hidden_def is redefined using

>      direct asm assembly directives instead of function attributes.

>      This avoid the incompatbile types for a symbol and its alias.

> 

>   2. A new macro NO_MEM_INTERAL_SYM_HACKS is added on symbol-hacks

>      and defined on arm ifunc objects.  It avoids the symbol

>      definition loop because compiler might emit the hacks for first

>      fix before the ifunc function definition itself.


As a general principle, I don't think we should be checking in workarounds 
for defects in unreleased GCC versions (this is not specific to this 
particular issue - it means more generally that if you see a warning 
building with mainline GCC, you need to consider whether that warning is 
buggy before applying glibc changes to avoid the warning).

That is, we should fix the default in GCC mainline and then propose glibc 
changes that do not involve such workarounds.  (Arguably the default 
should be to support the attribute for all architectures, to avoid future 
issues when new architectures gain binutils support for IFUNCs after the 
GCC 8 release.)

-- 
Joseph S. Myers
joseph@codesourcery.com
Adhemerval Zanella Oct. 9, 2017, 11:44 a.m. UTC | #2
On 06/10/2017 20:05, Joseph Myers wrote:
> On Fri, 6 Oct 2017, Adhemerval Zanella wrote:

> 

>> This patch refactor ARM memcpy ifunc selector to a C implementation.

>> No functional change is expected, including ifunc resolution rules.

>>

>> To avoid build issues with mainline GCC which set no default gnu

>> indirect function support for ARM (--enable-gnu-indirect-function)

>> two fixes are added:

>>

>>   1. The new macro arm_libc_ifunc_hidden_def is redefined using

>>      direct asm assembly directives instead of function attributes.

>>      This avoid the incompatbile types for a symbol and its alias.

>>

>>   2. A new macro NO_MEM_INTERAL_SYM_HACKS is added on symbol-hacks

>>      and defined on arm ifunc objects.  It avoids the symbol

>>      definition loop because compiler might emit the hacks for first

>>      fix before the ifunc function definition itself.

> 

> As a general principle, I don't think we should be checking in workarounds 

> for defects in unreleased GCC versions (this is not specific to this 

> particular issue - it means more generally that if you see a warning 

> building with mainline GCC, you need to consider whether that warning is 

> buggy before applying glibc changes to avoid the warning).

> 

> That is, we should fix the default in GCC mainline and then propose glibc 

> changes that do not involve such workarounds.  (Arguably the default 

> should be to support the attribute for all architectures, to avoid future 

> issues when new architectures gain binutils support for IFUNCs after the 

> GCC 8 release.)


There are two different issues here:

  1. My understanding if for 1. is for gcc mainline we are aiming to *not* 
     support glibc builds support for gnu indirection function 
     (--enable-gnu-indirect-function).  I think this is too restrictive and
     since it is possible to support glibc build whether gcc has it supports
     should not prevent this specific support on glibc.

  2. The 2. is indeed a workaround for mainline issue and I agree we should
     avoid pushing fixes for this issues on glibc.  I will work on it.
Ramana Radhakrishnan Oct. 9, 2017, 11:59 a.m. UTC | #3
> That is, we should fix the default in GCC mainline and then propose glibc

> changes that do not involve such workarounds.  (Arguably the default

> should be to support the attribute for all architectures, to avoid future

> issues when new architectures gain binutils support for IFUNCs after the

> GCC 8 release.)


Is there a patch for this to mainline gcc - my quick searches did not
find anything ? I see no reason for not defaulting to this on linux /
glibc configurations in mainline gcc taking care not to break things
for people who use musl or bionic. We've had ifuncs on aarch32 glibc /
binutils for a few years now IIRC so I'm happy to review a patch on
gcc-patches if someone can point me at it or propose a patch ....


regards
Ramana



>

> --

> Joseph S. Myers

> joseph@codesourcery.com
Joseph Myers Oct. 9, 2017, noon UTC | #4
On Mon, 9 Oct 2017, Adhemerval Zanella wrote:

> There are two different issues here:

> 

>   1. My understanding if for 1. is for gcc mainline we are aiming to *not* 

>      support glibc builds support for gnu indirection function 

>      (--enable-gnu-indirect-function).  I think this is too restrictive and

>      since it is possible to support glibc build whether gcc has it supports

>      should not prevent this specific support on glibc.


I believe the goal should be to phase out support for multiarch glibc 
built by compilers without ifunc attribute support for that architecture.  
(Meaning the configure test for multiarch support would end up requiring 
the attribute support, say once we require GCC >= 8 to build glibc.)  
Using the attribute gives better debug info, and we want to avoid having 
too many arbitrarily different ways to build glibc.

-- 
Joseph S. Myers
joseph@codesourcery.com
Joseph Myers Oct. 9, 2017, 12:13 p.m. UTC | #5
On Mon, 9 Oct 2017, Ramana Radhakrishnan wrote:

> > That is, we should fix the default in GCC mainline and then propose glibc

> > changes that do not involve such workarounds.  (Arguably the default

> > should be to support the attribute for all architectures, to avoid future

> > issues when new architectures gain binutils support for IFUNCs after the

> > GCC 8 release.)

> 

> Is there a patch for this to mainline gcc - my quick searches did not

> find anything ? I see no reason for not defaulting to this on linux /

> glibc configurations in mainline gcc taking care not to break things

> for people who use musl or bionic. We've had ifuncs on aarch32 glibc /

> binutils for a few years now IIRC so I'm happy to review a patch on

> gcc-patches if someone can point me at it or propose a patch ....


My view is that we should default to having the support in GCC for all 
architectures with glibc, whether or not binutils/ABI support exists right 
now, to avoid unnecessarily requiring a GCC update as well as 
binutils/glibc ones to use it when support is added on a new architecture.  
But that would be most friendly to users if the assembler then rejects 
IFUNC creation in the absence of ABI/linker support.

-- 
Joseph S. Myers
joseph@codesourcery.com
Adhemerval Zanella Oct. 9, 2017, 12:39 p.m. UTC | #6
On 09/10/2017 09:00, Joseph Myers wrote:
> On Mon, 9 Oct 2017, Adhemerval Zanella wrote:

> 

>> There are two different issues here:

>>

>>   1. My understanding if for 1. is for gcc mainline we are aiming to *not* 

>>      support glibc builds support for gnu indirection function 

>>      (--enable-gnu-indirect-function).  I think this is too restrictive and

>>      since it is possible to support glibc build whether gcc has it supports

>>      should not prevent this specific support on glibc.

> 

> I believe the goal should be to phase out support for multiarch glibc 

> built by compilers without ifunc attribute support for that architecture.  

> (Meaning the configure test for multiarch support would end up requiring 

> the attribute support, say once we require GCC >= 8 to build glibc.)  

> Using the attribute gives better debug info, and we want to avoid having 

> too many arbitrarily different ways to build glibc.

> 


I agree with you, but currently glibc build just fail with gcc mainline
without ifunc attribute support for such architectures.  What about to
add a configure test for glibc master to check for such failure on
configure (mismatch alias for ifunc resolvers)?
Adhemerval Zanella Oct. 9, 2017, 12:44 p.m. UTC | #7
On 09/10/2017 08:59, Ramana Radhakrishnan wrote:
>> That is, we should fix the default in GCC mainline and then propose glibc

>> changes that do not involve such workarounds.  (Arguably the default

>> should be to support the attribute for all architectures, to avoid future

>> issues when new architectures gain binutils support for IFUNCs after the

>> GCC 8 release.)

> 

> Is there a patch for this to mainline gcc - my quick searches did not

> find anything ? I see no reason for not defaulting to this on linux /

> glibc configurations in mainline gcc taking care not to break things

> for people who use musl or bionic. We've had ifuncs on aarch32 glibc /

> binutils for a few years now IIRC so I'm happy to review a patch on

> gcc-patches if someone can point me at it or propose a patch ....


I will on on it, the patch should be simple enough as the one for
sparc [1].

[1] https://gcc.gnu.org/ml/gcc-patches/2017-09/msg01779.html
Joseph Myers Oct. 9, 2017, 1:39 p.m. UTC | #8
On Mon, 9 Oct 2017, Adhemerval Zanella wrote:

> I agree with you, but currently glibc build just fail with gcc mainline

> without ifunc attribute support for such architectures.  What about to

> add a configure test for glibc master to check for such failure on

> configure (mismatch alias for ifunc resolvers)?


Some such check would be reasonable, once GCC has been changed for ARM.

To be clear, with GCC 7 and before it's reasonable to build IFUNCs using 
the versions of the C macros that get types and debug info wrong.  With 
GCC 8 and later, IFUNCs built in C need to use the ifunc attribute to 
avoid the errors about types (and we'd like to phase out IFUNCs 
implemented in assembly).  So if you get the error for mismatched types, 
and don't have ifunc attribute support, that should be considered a case 
where multiarch support should be disabled by configure, just like if the 
assembler or linker support are missing.

-- 
Joseph S. Myers
joseph@codesourcery.com
Adhemerval Zanella Oct. 9, 2017, 10:12 p.m. UTC | #9
On 09/10/2017 09:44, Adhemerval Zanella wrote:
> 

> 

> On 09/10/2017 08:59, Ramana Radhakrishnan wrote:

>>> That is, we should fix the default in GCC mainline and then propose glibc

>>> changes that do not involve such workarounds.  (Arguably the default

>>> should be to support the attribute for all architectures, to avoid future

>>> issues when new architectures gain binutils support for IFUNCs after the

>>> GCC 8 release.)

>>

>> Is there a patch for this to mainline gcc - my quick searches did not

>> find anything ? I see no reason for not defaulting to this on linux /

>> glibc configurations in mainline gcc taking care not to break things

>> for people who use musl or bionic. We've had ifuncs on aarch32 glibc /

>> binutils for a few years now IIRC so I'm happy to review a patch on

>> gcc-patches if someone can point me at it or propose a patch ....

> 

> I will on on it, the patch should be simple enough as the one for

> sparc [1].

> 

> [1] https://gcc.gnu.org/ml/gcc-patches/2017-09/msg01779.html

> 


Patch for ARM sent for review [1].

[1] https://gcc.gnu.org/ml/gcc-patches/2017-10/msg00521.html
diff mbox series

Patch

diff --git a/sysdeps/arm/arm-ifunc.h b/sysdeps/arm/arm-ifunc.h
new file mode 100644
index 0000000..f7d3473
--- /dev/null
+++ b/sysdeps/arm/arm-ifunc.h
@@ -0,0 +1,47 @@ 
+/* Common definition for ifunc resolvers.  Linux/ARM version.
+   This file is part of the GNU C Library.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <ifunc-init.h>
+
+#define INIT_ARCH()
+
+#define arm_libc_ifunc_redirected(redirected_name, name, expr)	\
+  __ifunc (redirected_name, name, expr(hwcap), int hwcap, INIT_ARCH)
+
+#if defined SHARED
+# ifdef HAVE_GCC_IFUNC
+#  define arm_libc_ifunc_hidden_def(redirect_name, name) \
+  __hidden_ver1 (name, __GI_##name, redirect_name) \
+    __attribute__ ((visibility ("hidden")))
+# else
+/* GCC 8 without support for ifunc issues an error when trying to
+   alias symbols with different prototypes (in this case the redirect
+   one which have the same as the function implementation and the
+   ifunc resolver).  The macro below avoid it by issuing the required
+   alias directly.  */
+#  define arm_libc_ifunc_hidden_def(redirect_name, name) \
+  _arm_ifunc_hidden_ver (__GI_##name, name)
+#  define _arm_ifunc_hidden_ver(local, name)	\
+  asm (".globl " #local ";"			\
+       ".hidden " #local ";"			\
+       #local "=" #name)
+# endif
+#else
+# define arm_libc_ifunc_hidden_def(redirect_name, name)
+#endif
diff --git a/sysdeps/arm/armv7/multiarch/Makefile b/sysdeps/arm/armv7/multiarch/Makefile
index 9e1e61c..24c5e5a 100644
--- a/sysdeps/arm/armv7/multiarch/Makefile
+++ b/sysdeps/arm/armv7/multiarch/Makefile
@@ -1,3 +1,9 @@ 
 ifeq ($(subdir),string)
-sysdep_routines += memcpy_neon memcpy_vfp memchr_neon
+sysdep_routines += memcpy_neon memcpy_vfp memchr_neon memcpy_arm
+
+# For ifunc resolvers compiler might place the alias from generic
+# symbol-hacks.h before the resolver implementation itself.  This
+# causes definition loops and the macro below suppress the alias
+# definition.
+CFLAGS-.os += -DNO_MEM_INTERAL_SYM_HACKS
 endif
diff --git a/sysdeps/arm/armv7/multiarch/ifunc-memcpy.h b/sysdeps/arm/armv7/multiarch/ifunc-memcpy.h
new file mode 100644
index 0000000..78cef2a
--- /dev/null
+++ b/sysdeps/arm/armv7/multiarch/ifunc-memcpy.h
@@ -0,0 +1,37 @@ 
+/* Common definition for memcpy resolver.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef __SOFTFP__
+__typeof (REDIRECT_NAME) OPTIMIZE (arm) attribute_hidden;
+#endif
+__typeof (REDIRECT_NAME) OPTIMIZE (vfp) attribute_hidden;
+__typeof (REDIRECT_NAME) OPTIMIZE (neon) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (int hwcap)
+{
+  if (hwcap & HWCAP_ARM_NEON)
+    return OPTIMIZE (neon);
+#ifdef __SOFTFP__
+  if (hwcap & HWCAP_ARM_VFP)
+    return OPTIMIZE (vfp);
+  return OPTIMIZE (arm);
+#else
+  return OPTIMIZE (vfp);
+#endif
+}
diff --git a/sysdeps/arm/armv7/multiarch/memcpy.S b/sysdeps/arm/armv7/multiarch/memcpy.S
deleted file mode 100644
index 8a53bda..0000000
--- a/sysdeps/arm/armv7/multiarch/memcpy.S
+++ /dev/null
@@ -1,76 +0,0 @@ 
-/* Multiple versions of memcpy
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2013-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-/* Thumb requires excess IT instructions here.  */
-#define NO_THUMB
-#include <sysdep.h>
-#include <rtld-global-offsets.h>
-
-#if IS_IN (libc)
-/* Under __ARM_NEON__, memcpy_neon.S defines the name memcpy.  */
-# ifndef __ARM_NEON__
-	.text
-ENTRY(memcpy)
-	.type	memcpy, %gnu_indirect_function
-# ifdef __SOFTFP__
-	ldr	r1, .Lmemcpy_arm
-	tst	r0, #HWCAP_ARM_VFP
-	ldrne	r1, .Lmemcpy_vfp
-# else
-	ldr	r1, .Lmemcpy_vfp
-# endif
-	tst	r0, #HWCAP_ARM_NEON
-	ldrne	r1, .Lmemcpy_neon
-1:
-	add	r0, r1, pc
-	DO_RET(lr)
-
-# ifdef __SOFTFP__
-.Lmemcpy_arm:
-	.long	C_SYMBOL_NAME(__memcpy_arm) - 1b - PC_OFS
-# endif
-.Lmemcpy_neon:
-	.long	C_SYMBOL_NAME(__memcpy_neon) - 1b - PC_OFS
-.Lmemcpy_vfp:
-	.long	C_SYMBOL_NAME(__memcpy_vfp) - 1b - PC_OFS
-
-END(memcpy)
-
-libc_hidden_builtin_def (memcpy)
-#endif  /* Not __ARM_NEON__.  */
-
-/* These versions of memcpy are defined not to clobber any VFP or NEON
-   registers so they must always call the ARM variant of the memcpy code.  */
-strong_alias (__memcpy_arm, __aeabi_memcpy)
-strong_alias (__memcpy_arm, __aeabi_memcpy4)
-strong_alias (__memcpy_arm, __aeabi_memcpy8)
-libc_hidden_def (__memcpy_arm)
-
-#undef libc_hidden_builtin_def
-#define libc_hidden_builtin_def(name)
-#undef weak_alias
-#define weak_alias(x, y)
-#undef libc_hidden_def
-#define libc_hidden_def(name)
-
-#define memcpy __memcpy_arm
-
-#endif
-
-#include "memcpy_impl.S"
diff --git a/sysdeps/arm/armv7/multiarch/memcpy.c b/sysdeps/arm/armv7/multiarch/memcpy.c
new file mode 100644
index 0000000..7ef6714
--- /dev/null
+++ b/sysdeps/arm/armv7/multiarch/memcpy.c
@@ -0,0 +1,33 @@ 
+/* Multiple versions of memcpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#if IS_IN (libc)
+# define memcpy __redirect_memcpy
+# include <string.h>
+# undef memcpy
+
+# include <arm-ifunc.h>
+
+# define SYMBOL_NAME memcpy
+# include "ifunc-memcpy.h"
+
+arm_libc_ifunc_redirected (__redirect_memcpy, memcpy, IFUNC_SELECTOR);
+
+arm_libc_ifunc_hidden_def (__redirect_memcpy, memcpy);
+#endif
diff --git a/sysdeps/arm/armv7/multiarch/memcpy_arm.S b/sysdeps/arm/armv7/multiarch/memcpy_arm.S
new file mode 100644
index 0000000..37565cd
--- /dev/null
+++ b/sysdeps/arm/armv7/multiarch/memcpy_arm.S
@@ -0,0 +1,6 @@ 
+#define memcpy __memcpy_arm
+#include "memcpy_impl.S"
+
+strong_alias (__memcpy_arm, __aeabi_memcpy)
+strong_alias (__memcpy_arm, __aeabi_memcpy4)
+strong_alias (__memcpy_arm, __aeabi_memcpy8)
diff --git a/sysdeps/arm/armv7/multiarch/rtld-memcpy.S b/sysdeps/arm/armv7/multiarch/rtld-memcpy.S
new file mode 100644
index 0000000..0190edc
--- /dev/null
+++ b/sysdeps/arm/armv7/multiarch/rtld-memcpy.S
@@ -0,0 +1 @@ 
+#include <./sysdeps/arm/armv7/multiarch/memcpy_impl.S>
diff --git a/sysdeps/generic/symbol-hacks.h b/sysdeps/generic/symbol-hacks.h
index d614c09..589585a 100644
--- a/sysdeps/generic/symbol-hacks.h
+++ b/sysdeps/generic/symbol-hacks.h
@@ -1,6 +1,7 @@ 
 /* Some compiler optimizations may transform loops into memset/memmove
    calls and without proper declaration it may generate PLT calls.  */
-#if !defined __ASSEMBLER__ && IS_IN (libc) && defined SHARED
+#if !defined __ASSEMBLER__ && IS_IN (libc) && defined SHARED \
+    && !defined(NO_MEM_INTERAL_SYM_HACKS)
 asm ("memmove = __GI_memmove");
 asm ("memset = __GI_memset");
 asm ("memcpy = __GI_memcpy");