Skip to content

Commit

Permalink
Auto merge of rust-lang#2827 - mojave2:memcpy, r=oli-obk
Browse files Browse the repository at this point in the history
add `memcpy` and `strcpy` shims
  • Loading branch information
bors committed Apr 12, 2023
2 parents dedac2d + 7e37783 commit fa8e02f
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/tools/miri/src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,44 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
dest,
)?;
}
"memcpy" => {
let [ptr_dest, ptr_src, n] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let ptr_dest = this.read_pointer(ptr_dest)?;
let ptr_src = this.read_pointer(ptr_src)?;
let n = this.read_target_usize(n)?;
this.mem_copy(
ptr_src,
Align::ONE,
ptr_dest,
Align::ONE,
Size::from_bytes(n),
true,
)?;
this.write_pointer(ptr_dest, dest)?;
}
"strcpy" => {
let [ptr_dest, ptr_src] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let ptr_dest = this.read_pointer(ptr_dest)?;
let ptr_src = this.read_pointer(ptr_src)?;

// We use `read_c_str` to determine the amount of data to copy,
// and then use `mem_copy` for the actual copy. This means
// pointer provenance is preserved by this implementation of `strcpy`.
// That is probably overly cautious, but there also is no fundamental
// reason to have `strcpy` destroy pointer provenance.
let n = this.read_c_str(ptr_src)?.len().checked_add(1).unwrap();
this.mem_copy(
ptr_src,
Align::ONE,
ptr_dest,
Align::ONE,
Size::from_bytes(n),
true,
)?;
this.write_pointer(ptr_dest, dest)?;
}

// math functions (note that there are also intrinsics for some other functions)
#[rustfmt::skip]
Expand Down
80 changes: 80 additions & 0 deletions src/tools/miri/tests/pass-dep/shims/libc-misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,83 @@ fn test_posix_mkstemp() {
}
}

fn test_memcpy() {
unsafe {
let src = [1i8, 2, 3];
let dest = libc::calloc(3, 1);
libc::memcpy(dest, src.as_ptr() as *const libc::c_void, 3);
let slc = std::slice::from_raw_parts(dest as *const i8, 3);
assert_eq!(*slc, [1i8, 2, 3]);
libc::free(dest);
}

unsafe {
let src = [1i8, 2, 3];
let dest = libc::calloc(4, 1);
libc::memcpy(dest, src.as_ptr() as *const libc::c_void, 3);
let slc = std::slice::from_raw_parts(dest as *const i8, 4);
assert_eq!(*slc, [1i8, 2, 3, 0]);
libc::free(dest);
}

unsafe {
let src = 123_i32;
let mut dest = 0_i32;
libc::memcpy(
&mut dest as *mut i32 as *mut libc::c_void,
&src as *const i32 as *const libc::c_void,
std::mem::size_of::<i32>(),
);
assert_eq!(dest, src);
}

unsafe {
let src = Some(123);
let mut dest: Option<i32> = None;
libc::memcpy(
&mut dest as *mut Option<i32> as *mut libc::c_void,
&src as *const Option<i32> as *const libc::c_void,
std::mem::size_of::<Option<i32>>(),
);
assert_eq!(dest, src);
}

unsafe {
let src = &123;
let mut dest = &42;
libc::memcpy(
&mut dest as *mut &'static i32 as *mut libc::c_void,
&src as *const &'static i32 as *const libc::c_void,
std::mem::size_of::<&'static i32>(),
);
assert_eq!(*dest, 123);
}
}

fn test_strcpy() {
use std::ffi::{CStr, CString};

// case: src_size equals dest_size
unsafe {
let src = CString::new("rust").unwrap();
let size = src.as_bytes_with_nul().len();
let dest = libc::malloc(size);
libc::strcpy(dest as *mut libc::c_char, src.as_ptr());
assert_eq!(CStr::from_ptr(dest as *const libc::c_char), src.as_ref());
libc::free(dest);
}

// case: src_size is less than dest_size
unsafe {
let src = CString::new("rust").unwrap();
let size = src.as_bytes_with_nul().len();
let dest = libc::malloc(size + 1);
libc::strcpy(dest as *mut libc::c_char, src.as_ptr());
assert_eq!(CStr::from_ptr(dest as *const libc::c_char), src.as_ref());
libc::free(dest);
}
}

#[cfg(target_os = "linux")]
fn test_sigrt() {
let min = libc::SIGRTMIN();
Expand Down Expand Up @@ -333,6 +410,9 @@ fn main() {
test_isatty();
test_clocks();

test_memcpy();
test_strcpy();

#[cfg(target_os = "linux")]
{
test_posix_fadvise();
Expand Down

0 comments on commit fa8e02f

Please sign in to comment.