Skip to content

Commit ab9f83a

Browse files
committed
addressing comments
1 parent d3c2390 commit ab9f83a

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

src/shims/alloc.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
6464
Align::from_bytes(prev_power_of_two(size)).unwrap()
6565
}
6666

67+
fn min_align(&self, align: u64, size: u64) -> Align {
68+
let mut align = Align::from_bytes(align).unwrap();
69+
let min_align = self.malloc_align(size);
70+
if align < min_align {
71+
align = min_align
72+
}
73+
align
74+
}
75+
6776
/// Emulates calling the internal __rust_* allocator functions
6877
fn emulate_allocator(
6978
&mut self,

src/shims/unix/foreign_items.rs

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

44
use rustc_middle::ty::layout::LayoutOf;
55
use rustc_span::Symbol;
6+
use rustc_target::abi::Size;
67
use rustc_target::spec::abi::Abi;
78

89
use crate::shims::alloc::EvalContextExt as _;
@@ -303,36 +304,32 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
303304
let align = this.read_target_usize(align)?;
304305
let size = this.read_target_usize(size)?;
305306

306-
// The size must be a power of the alignment.
307-
// The specs says nothing about error handling other than null
308-
// pointer but aligned_alloc Linux/macOs implementations set EINVAL. Note that
309-
// on FreeBSD setting a size not being a power of alignment is UB but we do not
310-
// want it.
307+
// The size must be a multiple of the alignment.
308+
// Alignment must be a power of 2, and "supported by the implementation".
309+
// If any of these are violated, we have to return NULL.
310+
// All fundamental alignments must be supported.
311+
// We decide that our implementation supports all alignments.
311312
//
313+
// macOS and Illumos are buggy in that they require the alignment
314+
// to be at least the size of a pointer. We do not emulate those platform bugs.
315+
//
316+
// Linux also sets errno to EINVAL, but that's non-standard behavior that we do not
317+
// emulate/
318+
// FreeBSD says some of these cases are UB but that's violating the C standard.
312319
// http://en.cppreference.com/w/cpp/memory/c/aligned_alloc
313320
// Linux: https://linux.die.net/man/3/aligned_alloc
314321
// FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=aligned_alloc&apropos=0&sektion=3&manpath=FreeBSD+9-current&format=html
315322
match size.checked_rem(align) {
316-
Some(0) => {
317-
if !align.is_power_of_two() {
318-
let _ = this.set_last_error(this.eval_libc("EINVAL"));
319-
this.write_null(dest)?;
320-
} else {
321-
let mut align = Align::from_bytes(align).unwrap();
322-
let min_align = this.malloc_align(size);
323-
if align < min_align {
324-
align = min_align;
325-
}
323+
Some(0) if align.is_power_of_two() => {
324+
let align = this.min_align(align, size);
326325
let ptr = this.allocate_ptr(
327326
Size::from_bytes(size),
328327
align,
329328
MiriMemoryKind::C.into(),
330329
)?;
331330
this.write_pointer(ptr, dest)?;
332-
}
333331
},
334332
_ => {
335-
let _ = this.set_last_error(this.eval_libc("EINVAL"));
336333
this.write_null(dest)?;
337334
}
338335
}

0 commit comments

Comments
 (0)