diff --git a/src/lib.rs b/src/lib.rs index 0ff18f97..a2d3d189 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,7 +28,7 @@ use std::ops::{Deref, DerefMut}; /// `MmapOptions::map_exec`, or `MmapOptions::map_copy`. #[derive(Clone, Debug, Default)] pub struct MmapOptions { - offset: usize, + offset: u64, len: Option, stack: bool, } @@ -86,7 +86,7 @@ impl MmapOptions { /// # } /// # fn main() { try_main().unwrap(); } /// ``` - pub fn offset(&mut self, offset: usize) -> &mut Self { + pub fn offset(&mut self, offset: u64) -> &mut Self { self.offset = offset; self } @@ -123,13 +123,14 @@ impl MmapOptions { fn get_len(&self, file: &File) -> Result { self.len.map(Ok).unwrap_or_else(|| { let len = file.metadata()?.len(); + let len = len - self.offset; if len > (usize::MAX as u64) { return Err(Error::new( ErrorKind::InvalidData, "file length overflows usize", )); } - Ok(len as usize - self.offset) + Ok(len as usize) }) } @@ -829,12 +830,20 @@ mod test { .open(&path) .unwrap(); - file.set_len(500000 as u64).unwrap(); + let offset = u32::max_value() as u64 + 2; + let len = 5432; + file.set_len(offset + len as u64).unwrap(); - let offset = 5099; - let len = 50050; + // Test both auto-length and explicit length let mut mmap = unsafe { + MmapOptions::new() + .offset(offset) + .map_mut(&file) + .unwrap() + }; + assert_eq!(len, mmap.len()); + mmap = unsafe { MmapOptions::new() .offset(offset) .len(len) diff --git a/src/unix.rs b/src/unix.rs index fbece88f..0abaa32d 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -26,10 +26,10 @@ impl MmapInner { prot: libc::c_int, flags: libc::c_int, file: RawFd, - offset: usize, + offset: u64, ) -> io::Result { - let alignment = offset % page_size(); - let aligned_offset = offset - alignment; + let alignment = (offset % page_size() as u64) as usize; + let aligned_offset = offset - alignment as u64; let aligned_len = len + alignment; if aligned_len == 0 { // Normally the OS would catch this, but it segfaults under QEMU. @@ -60,7 +60,7 @@ impl MmapInner { } } - pub fn map(len: usize, file: &File, offset: usize) -> io::Result { + pub fn map(len: usize, file: &File, offset: u64) -> io::Result { MmapInner::new( len, libc::PROT_READ, @@ -70,7 +70,7 @@ impl MmapInner { ) } - pub fn map_exec(len: usize, file: &File, offset: usize) -> io::Result { + pub fn map_exec(len: usize, file: &File, offset: u64) -> io::Result { MmapInner::new( len, libc::PROT_READ | libc::PROT_EXEC, @@ -80,7 +80,7 @@ impl MmapInner { ) } - pub fn map_mut(len: usize, file: &File, offset: usize) -> io::Result { + pub fn map_mut(len: usize, file: &File, offset: u64) -> io::Result { MmapInner::new( len, libc::PROT_READ | libc::PROT_WRITE, @@ -90,7 +90,7 @@ impl MmapInner { ) } - pub fn map_copy(len: usize, file: &File, offset: usize) -> io::Result { + pub fn map_copy(len: usize, file: &File, offset: u64) -> io::Result { MmapInner::new( len, libc::PROT_READ | libc::PROT_WRITE, diff --git a/src/windows.rs b/src/windows.rs index a6f4bcdf..476241a2 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -46,12 +46,12 @@ impl MmapInner { file: &File, protect: DWORD, access: DWORD, - offset: usize, + offset: u64, len: usize, copy: bool, ) -> io::Result { - let alignment = offset % allocation_granularity(); - let aligned_offset = offset - alignment; + let alignment = (offset % allocation_granularity() as u64) as usize; + let aligned_offset = offset - alignment as u64; let aligned_len = len + alignment; unsafe { @@ -70,7 +70,7 @@ impl MmapInner { let ptr = MapViewOfFile( handle, access, - (aligned_offset >> 16 >> 16) as DWORD, + (aligned_offset >> 32) as DWORD, (aligned_offset & 0xffffffff) as DWORD, aligned_len as SIZE_T, ); @@ -89,7 +89,7 @@ impl MmapInner { } } - pub fn map(len: usize, file: &File, offset: usize) -> io::Result { + pub fn map(len: usize, file: &File, offset: u64) -> io::Result { let write = protection_supported(file.as_raw_handle(), PAGE_READWRITE); let exec = protection_supported(file.as_raw_handle(), PAGE_EXECUTE_READ); let mut access = FILE_MAP_READ; @@ -116,7 +116,7 @@ impl MmapInner { Ok(inner) } - pub fn map_exec(len: usize, file: &File, offset: usize) -> io::Result { + pub fn map_exec(len: usize, file: &File, offset: u64) -> io::Result { let write = protection_supported(file.as_raw_handle(), PAGE_READWRITE); let mut access = FILE_MAP_READ | FILE_MAP_EXECUTE; let protection = if write { @@ -133,7 +133,7 @@ impl MmapInner { Ok(inner) } - pub fn map_mut(len: usize, file: &File, offset: usize) -> io::Result { + pub fn map_mut(len: usize, file: &File, offset: u64) -> io::Result { let exec = protection_supported(file.as_raw_handle(), PAGE_EXECUTE_READ); let mut access = FILE_MAP_READ | FILE_MAP_WRITE; let protection = if exec { @@ -150,7 +150,7 @@ impl MmapInner { Ok(inner) } - pub fn map_copy(len: usize, file: &File, offset: usize) -> io::Result { + pub fn map_copy(len: usize, file: &File, offset: u64) -> io::Result { let exec = protection_supported(file.as_raw_handle(), PAGE_EXECUTE_READWRITE); let mut access = FILE_MAP_COPY; let protection = if exec {