From 7ad3926d996f6471da05a8f3cab0283bb38c1498 Mon Sep 17 00:00:00 2001 From: Wouter Dullaert Date: Fri, 21 Jun 2024 09:51:51 +0200 Subject: [PATCH] feat(aya-ebpf): Implement memmove The compiler will emit this function for certain operations, but aya currently does not provide an implementation. This leads to ebpf loading failures as the kernel can't find the symbol when loading the program. The implementation is based on https://github.com/rust-lang/compiler-builtins/blob/master/src/mem/mod.rs#L29-L40 and https://github.com/rust-lang/compiler-builtins/blob/master/src/mem/impls.rs#L128-L135 Only the simplest case has been implemented, none of the word optimizations, since memcpy also doesn't seem to have them. --- ebpf/aya-ebpf/src/lib.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ebpf/aya-ebpf/src/lib.rs b/ebpf/aya-ebpf/src/lib.rs index 04a4002e..e141bfe6 100644 --- a/ebpf/aya-ebpf/src/lib.rs +++ b/ebpf/aya-ebpf/src/lib.rs @@ -73,11 +73,35 @@ pub unsafe extern "C" fn memset(s: *mut u8, c: c_int, n: usize) { #[no_mangle] pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *mut u8, n: usize) { + copy_forward(dest, src, n); +} + +#[no_mangle] +pub unsafe extern "C" fn memmove(dest: *mut u8, src: *mut u8, n: usize) { + let delta = (dest as usize).wrapping_sub(src as usize); + if delta >= n { + // We can copy forwards because either dest is far enough ahead of src, + // or src is ahead of dest (and delta overflowed). + copy_forward(dest, src, n); + } else { + copy_backward(dest, src, n); + } +} + +#[inline(always)] +unsafe fn copy_forward(dest: *mut u8, src: *mut u8, n: usize) { for i in 0..n { *dest.add(i) = *src.add(i); } } +#[inline(always)] +unsafe fn copy_backward(dest: *mut u8, src: *mut u8, n: usize) { + for i in (0..n).rev() { + *dest.add(i) = *src.add(i); + } +} + /// Check if a value is within a range, using conditional forms compatible with /// the verifier. #[inline(always)]