Skip to content

Commit

Permalink
[WIP] support aligned_alloc for unixes support.
Browse files Browse the repository at this point in the history
  • Loading branch information
devnexen committed May 7, 2024
1 parent cf2df2d commit 0552e7a
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/shims/unix/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,33 @@ 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)?;

// The size must be a power of the alignment.
// The specs says nothing about error handling other than null
// pointer but aligned_alloc Linux/macOs implementations set EINVAL. Note that
// on FreeBSD setting a size not being a power of alignment is UB but we do not
// want it.
//
// http://en.cppreference.com/w/cpp/memory/c/aligned_alloc
// Linux: https://linux.die.net/man/3/aligned_alloc
// FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=aligned_alloc&apropos=0&sektion=3&manpath=FreeBSD+9-current&format=html
if (align > 0 && size % align != 0) || !align.is_power_of_two() || align < this.pointer_size().bytes() {
let _ = this.set_last_error(this.eval_libc("EINVAL"));
this.write_null(dest)?;
} else {
let ptr = this.allocate_ptr(
Size::from_bytes(size),
Align::from_bytes(align).unwrap(),
MiriMemoryKind::C.into(),
)?;
this.write_pointer(ptr, dest)?;
}
}

// Dynamic symbol loading
"dlsym" => {
Expand Down
28 changes: 28 additions & 0 deletions tests/pass-dep/libc/libc-mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,32 @@ fn test_reallocarray() {
}
}

#[cfg(not(target_os = "windows"))]
fn test_aligned_alloc() {
extern "C" {
fn aligned_alloc(_: libc::size_t, _: libc::size_t) -> *mut libc::c_void;
}
// wrong size
unsafe {
let p = aligned_alloc(16, 3);
assert_eq!(p, ptr::null_mut());
}

// alignment not power of 2
unsafe {
let p = aligned_alloc(63, 8);
assert_eq!(p, ptr::null_mut());
}

// finally ..
unsafe {
let p = aligned_alloc(16, 16);
assert!(!p.is_null());
assert!(p.is_aligned_to(16));
libc::free(p);
}
}

fn main() {
test_malloc();
test_calloc();
Expand All @@ -249,6 +275,8 @@ fn main() {
target_os = "solaris"
)))]
test_reallocarray();
#[cfg(not(target_os = "windows"))]
test_aligned_alloc();

test_memcpy();
test_strcpy();
Expand Down

0 comments on commit 0552e7a

Please sign in to comment.