* [PATCH] KVM: selftests: Override memmove() to prevent "magic" references to memcpy()
@ 2026-11-10 20:33 Sean Christopherson
0 siblings, 0 replies; only message in thread
From: Sean Christopherson @ 2026-11-10 20:33 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Sean Christopherson, kvm, linux-kernel
Override memmove() along with the other string operations to prevent the
compiler from generating a reference to the built-in memcpy() when using
musl as the libc with a static build, which utlimately results in an error
during linking due to a duplicate memcpy symbol:
ld.lld: error: duplicate symbol: memcpy
>>> defined at string_override.c:23 (lib/string_override.c:23)
>>> $BUILD/build/selftests/c/lib/string_override.o:(memcpy)
>>> defined at memcpy.lo:(.text+0x0) in archive $BUILD/build/musl/lib/libc.a
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile.kvm:382: $BUILD/build/selftests/c/demand_paging_test] Error 1
The failure crops up when linking in the TDX library code[*] due to
tdx_init_vm() generating a call to memmove(), which is "fine" until the
perfect combination of static linking with musl triggers the above.
All kudos goes to AI for figuring out the insanity:
1. string_override.c defines its own memcpy, memset, memcmp, and strnlen (so
guest VM code doesn't jump through the dynamic linker's PLT in normal
dynamic builds), but it does not define memmove.
2. In musl on x86_64, src/string/x86_64/memcpy.s (memcpy.lo) defines two
global symbols at the function entry point:
.global memcpy
.global __memcpy_fwd
.hidden __memcpy_fwd
memcpy:
__memcpy_fwd:
3. And musl's src/string/x86_64/memmove.s (memmove.lo) implements
non-overlapping forward moves by jumping directly to __memcpy_fwd:
memmove:
mov %rdi,%rax
sub %rsi,%rax
cmp %rdx,%rax
jae __memcpy_fwd
4. As long as nothing calls memmove, ld.lld already has memcpy from
string_override.o and never extracts memcpy.lo from libc.a.
5. However, the one library file that calls memmove (either directly or
transitively via a libc.a function like getline/stdio that only that
file uses) causes ld.lld to extract memmove.lo from libc.a, which has
an unresolved reference to __memcpy_fwd. To satisfy __memcpy_fwd,
ld.lld is forced to extract memcpy.lo from libc.a, which also defines
memcpy and collides with string_override.o!
Link: https://lore.kernel.org/all/20261105-tdx-selftests-v16-3-2024e8fa517a@google.com [*]
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/Makefile.kvm | 2 +-
tools/testing/selftests/kvm/lib/string_override.c | 14 ++++++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 17a4256e9081..031f78643af8 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -295,7 +295,7 @@ CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
-Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \
-U_FORTIFY_SOURCE \
-fno-builtin-memcmp -fno-builtin-memcpy \
- -fno-builtin-memset -fno-builtin-strnlen \
+ -fno-builtin-memset -fno-builtin-strnlen -fno-builtin-memmove \
-fno-stack-protector -fno-PIE -fno-strict-aliasing \
-I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \
-I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH) \
diff --git a/tools/testing/selftests/kvm/lib/string_override.c b/tools/testing/selftests/kvm/lib/string_override.c
index 5d1c87277c49..3bc434f46177 100644
--- a/tools/testing/selftests/kvm/lib/string_override.c
+++ b/tools/testing/selftests/kvm/lib/string_override.c
@@ -29,6 +29,20 @@ void *memcpy(void *dest, const void *src, size_t count)
return dest;
}
+void *memmove(void *dest, const void *src, size_t count)
+{
+ const unsigned char *s = src;
+ unsigned char *d = dest;
+
+ if (d <= s || d - s >= count)
+ return memcpy(dest, src, count);
+
+ while (count-- > 0)
+ d[count] = s[count];
+
+ return dest;
+}
+
void *memset(void *s, int c, size_t count)
{
char *xs = s;
base-commit: cf7fa575900051e489f95944c65f432ea706ed73
--
2.56.0.542.g3ef89b7020-goog
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-11-10 20:33 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-10 20:33 [PATCH] KVM: selftests: Override memmove() to prevent "magic" references to memcpy() Sean Christopherson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®