From 78ed7ac2188ac41f9c9c0dd5bbd0a04095ae319f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 19 May 2024 11:48:51 +0200 Subject: [PATCH] a bit of refactoring and tweak the aligned-allocation tests --- src/shims/alloc.rs | 7 +- src/shims/unix/foreign_items.rs | 3 - src/shims/wasi/foreign_items.rs | 3 - tests/pass-dep/libc/libc-mem.rs | 110 ++++++++++++++++---------------- 4 files changed, 61 insertions(+), 62 deletions(-) diff --git a/src/shims/alloc.rs b/src/shims/alloc.rs index 6c18989caa..bd84de81e6 100644 --- a/src/shims/alloc.rs +++ b/src/shims/alloc.rs @@ -175,10 +175,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn aligned_alloc( &mut self, - align: u64, - size: u64, + align: &OpTy<'tcx, Provenance>, + size: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, Pointer>> { let this = self.eval_context_mut(); + let align = this.read_target_usize(align)?; + let size = this.read_target_usize(size)?; + // Alignment must be a power of 2, and "supported by the implementation". // We decide that "supported by the implementation" means that the // size must be a multiple of the alignment. (This restriction seems common diff --git a/src/shims/unix/foreign_items.rs b/src/shims/unix/foreign_items.rs index ca59e6e650..74fb2fb4b2 100644 --- a/src/shims/unix/foreign_items.rs +++ b/src/shims/unix/foreign_items.rs @@ -300,9 +300,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // (MSVC explicitly does not support this.) let [align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let align = this.read_target_usize(align)?; - let size = this.read_target_usize(size)?; - let res = this.aligned_alloc(align, size)?; this.write_pointer(res, dest)?; } diff --git a/src/shims/wasi/foreign_items.rs b/src/shims/wasi/foreign_items.rs index 9c0a8e6639..d911f43eb6 100644 --- a/src/shims/wasi/foreign_items.rs +++ b/src/shims/wasi/foreign_items.rs @@ -29,9 +29,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "aligned_alloc" => { let [align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let align = this.read_target_usize(align)?; - let size = this.read_target_usize(size)?; - let res = this.aligned_alloc(align, size)?; this.write_pointer(res, dest)?; } diff --git a/tests/pass-dep/libc/libc-mem.rs b/tests/pass-dep/libc/libc-mem.rs index 25aef0a183..aa383a99bc 100644 --- a/tests/pass-dep/libc/libc-mem.rs +++ b/tests/pass-dep/libc/libc-mem.rs @@ -148,53 +148,55 @@ fn test_calloc() { #[cfg(not(target_os = "windows"))] fn test_memalign() { - // A normal allocation. - unsafe { - let mut ptr: *mut libc::c_void = ptr::null_mut(); - let align = 8; - let size = 64; - assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); - assert!(!ptr.is_null()); - assert!(ptr.is_aligned_to(align)); - ptr.cast::().write_bytes(1, size); - libc::free(ptr); - } + for _ in 0..16 { + // A normal allocation. + unsafe { + let mut ptr: *mut libc::c_void = ptr::null_mut(); + let align = 8; + let size = 64; + assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); + assert!(!ptr.is_null()); + assert!(ptr.is_aligned_to(align)); + ptr.cast::().write_bytes(1, size); + libc::free(ptr); + } - // Align > size. - unsafe { - let mut ptr: *mut libc::c_void = ptr::null_mut(); - let align = 64; - let size = 8; - assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); - assert!(!ptr.is_null()); - assert!(ptr.is_aligned_to(align)); - ptr.cast::().write_bytes(1, size); - libc::free(ptr); - } + // Align > size. + unsafe { + let mut ptr: *mut libc::c_void = ptr::null_mut(); + let align = 64; + let size = 8; + assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); + assert!(!ptr.is_null()); + assert!(ptr.is_aligned_to(align)); + ptr.cast::().write_bytes(1, size); + libc::free(ptr); + } - // Size not multiple of align - unsafe { - let mut ptr: *mut libc::c_void = ptr::null_mut(); - let align = 16; - let size = 31; - assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); - assert!(!ptr.is_null()); - assert!(ptr.is_aligned_to(align)); - ptr.cast::().write_bytes(1, size); - libc::free(ptr); - } + // Size not multiple of align + unsafe { + let mut ptr: *mut libc::c_void = ptr::null_mut(); + let align = 16; + let size = 31; + assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); + assert!(!ptr.is_null()); + assert!(ptr.is_aligned_to(align)); + ptr.cast::().write_bytes(1, size); + libc::free(ptr); + } - // Size == 0 - unsafe { - let mut ptr: *mut libc::c_void = ptr::null_mut(); - let align = 64; - let size = 0; - assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); - // Non-null pointer is returned if size == 0. - // (This is not a guarantee, it just reflects our current behavior.) - assert!(!ptr.is_null()); - assert!(ptr.is_aligned_to(align)); - libc::free(ptr); + // Size == 0 + unsafe { + let mut ptr: *mut libc::c_void = ptr::null_mut(); + let align = 64; + let size = 0; + assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); + // Non-null pointer is returned if size == 0. + // (This is not a guarantee, it just reflects our current behavior.) + assert!(!ptr.is_null()); + assert!(ptr.is_aligned_to(align)); + libc::free(ptr); + } } // Non-power of 2 align @@ -260,20 +262,20 @@ fn test_aligned_alloc() { assert_eq!(p, ptr::null_mut()); } - // alignment lesser than a word but still a successful allocation - unsafe { - let p = aligned_alloc(1, 4); - assert!(!p.is_null()); - assert!(p.is_aligned_to(4)); - libc::free(p); - } - // repeated tests on correct alignment/size for _ in 0..16 { + // alignment 1, size 4 should succeed and actually must align to 4 (because C says so...) + unsafe { + let p = aligned_alloc(1, 4); + assert!(!p.is_null()); + assert!(p.is_aligned_to(4)); + libc::free(p); + } + unsafe { - let p = aligned_alloc(16, 16); + let p = aligned_alloc(64, 64); assert!(!p.is_null()); - assert!(p.is_aligned_to(16)); + assert!(p.is_aligned_to(64)); libc::free(p); } }