Skip to content

Commit 39275ab

Browse files
authored
Merge pull request #632 from RalfJung/memalign
implement and test posix_memalign
2 parents bd1dc28 + 8466f78 commit 39275ab

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-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_system.rs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//ignore-windows: Inspects allocation base address on Windows
2+
#![feature(allocator_api)]
3+
4+
use std::alloc::{Global, Alloc, Layout, System};
5+
6+
fn check_overalign_requests<T: Alloc>(mut allocator: T) {
7+
let size = 8;
8+
let align = 16; // greater than size
9+
let iterations = 1; // Miri is deterministic, no need to try many times
10+
unsafe {
11+
let pointers: Vec<_> = (0..iterations).map(|_| {
12+
allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap()
13+
}).collect();
14+
for &ptr in &pointers {
15+
assert_eq!((ptr.as_ptr() as usize) % align, 0,
16+
"Got a pointer less aligned than requested")
17+
}
18+
19+
// Clean up
20+
for &ptr in &pointers {
21+
allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap())
22+
}
23+
}
24+
}
25+
26+
fn main() {
27+
check_overalign_requests(System);
28+
check_overalign_requests(Global);
29+
}

0 commit comments

Comments
 (0)