Skip to content

Commit e2b42a5

Browse files
committed
Auto merge of #3285 - sunfishcode:sunfishcode/mmap64, r=RalfJung
Implement the `mmap64` foreign item. `mmap64` is like `mmap` but uses a 64-bit integer instead of `off_t` for the offset parameter.
2 parents a40a100 + 064ad45 commit e2b42a5

File tree

4 files changed

+36
-16
lines changed

4 files changed

+36
-16
lines changed

src/tools/miri/src/shims/unix/foreign_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
260260

261261
"mmap" => {
262262
let [addr, length, prot, flags, fd, offset] = this.check_shim(abi, Abi::C {unwind: false}, link_name, args)?;
263+
let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?;
263264
let ptr = this.mmap(addr, length, prot, flags, fd, offset)?;
264265
this.write_scalar(ptr, dest)?;
265266
}

src/tools/miri/src/shims/unix/linux/foreign_items.rs

+9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use shims::unix::fs::EvalContextExt as _;
99
use shims::unix::linux::fd::EvalContextExt as _;
1010
use shims::unix::linux::mem::EvalContextExt as _;
1111
use shims::unix::linux::sync::futex;
12+
use shims::unix::mem::EvalContextExt as _;
1213
use shims::unix::sync::EvalContextExt as _;
1314
use shims::unix::thread::EvalContextExt as _;
1415

@@ -43,6 +44,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
4344
let result = this.linux_readdir64(dirp)?;
4445
this.write_scalar(result, dest)?;
4546
}
47+
"mmap64" => {
48+
let [addr, length, prot, flags, fd, offset] =
49+
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
50+
let offset = this.read_scalar(offset)?.to_i64()?;
51+
let ptr = this.mmap(addr, length, prot, flags, fd, offset.into())?;
52+
this.write_scalar(ptr, dest)?;
53+
}
54+
4655
// Linux-only
4756
"sync_file_range" => {
4857
let [fd, offset, nbytes, flags] =

src/tools/miri/src/shims/unix/mem.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
2626
prot: &OpTy<'tcx, Provenance>,
2727
flags: &OpTy<'tcx, Provenance>,
2828
fd: &OpTy<'tcx, Provenance>,
29-
offset: &OpTy<'tcx, Provenance>,
29+
offset: i128,
3030
) -> InterpResult<'tcx, Scalar<Provenance>> {
3131
let this = self.eval_context_mut();
3232

@@ -36,7 +36,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
3636
let prot = this.read_scalar(prot)?.to_i32()?;
3737
let flags = this.read_scalar(flags)?.to_i32()?;
3838
let fd = this.read_scalar(fd)?.to_i32()?;
39-
let offset = this.read_target_usize(offset)?;
4039

4140
let map_private = this.eval_libc_i32("MAP_PRIVATE");
4241
let map_anonymous = this.eval_libc_i32("MAP_ANONYMOUS");

src/tools/miri/tests/pass-dep/shims/mmap.rs

+25-14
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,25 @@
55
use std::io::Error;
66
use std::{ptr, slice};
77

8-
fn test_mmap() {
8+
fn test_mmap<Offset: Default>(
9+
mmap: unsafe extern "C" fn(
10+
*mut libc::c_void,
11+
libc::size_t,
12+
libc::c_int,
13+
libc::c_int,
14+
libc::c_int,
15+
Offset,
16+
) -> *mut libc::c_void,
17+
) {
918
let page_size = page_size::get();
1019
let ptr = unsafe {
11-
libc::mmap(
20+
mmap(
1221
ptr::null_mut(),
1322
page_size,
1423
libc::PROT_READ | libc::PROT_WRITE,
1524
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
1625
-1,
17-
0,
26+
Default::default(),
1827
)
1928
};
2029
assert!(!ptr.is_null());
@@ -35,40 +44,40 @@ fn test_mmap() {
3544

3645
// Test all of our error conditions
3746
let ptr = unsafe {
38-
libc::mmap(
47+
mmap(
3948
ptr::null_mut(),
4049
page_size,
4150
libc::PROT_READ | libc::PROT_WRITE,
4251
libc::MAP_PRIVATE | libc::MAP_SHARED, // Can't be both private and shared
4352
-1,
44-
0,
53+
Default::default(),
4554
)
4655
};
4756
assert_eq!(ptr, libc::MAP_FAILED);
4857
assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
4958

5059
let ptr = unsafe {
51-
libc::mmap(
60+
mmap(
5261
ptr::null_mut(),
5362
0, // Can't map no memory
5463
libc::PROT_READ | libc::PROT_WRITE,
5564
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
5665
-1,
57-
0,
66+
Default::default(),
5867
)
5968
};
6069
assert_eq!(ptr, libc::MAP_FAILED);
6170
assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
6271

6372
let ptr = unsafe {
64-
libc::mmap(
73+
mmap(
6574
ptr::invalid_mut(page_size * 64),
6675
page_size,
6776
libc::PROT_READ | libc::PROT_WRITE,
6877
// We don't support MAP_FIXED
6978
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS | libc::MAP_FIXED,
7079
-1,
71-
0,
80+
Default::default(),
7281
)
7382
};
7483
assert_eq!(ptr, libc::MAP_FAILED);
@@ -77,13 +86,13 @@ fn test_mmap() {
7786
// We don't support protections other than read+write
7887
for prot in [libc::PROT_NONE, libc::PROT_EXEC, libc::PROT_READ, libc::PROT_WRITE] {
7988
let ptr = unsafe {
80-
libc::mmap(
89+
mmap(
8190
ptr::null_mut(),
8291
page_size,
8392
prot,
8493
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
8594
-1,
86-
0,
95+
Default::default(),
8796
)
8897
};
8998
assert_eq!(ptr, libc::MAP_FAILED);
@@ -93,13 +102,13 @@ fn test_mmap() {
93102
// We report an error for mappings whose length cannot be rounded up to a multiple of
94103
// the page size.
95104
let ptr = unsafe {
96-
libc::mmap(
105+
mmap(
97106
ptr::null_mut(),
98107
usize::MAX - 1,
99108
libc::PROT_READ | libc::PROT_WRITE,
100109
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
101110
-1,
102-
0,
111+
Default::default(),
103112
)
104113
};
105114
assert_eq!(ptr, libc::MAP_FAILED);
@@ -163,7 +172,9 @@ fn test_mremap() {
163172
}
164173

165174
fn main() {
166-
test_mmap();
175+
test_mmap(libc::mmap);
176+
#[cfg(target_os = "linux")]
177+
test_mmap(libc::mmap64);
167178
#[cfg(target_os = "linux")]
168179
test_mremap();
169180
}

0 commit comments

Comments
 (0)