Add memory operation syscalls (#16447)

This commit is contained in:
Jack May
2021-06-01 15:33:17 -07:00
committed by GitHub
parent 38d71c37da
commit 2b50529265
16 changed files with 605 additions and 145 deletions

View File

@@ -12,12 +12,13 @@ lazy_static::lazy_static! {
static ref SYSCALL_STUBS: Arc<RwLock<Box<dyn SyscallStubs>>> = Arc::new(RwLock::new(Box::new(DefaultSyscallStubs {})));
}
// The default syscall stubs don't do much, but `set_syscalls()` can be used to swap in
// alternatives
// The default syscall stubs may not do much, but `set_syscalls()` can be used
// to swap in alternatives
pub fn set_syscall_stubs(syscall_stubs: Box<dyn SyscallStubs>) -> Box<dyn SyscallStubs> {
std::mem::replace(&mut SYSCALL_STUBS.write().unwrap(), syscall_stubs)
}
#[allow(clippy::integer_arithmetic)]
pub trait SyscallStubs: Sync + Send {
fn sol_log(&self, message: &str) {
println!("{}", message);
@@ -34,7 +35,6 @@ pub trait SyscallStubs: Sync + Send {
sol_log("SyscallStubs: sol_invoke_signed() not available");
Ok(())
}
fn sol_get_clock_sysvar(&self, _var_addr: *mut u8) -> u64 {
UNSUPPORTED_SYSVAR
}
@@ -47,6 +47,39 @@ pub trait SyscallStubs: Sync + Send {
fn sol_get_rent_sysvar(&self, _var_addr: *mut u8) -> u64 {
UNSUPPORTED_SYSVAR
}
/// # Safety
unsafe fn sol_memcpy(&self, dst: *mut u8, src: *const u8, n: usize) {
// cannot be overlapping
if dst as usize + n > src as usize && src as usize > dst as usize {
panic!("memcpy does not support oveerlapping regions");
}
std::ptr::copy_nonoverlapping(src, dst, n as usize);
}
/// # Safety
unsafe fn sol_memmove(&self, dst: *mut u8, src: *const u8, n: usize) {
std::ptr::copy(src, dst, n as usize);
}
/// # Safety
unsafe fn sol_memcmp(&self, s1: *const u8, s2: *const u8, n: usize, result: *mut i32) {
let mut i = 0;
while i < n {
let a = *s1.add(i);
let b = *s2.add(i);
if a != b {
*result = a as i32 - b as i32;
return;
}
i += 1;
}
*result = 0
}
/// # Safety
unsafe fn sol_memset(&self, s: *mut u8, c: u8, n: usize) {
let s = std::slice::from_raw_parts_mut(s, n);
for val in s.iter_mut().take(n) {
*val = c;
}
}
}
struct DefaultSyscallStubs {}
@@ -96,3 +129,27 @@ pub(crate) fn sol_get_fees_sysvar(var_addr: *mut u8) -> u64 {
pub(crate) fn sol_get_rent_sysvar(var_addr: *mut u8) -> u64 {
SYSCALL_STUBS.read().unwrap().sol_get_rent_sysvar(var_addr)
}
pub(crate) fn sol_memcpy(dst: *mut u8, src: *const u8, n: usize) {
unsafe {
SYSCALL_STUBS.read().unwrap().sol_memcpy(dst, src, n);
}
}
pub(crate) fn sol_memmove(dst: *mut u8, src: *const u8, n: usize) {
unsafe {
SYSCALL_STUBS.read().unwrap().sol_memmove(dst, src, n);
}
}
pub(crate) fn sol_memcmp(s1: *const u8, s2: *const u8, n: usize, result: *mut i32) {
unsafe {
SYSCALL_STUBS.read().unwrap().sol_memcmp(s1, s2, n, result);
}
}
pub(crate) fn sol_memset(s: *mut u8, c: u8, n: usize) {
unsafe {
SYSCALL_STUBS.read().unwrap().sol_memset(s, c, n);
}
}