2022-04-20 18:20:17 -07:00
|
|
|
//! Basic low-level memory operations.
|
|
|
|
//!
|
|
|
|
//! Within the BPF environment, these are implemented as syscalls and executed by
|
|
|
|
//! the runtime in native code.
|
2021-06-01 15:33:17 -07:00
|
|
|
|
2022-04-20 18:20:17 -07:00
|
|
|
/// Like C `memcpy`.
|
2021-06-01 15:33:17 -07:00
|
|
|
///
|
2022-04-20 18:20:17 -07:00
|
|
|
/// # Arguments
|
|
|
|
///
|
|
|
|
/// - `dst` - Destination
|
|
|
|
/// - `src` - Source
|
|
|
|
/// - `n` - Number of bytes to copy
|
|
|
|
///
|
|
|
|
/// # Errors
|
|
|
|
///
|
|
|
|
/// When executed within a BPF program, the memory regions spanning `n` bytes
|
|
|
|
/// from from the start of `dst` and `src` must be mapped program memory. If not,
|
|
|
|
/// the program will abort.
|
|
|
|
///
|
|
|
|
/// The memory regions spanning `n` bytes from `dst` and `src` from the start
|
|
|
|
/// of `dst` and `src` must not overlap. If they do, then the program will abort
|
|
|
|
/// or, if run outside of the BPF VM, will panic.
|
|
|
|
///
|
|
|
|
/// # Safety
|
|
|
|
///
|
|
|
|
/// __This function is incorrectly missing an `unsafe` declaration.__
|
|
|
|
///
|
|
|
|
/// This function does not verify that `n` is less than or equal to the
|
|
|
|
/// lengths of the `dst` and `src` slices passed to it — it will copy
|
|
|
|
/// bytes to and from beyond the slices.
|
|
|
|
///
|
|
|
|
/// Specifying an `n` greater than either the length of `dst` or `src` will
|
|
|
|
/// likely introduce undefined behavior.
|
2021-06-01 15:33:17 -07:00
|
|
|
#[inline]
|
|
|
|
pub fn sol_memcpy(dst: &mut [u8], src: &[u8], n: usize) {
|
|
|
|
#[cfg(target_arch = "bpf")]
|
|
|
|
{
|
|
|
|
extern "C" {
|
|
|
|
fn sol_memcpy_(dst: *mut u8, src: *const u8, n: u64);
|
|
|
|
}
|
|
|
|
unsafe {
|
|
|
|
sol_memcpy_(dst.as_mut_ptr(), src.as_ptr(), n as u64);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(target_arch = "bpf"))]
|
|
|
|
crate::program_stubs::sol_memcpy(dst.as_mut_ptr(), src.as_ptr(), n);
|
|
|
|
}
|
|
|
|
|
2022-04-20 18:20:17 -07:00
|
|
|
/// Like C `memmove`.
|
|
|
|
///
|
|
|
|
/// # Arguments
|
|
|
|
///
|
|
|
|
/// - `dst` - Destination
|
|
|
|
/// - `src` - Source
|
|
|
|
/// - `n` - Number of bytes to copy
|
|
|
|
///
|
|
|
|
/// # Errors
|
2021-06-01 15:33:17 -07:00
|
|
|
///
|
2022-04-20 18:20:17 -07:00
|
|
|
/// When executed within a BPF program, the memory regions spanning `n` bytes
|
|
|
|
/// from from `dst` and `src` must be mapped program memory. If not, the program
|
|
|
|
/// will abort.
|
2021-06-01 15:33:17 -07:00
|
|
|
///
|
|
|
|
/// # Safety
|
2022-04-20 18:20:17 -07:00
|
|
|
///
|
|
|
|
/// The same safety rules apply as in [`ptr::copy`].
|
|
|
|
///
|
|
|
|
/// [`ptr::copy`]: https://doc.rust-lang.org/std/ptr/fn.copy.html
|
2021-06-01 15:33:17 -07:00
|
|
|
#[inline]
|
|
|
|
pub unsafe fn sol_memmove(dst: *mut u8, src: *mut u8, n: usize) {
|
|
|
|
#[cfg(target_arch = "bpf")]
|
|
|
|
{
|
|
|
|
extern "C" {
|
|
|
|
fn sol_memmove_(dst: *mut u8, src: *const u8, n: u64);
|
|
|
|
}
|
|
|
|
sol_memmove_(dst, src, n as u64);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(target_arch = "bpf"))]
|
|
|
|
crate::program_stubs::sol_memmove(dst, src, n);
|
|
|
|
}
|
|
|
|
|
2022-04-20 18:20:17 -07:00
|
|
|
/// Like C `memcmp`.
|
|
|
|
///
|
|
|
|
/// # Arguments
|
2021-06-01 15:33:17 -07:00
|
|
|
///
|
2022-04-20 18:20:17 -07:00
|
|
|
/// - `s1` - Slice to be compared
|
|
|
|
/// - `s2` - Slice to be compared
|
|
|
|
/// - `n` - Number of bytes to compare
|
|
|
|
///
|
|
|
|
/// # Errors
|
|
|
|
///
|
|
|
|
/// When executed within a BPF program, the memory regions spanning `n` bytes
|
|
|
|
/// from from the start of `dst` and `src` must be mapped program memory. If not,
|
|
|
|
/// the program will abort.
|
|
|
|
///
|
|
|
|
/// # Safety
|
|
|
|
///
|
|
|
|
/// __This function is incorrectly missing an `unsafe` declaration.__
|
|
|
|
///
|
|
|
|
/// It does not verify that `n` is less than or equal to the lengths of the
|
|
|
|
/// `dst` and `src` slices passed to it — it will read bytes beyond the
|
|
|
|
/// slices.
|
|
|
|
///
|
|
|
|
/// Specifying an `n` greater than either the length of `dst` or `src` will
|
|
|
|
/// likely introduce undefined behavior.
|
2021-06-01 15:33:17 -07:00
|
|
|
#[inline]
|
|
|
|
pub fn sol_memcmp(s1: &[u8], s2: &[u8], n: usize) -> i32 {
|
|
|
|
let mut result = 0;
|
|
|
|
|
|
|
|
#[cfg(target_arch = "bpf")]
|
|
|
|
{
|
|
|
|
extern "C" {
|
|
|
|
fn sol_memcmp_(s1: *const u8, s2: *const u8, n: u64, result: *mut i32);
|
|
|
|
}
|
|
|
|
unsafe {
|
|
|
|
sol_memcmp_(s1.as_ptr(), s2.as_ptr(), n as u64, &mut result as *mut i32);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(target_arch = "bpf"))]
|
|
|
|
crate::program_stubs::sol_memcmp(s1.as_ptr(), s2.as_ptr(), n, &mut result as *mut i32);
|
|
|
|
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
2022-04-20 18:20:17 -07:00
|
|
|
/// Like C `memset`.
|
|
|
|
///
|
|
|
|
/// # Arguments
|
|
|
|
///
|
|
|
|
/// - `s` - Slice to be set
|
|
|
|
/// - `c` - Repeated byte to set
|
|
|
|
/// - `n` - Number of bytes to set
|
|
|
|
///
|
|
|
|
/// # Errors
|
|
|
|
///
|
|
|
|
/// When executed within a BPF program, the memory region spanning `n` bytes
|
|
|
|
/// from from the start of `s` must be mapped program memory. If not, the program
|
|
|
|
/// will abort.
|
|
|
|
///
|
|
|
|
/// # Safety
|
|
|
|
///
|
|
|
|
/// __This function is incorrectly missing an `unsafe` declaration.__
|
|
|
|
///
|
|
|
|
/// This function does not verify that `n` is less than or equal to the length
|
|
|
|
/// of the `s` slice passed to it — it will write bytes beyond the
|
|
|
|
/// slice.
|
2021-06-01 15:33:17 -07:00
|
|
|
///
|
2022-04-20 18:20:17 -07:00
|
|
|
/// Specifying an `n` greater than the length of `s` will likely introduce
|
|
|
|
/// undefined behavior.
|
2021-06-01 15:33:17 -07:00
|
|
|
#[inline]
|
|
|
|
pub fn sol_memset(s: &mut [u8], c: u8, n: usize) {
|
|
|
|
#[cfg(target_arch = "bpf")]
|
|
|
|
{
|
|
|
|
extern "C" {
|
|
|
|
fn sol_memset_(s: *mut u8, c: u8, n: u64);
|
|
|
|
}
|
|
|
|
unsafe {
|
|
|
|
sol_memset_(s.as_mut_ptr(), c, n as u64);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(target_arch = "bpf"))]
|
|
|
|
crate::program_stubs::sol_memset(s.as_mut_ptr(), c, n);
|
|
|
|
}
|