Skip to content

Commit 2d32385

Browse files
committed
implement and test posix_memalign
1 parent bd1dc28 commit 2d32385

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

src/fn_call.rs

+26
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,32 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
9393
this.write_scalar(Scalar::Ptr(ptr.with_default_tag()), dest)?;
9494
}
9595
}
96+
"posix_memalign" => {
97+
let ret = this.deref_operand(args[0])?;
98+
let align = this.read_scalar(args[1])?.to_usize(this)?;
99+
let size = this.read_scalar(args[2])?.to_usize(this)?;
100+
// align must be a power of 2, and also at least ptr-sized (wtf, POSIX)
101+
if !align.is_power_of_two() {
102+
return err!(HeapAllocNonPowerOfTwoAlignment(align));
103+
}
104+
if align < this.pointer_size().bytes() {
105+
return err!(MachineError(format!(
106+
"posix_memalign: alignment must be at least the size of a pointer, but is {}",
107+
align,
108+
)));
109+
}
110+
if size == 0 {
111+
this.write_null(ret.into())?;
112+
} else {
113+
let ptr = this.memory_mut().allocate(
114+
Size::from_bytes(size),
115+
Align::from_bytes(align).unwrap(),
116+
MiriMemoryKind::C.into()
117+
);
118+
this.write_scalar(Scalar::Ptr(ptr.with_default_tag()), ret.into())?;
119+
}
120+
this.write_null(dest)?;
121+
}
96122

97123
"free" => {
98124
let ptr = this.read_scalar(args[0])?.not_undef()?;

tests/run-pass/heap.rs

+26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
#![feature(box_syntax)]
2+
#![feature(allocator_api)]
3+
4+
use std::alloc::{Global, Alloc, Layout, System};
25

36
fn make_box() -> Box<(i16, i16)> {
47
Box::new((1, 2))
@@ -27,8 +30,31 @@ fn allocate_reallocate() {
2730
assert_eq!(s.capacity(), 9);
2831
}
2932

33+
fn check_overalign_requests<T: Alloc>(mut allocator: T) {
34+
let size = 8;
35+
let align = 16; // greater than size
36+
let iterations = 1; // Miri is deterministic, no need to try many times
37+
unsafe {
38+
let pointers: Vec<_> = (0..iterations).map(|_| {
39+
allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap()
40+
}).collect();
41+
for &ptr in &pointers {
42+
assert_eq!((ptr.as_ptr() as usize) % align, 0,
43+
"Got a pointer less aligned than requested")
44+
}
45+
46+
// Clean up
47+
for &ptr in &pointers {
48+
allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap())
49+
}
50+
}
51+
}
52+
3053
fn main() {
3154
assert_eq!(*make_box(), (1, 2));
3255
assert_eq!(*make_box_syntax(), (1, 2));
3356
allocate_reallocate();
57+
58+
check_overalign_requests(System);
59+
check_overalign_requests(Global);
3460
}

0 commit comments

Comments
 (0)