Skip to content

Commit 27afeb0

Browse files
feat: add support for libc::memset
Signed-off-by: vishruth-thimmaiah <[email protected]>
1 parent 91a9b1f commit 27afeb0

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

src/tools/miri/src/shims/foreign_items.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,22 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
827827
this.mem_copy(ptr_src, ptr_dest, Size::from_bytes(n), true)?;
828828
this.write_pointer(ptr_dest, dest)?;
829829
}
830+
"memset" => {
831+
let [ptr_dest, val, n] =
832+
this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
833+
let ptr_dest = this.read_pointer(ptr_dest)?;
834+
let val = this.read_scalar(val)?.to_i32()?;
835+
let n = this.read_target_usize(n)?;
836+
// The docs say val is "interpreted as unsigned char".
837+
#[expect(clippy::as_conversions)]
838+
let val = val as u8;
839+
840+
this.ptr_get_alloc_id(ptr_dest, 0)?;
841+
842+
let bytes = std::iter::repeat_n(val, n.try_into().unwrap());
843+
this.write_bytes_ptr(ptr_dest, bytes)?;
844+
this.write_pointer(ptr_dest, dest)?;
845+
}
830846

831847
// LLVM intrinsics
832848
"llvm.prefetch" => {

src/tools/miri/tests/pass-dep/libc/libc-mem.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,47 @@ fn test_strcpy() {
7878
}
7979
}
8080

81+
fn test_memset() {
82+
unsafe {
83+
let val = 1;
84+
let dest = libc::calloc(3, 1);
85+
libc::memset(dest, val, 3);
86+
let slc = std::slice::from_raw_parts(dest as *const i8, 3);
87+
assert_eq!(*slc, [1i8, 1, 1]);
88+
libc::free(dest);
89+
}
90+
91+
unsafe {
92+
let val = 1;
93+
let dest = libc::calloc(4, 1);
94+
libc::memset(dest, val, 3);
95+
let slc = std::slice::from_raw_parts(dest as *const i8, 4);
96+
assert_eq!(*slc, [1i8, 1, 1, 0]);
97+
libc::free(dest);
98+
}
99+
100+
unsafe {
101+
let val = 1;
102+
let mut dest = 0_i8;
103+
libc::memset(&mut dest as *mut i8 as *mut libc::c_void, val, mem::size_of::<i8>());
104+
assert_eq!(dest, val as i8);
105+
}
106+
107+
unsafe {
108+
let val = 1;
109+
let mut dest = 0_i16;
110+
libc::memset(&mut dest as *mut i16 as *mut libc::c_void, val, mem::size_of::<i16>());
111+
assert_eq!(dest, 257);
112+
}
113+
114+
unsafe {
115+
let val = 257;
116+
let mut dest = 0_i16;
117+
libc::memset(&mut dest as *mut i16 as *mut libc::c_void, val, mem::size_of::<i16>());
118+
assert_eq!(dest, 257);
119+
}
120+
}
121+
81122
fn test_malloc() {
82123
// Test that small allocations sometimes *are* not very aligned.
83124
let saw_unaligned = (0..64).any(|_| unsafe {
@@ -310,4 +351,5 @@ fn main() {
310351

311352
test_memcpy();
312353
test_strcpy();
354+
test_memset();
313355
}

0 commit comments

Comments
 (0)