solana_program/
program_memory.rs

1//! Basic low-level memory operations.
2//!
3//! Within the BPF environment, these are implemented as syscalls and executed by
4//! the runtime in native code.
5
6/// Like C `memcpy`.
7///
8/// # Arguments
9///
10/// - `dst` - Destination
11/// - `src` - Source
12/// - `n` - Number of bytes to copy
13///
14/// # Errors
15///
16/// When executed within a BPF program, the memory regions spanning `n` bytes
17/// from from the start of `dst` and `src` must be mapped program memory. If not,
18/// the program will abort.
19///
20/// The memory regions spanning `n` bytes from `dst` and `src` from the start
21/// of `dst` and `src` must not overlap. If they do, then the program will abort
22/// or, if run outside of the BPF VM, will panic.
23///
24/// # Safety
25///
26/// __This function is incorrectly missing an `unsafe` declaration.__
27///
28/// This function does not verify that `n` is less than or equal to the
29/// lengths of the `dst` and `src` slices passed to it — it will copy
30/// bytes to and from beyond the slices.
31///
32/// Specifying an `n` greater than either the length of `dst` or `src` will
33/// likely introduce undefined behavior.
34#[inline]
35pub fn sol_memcpy(dst: &mut [u8], src: &[u8], n: usize) {
36    #[cfg(target_os = "solana")]
37    unsafe {
38        crate::syscalls::sol_memcpy_(dst.as_mut_ptr(), src.as_ptr(), n as u64);
39    }
40
41    #[cfg(not(target_os = "solana"))]
42    crate::program_stubs::sol_memcpy(dst.as_mut_ptr(), src.as_ptr(), n);
43}
44
45/// Like C `memmove`.
46///
47/// # Arguments
48///
49/// - `dst` - Destination
50/// - `src` - Source
51/// - `n` - Number of bytes to copy
52///
53/// # Errors
54///
55/// When executed within a BPF program, the memory regions spanning `n` bytes
56/// from from `dst` and `src` must be mapped program memory. If not, the program
57/// will abort.
58///
59/// # Safety
60///
61/// The same safety rules apply as in [`ptr::copy`].
62///
63/// [`ptr::copy`]: https://doc.rust-lang.org/std/ptr/fn.copy.html
64#[inline]
65pub unsafe fn sol_memmove(dst: *mut u8, src: *mut u8, n: usize) {
66    #[cfg(target_os = "solana")]
67    crate::syscalls::sol_memmove_(dst, src, n as u64);
68
69    #[cfg(not(target_os = "solana"))]
70    crate::program_stubs::sol_memmove(dst, src, n);
71}
72
73/// Like C `memcmp`.
74///
75/// # Arguments
76///
77/// - `s1` - Slice to be compared
78/// - `s2` - Slice to be compared
79/// - `n` - Number of bytes to compare
80///
81/// # Errors
82///
83/// When executed within a BPF program, the memory regions spanning `n` bytes
84/// from from the start of `dst` and `src` must be mapped program memory. If not,
85/// the program will abort.
86///
87/// # Safety
88///
89/// __This function is incorrectly missing an `unsafe` declaration.__
90///
91/// It does not verify that `n` is less than or equal to the lengths of the
92/// `dst` and `src` slices passed to it — it will read bytes beyond the
93/// slices.
94///
95/// Specifying an `n` greater than either the length of `dst` or `src` will
96/// likely introduce undefined behavior.
97#[inline]
98pub fn sol_memcmp(s1: &[u8], s2: &[u8], n: usize) -> i32 {
99    let mut result = 0;
100
101    #[cfg(target_os = "solana")]
102    unsafe {
103        crate::syscalls::sol_memcmp_(s1.as_ptr(), s2.as_ptr(), n as u64, &mut result as *mut i32);
104    }
105
106    #[cfg(not(target_os = "solana"))]
107    crate::program_stubs::sol_memcmp(s1.as_ptr(), s2.as_ptr(), n, &mut result as *mut i32);
108
109    result
110}
111
112/// Like C `memset`.
113///
114/// # Arguments
115///
116/// - `s` - Slice to be set
117/// - `c` - Repeated byte to set
118/// - `n` - Number of bytes to set
119///
120/// # Errors
121///
122/// When executed within a BPF program, the memory region spanning `n` bytes
123/// from from the start of `s` must be mapped program memory. If not, the program
124/// will abort.
125///
126/// # Safety
127///
128/// __This function is incorrectly missing an `unsafe` declaration.__
129///
130/// This function does not verify that `n` is less than or equal to the length
131/// of the `s` slice passed to it — it will write bytes beyond the
132/// slice.
133///
134/// Specifying an `n` greater than the length of `s` will likely introduce
135/// undefined behavior.
136#[inline]
137pub fn sol_memset(s: &mut [u8], c: u8, n: usize) {
138    #[cfg(target_os = "solana")]
139    unsafe {
140        crate::syscalls::sol_memset_(s.as_mut_ptr(), c, n as u64);
141    }
142
143    #[cfg(not(target_os = "solana"))]
144    crate::program_stubs::sol_memset(s.as_mut_ptr(), c, n);
145}