Commit ba7ee44b authored by Kir Kolyshkin's avatar Kir Kolyshkin Committed by Pavel Emelyanov

pie: provide own memcpy for x86

When compiling criu with clang, I discovered compilation fails like
this:

    GEN      criu/pie/restorer-blob.h
 restorer_blob: Error (compel/src/lib/handle-elf-host.c:328): Unexpected
 undefined symbol: `memcpy'. External symbol in PIE?

This happens because clang emits a call to memcpy for struct
initialization (specifically, struct vdso_symtable in vdso_proxify()).
Naturally, as pie is complied without libc there is no memcpy()
so "compel piegen" rightfully complains.

There are a number of possible solutions to that:
 1. Write our own vdso_init_symtable() function instead of using =
 2. Use some compiler flags that disables using memcpy
 3. Provide own version of memcpy

Now, (1) looks ugly, (2) I was not able to find such flags. Another
argument in favor of (3) is we already have implementation of
builtin_memcpy() optimized for x86.

The only problem is it is not named memcpy(). Using assembler file (.S)
we can have a function with two names (entry points).

For a similar issue in ppc, see commits 0570dd81 and 1ad78171. Ultimately,
we should get rid of builtin_mem* names and just use memcpy(), memcmp()
etc, which in case of non-libc linked objects are to be provided by us.

Cc: Laurent Dufour <ldufour@linux.vnet.ibm.com>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarKir Kolyshkin <kir@openvz.org>
Acked-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Acked-by: 's avatarLaurent Dufour <ldufour@linux.vnet.ibm.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
(cherry picked from commit 214e28089e832d30e381b3780862d3309df17fb8)
Signed-off-by: 's avatarKir Kolyshkin <kir@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent feddef44
......@@ -6,19 +6,16 @@
#include "compiler.h"
#include "asm-generic/string.h"
static always_inline void *builtin_memcpy(void *to, const void *from, unsigned int n)
#ifdef CR_NOGLIBC
extern void *memcpy_x86(void *to, const void *from, size_t n);
static inline void *builtin_memcpy(void *to, const void *from, size_t n)
{
int d0, d1, d2;
asm volatile("rep ; movsl \n"
"movl %4,%%ecx \n"
"andl $3,%%ecx \n"
"jz 1f \n"
"rep ; movsb \n"
"1:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n / 4), "g" (n), "1" ((long)to), "2" ((long)from)
: "memory");
if (n)
memcpy_x86(to, from, n);
return to;
}
#else
#define builtin_memcpy memcpy
#endif /* CR_NOGLIBC */
#endif /* __CR_ASM_STRING_H__ */
#include "asm/linkage.h"
/* The following code is taken from Linux kernel (arch/x86/lib/memcpy_64.S).
* There are 3 implementations in there, we use the one that relies on
* X86_FEATURE_REP_GOOD ("rep microcode works well").
*/
/*
* memcpy - Copy a memory block.
*
* Input:
* rdi destination
* rsi source
* rdx count
*
* Output:
* rax original destination
*/
ENTRY(memcpy_x86)
ENTRY(memcpy)
movq %rdi, %rax
movq %rdx, %rcx
shrq $3, %rcx
andl $7, %edx
rep movsq
movl %edx, %ecx
rep movsb
ret
END(memcpy)
END(memcpy_x86)
......@@ -22,6 +22,10 @@ ifeq ($(SRCARCH),ppc64)
lib-y += ./$(ARCH_DIR)/misc.o
endif
ifeq ($(SRCARCH),x86)
lib-y += ./$(ARCH_DIR)/memcpy.o
endif
#
# We can't provide proper mount implementation
# in parasite code -- it requires run-time rellocation
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment