Skip to content

Commit 9d0eb2a

Browse files
committed
to alloc.rs
1 parent 34ef27e commit 9d0eb2a

File tree

3 files changed

+42
-52
lines changed

3 files changed

+42
-52
lines changed

src/shims/alloc.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,42 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
172172
}
173173
}
174174
}
175+
176+
fn aligned_alloc(
177+
&mut self,
178+
align: u64,
179+
size: u64,
180+
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
181+
let this = self.eval_context_mut();
182+
// Alignment must be a power of 2, and "supported by the implementation".
183+
// We decide that "supported by the implementation" means that the
184+
// size must be a multiple of the alignment. (This restriction seems common
185+
// enough that it is stated on <https://en.cppreference.com/w/c/memory/aligned_alloc>
186+
// as a general rule, but the actual standard has no such rule.)
187+
// If any of these are violated, we have to return NULL.
188+
// All fundamental alignments must be supported.
189+
//
190+
// macOS and Illumos are buggy in that they require the alignment
191+
// to be at least the size of a pointer, so they do not support all fundamental
192+
// alignments. We do not emulate those platform bugs.
193+
//
194+
// Linux also sets errno to EINVAL, but that's non-standard behavior that we do not
195+
// emulate.
196+
// FreeBSD says some of these cases are UB but that's violating the C standard.
197+
// http://en.cppreference.com/w/cpp/memory/c/aligned_alloc
198+
// Linux: https://linux.die.net/man/3/aligned_alloc
199+
// FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=aligned_alloc&apropos=0&sektion=3&manpath=FreeBSD+9-current&format=html
200+
match size.checked_rem(align) {
201+
Some(0) if align.is_power_of_two() => {
202+
let align = align.max(this.malloc_align(size).bytes());
203+
let ptr = this.allocate_ptr(
204+
Size::from_bytes(size),
205+
Align::from_bytes(align).unwrap(),
206+
MiriMemoryKind::C.into(),
207+
)?;
208+
Ok(ptr.into())
209+
}
210+
_ => Ok(Pointer::null()),
211+
}
212+
}
175213
}

src/shims/unix/foreign_items.rs

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::str;
33

44
use rustc_middle::ty::layout::LayoutOf;
55
use rustc_span::Symbol;
6-
use rustc_target::abi::{Align, Size};
76
use rustc_target::spec::abi::Abi;
87

98
use crate::shims::alloc::EvalContextExt as _;
@@ -304,38 +303,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
304303
let align = this.read_target_usize(align)?;
305304
let size = this.read_target_usize(size)?;
306305

307-
// Alignment must be a power of 2, and "supported by the implementation".
308-
// We decide that "supported by the implementation" means that the
309-
// size must be a multiple of the alignment. (This restriction seems common
310-
// enough that it is stated on <https://en.cppreference.com/w/c/memory/aligned_alloc>
311-
// as a general rule, but the actual standard has no such rule.)
312-
// If any of these are violated, we have to return NULL.
313-
// All fundamental alignments must be supported.
314-
//
315-
// macOS and Illumos are buggy in that they require the alignment
316-
// to be at least the size of a pointer, so they do not support all fundamental
317-
// alignments. We do not emulate those platform bugs.
318-
//
319-
// Linux also sets errno to EINVAL, but that's non-standard behavior that we do not
320-
// emulate.
321-
// FreeBSD says some of these cases are UB but that's violating the C standard.
322-
// http://en.cppreference.com/w/cpp/memory/c/aligned_alloc
323-
// Linux: https://linux.die.net/man/3/aligned_alloc
324-
// FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=aligned_alloc&apropos=0&sektion=3&manpath=FreeBSD+9-current&format=html
325-
match size.checked_rem(align) {
326-
Some(0) if align.is_power_of_two() => {
327-
let align = align.max(this.malloc_align(size).bytes());
328-
let ptr = this.allocate_ptr(
329-
Size::from_bytes(size),
330-
Align::from_bytes(align).unwrap(),
331-
MiriMemoryKind::C.into(),
332-
)?;
333-
this.write_pointer(ptr, dest)?;
334-
},
335-
_ => {
336-
this.write_null(dest)?;
337-
}
338-
}
306+
let res = this.aligned_alloc(align, size)?;
307+
this.write_pointer(res, dest)?;
339308
}
340309

341310
// Dynamic symbol loading

src/shims/wasi/foreign_items.rs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use rustc_span::Symbol;
2-
use rustc_target::abi::{Align, Size};
32
use rustc_target::spec::abi::Abi;
43

54
use crate::shims::alloc::EvalContextExt as _;
@@ -33,24 +32,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
3332
let align = this.read_target_usize(align)?;
3433
let size = this.read_target_usize(size)?;
3534

36-
// Alignment must be a power of 2.
37-
// wasi libc makes no check for the size though but
38-
// here we do check it is a multiple of alignment.
39-
40-
match size.checked_rem(align) {
41-
Some(0) if align.is_power_of_two() => {
42-
let align = align.max(this.malloc_align(size).bytes());
43-
let ptr = this.allocate_ptr(
44-
Size::from_bytes(size),
45-
Align::from_bytes(align).unwrap(),
46-
MiriMemoryKind::C.into(),
47-
)?;
48-
this.write_pointer(ptr, dest)?;
49-
}
50-
_ => {
51-
this.write_null(dest)?;
52-
}
53-
}
35+
let res = this.aligned_alloc(align, size)?;
36+
this.write_pointer(res, dest)?;
5437
}
5538

5639
_ => return Ok(EmulateItemResult::NotSupported),

0 commit comments

Comments
 (0)