summaryrefslogtreecommitdiff
path: root/src/tools/miri/src/shims/foreign_items.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/miri/src/shims/foreign_items.rs')
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs40
1 files changed, 39 insertions, 1 deletions
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index fcee381ff71..44bca3796f9 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -46,7 +46,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// This list should be kept in sync with the one from libstd.
let min_align = match this.tcx.sess.target.arch.as_ref() {
"x86" | "arm" | "mips" | "powerpc" | "powerpc64" | "asmjs" | "wasm32" => 8,
- "x86_64" | "aarch64" | "mips64" | "s390x" | "sparc64" => 16,
+ "x86_64" | "aarch64" | "mips64" | "s390x" | "sparc64" | "loongarch64" => 16,
arch => bug!("unsupported target architecture for malloc: `{}`", arch),
};
// Windows always aligns, even small allocations.
@@ -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]