13da5c369Sopenharmony_ciuse nix::sys::mman::{mmap, MapFlags, ProtFlags}; 23da5c369Sopenharmony_ciuse std::num::NonZeroUsize; 33da5c369Sopenharmony_ci 43da5c369Sopenharmony_ci#[test] 53da5c369Sopenharmony_cifn test_mmap_anonymous() { 63da5c369Sopenharmony_ci unsafe { 73da5c369Sopenharmony_ci let ptr = mmap( 83da5c369Sopenharmony_ci None, 93da5c369Sopenharmony_ci NonZeroUsize::new(1).unwrap(), 103da5c369Sopenharmony_ci ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, 113da5c369Sopenharmony_ci MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS, 123da5c369Sopenharmony_ci -1, 133da5c369Sopenharmony_ci 0, 143da5c369Sopenharmony_ci ) 153da5c369Sopenharmony_ci .unwrap() as *mut u8; 163da5c369Sopenharmony_ci assert_eq!(*ptr, 0x00u8); 173da5c369Sopenharmony_ci *ptr = 0xffu8; 183da5c369Sopenharmony_ci assert_eq!(*ptr, 0xffu8); 193da5c369Sopenharmony_ci } 203da5c369Sopenharmony_ci} 213da5c369Sopenharmony_ci 223da5c369Sopenharmony_ci#[test] 233da5c369Sopenharmony_ci#[cfg(any(target_os = "linux", target_os = "netbsd"))] 243da5c369Sopenharmony_cifn test_mremap_grow() { 253da5c369Sopenharmony_ci use nix::libc::{c_void, size_t}; 263da5c369Sopenharmony_ci use nix::sys::mman::{mremap, MRemapFlags}; 273da5c369Sopenharmony_ci 283da5c369Sopenharmony_ci const ONE_K: size_t = 1024; 293da5c369Sopenharmony_ci let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap(); 303da5c369Sopenharmony_ci 313da5c369Sopenharmony_ci let slice: &mut [u8] = unsafe { 323da5c369Sopenharmony_ci let mem = mmap( 333da5c369Sopenharmony_ci None, 343da5c369Sopenharmony_ci one_k_non_zero, 353da5c369Sopenharmony_ci ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, 363da5c369Sopenharmony_ci MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, 373da5c369Sopenharmony_ci -1, 383da5c369Sopenharmony_ci 0, 393da5c369Sopenharmony_ci ) 403da5c369Sopenharmony_ci .unwrap(); 413da5c369Sopenharmony_ci std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) 423da5c369Sopenharmony_ci }; 433da5c369Sopenharmony_ci assert_eq!(slice[ONE_K - 1], 0x00); 443da5c369Sopenharmony_ci slice[ONE_K - 1] = 0xFF; 453da5c369Sopenharmony_ci assert_eq!(slice[ONE_K - 1], 0xFF); 463da5c369Sopenharmony_ci 473da5c369Sopenharmony_ci let slice: &mut [u8] = unsafe { 483da5c369Sopenharmony_ci #[cfg(target_os = "linux")] 493da5c369Sopenharmony_ci let mem = mremap( 503da5c369Sopenharmony_ci slice.as_mut_ptr() as *mut c_void, 513da5c369Sopenharmony_ci ONE_K, 523da5c369Sopenharmony_ci 10 * ONE_K, 533da5c369Sopenharmony_ci MRemapFlags::MREMAP_MAYMOVE, 543da5c369Sopenharmony_ci None, 553da5c369Sopenharmony_ci ) 563da5c369Sopenharmony_ci .unwrap(); 573da5c369Sopenharmony_ci #[cfg(target_os = "netbsd")] 583da5c369Sopenharmony_ci let mem = mremap( 593da5c369Sopenharmony_ci slice.as_mut_ptr() as *mut c_void, 603da5c369Sopenharmony_ci ONE_K, 613da5c369Sopenharmony_ci 10 * ONE_K, 623da5c369Sopenharmony_ci MRemapFlags::MAP_REMAPDUP, 633da5c369Sopenharmony_ci None, 643da5c369Sopenharmony_ci ) 653da5c369Sopenharmony_ci .unwrap(); 663da5c369Sopenharmony_ci std::slice::from_raw_parts_mut(mem as *mut u8, 10 * ONE_K) 673da5c369Sopenharmony_ci }; 683da5c369Sopenharmony_ci 693da5c369Sopenharmony_ci // The first KB should still have the old data in it. 703da5c369Sopenharmony_ci assert_eq!(slice[ONE_K - 1], 0xFF); 713da5c369Sopenharmony_ci 723da5c369Sopenharmony_ci // The additional range should be zero-init'd and accessible. 733da5c369Sopenharmony_ci assert_eq!(slice[10 * ONE_K - 1], 0x00); 743da5c369Sopenharmony_ci slice[10 * ONE_K - 1] = 0xFF; 753da5c369Sopenharmony_ci assert_eq!(slice[10 * ONE_K - 1], 0xFF); 763da5c369Sopenharmony_ci} 773da5c369Sopenharmony_ci 783da5c369Sopenharmony_ci#[test] 793da5c369Sopenharmony_ci#[cfg(any(target_os = "linux", target_os = "netbsd"))] 803da5c369Sopenharmony_ci// Segfaults for unknown reasons under QEMU for 32-bit targets 813da5c369Sopenharmony_ci#[cfg_attr(all(target_pointer_width = "32", qemu), ignore)] 823da5c369Sopenharmony_cifn test_mremap_shrink() { 833da5c369Sopenharmony_ci use nix::libc::{c_void, size_t}; 843da5c369Sopenharmony_ci use nix::sys::mman::{mremap, MRemapFlags}; 853da5c369Sopenharmony_ci use std::num::NonZeroUsize; 863da5c369Sopenharmony_ci 873da5c369Sopenharmony_ci const ONE_K: size_t = 1024; 883da5c369Sopenharmony_ci let ten_one_k = NonZeroUsize::new(10 * ONE_K).unwrap(); 893da5c369Sopenharmony_ci let slice: &mut [u8] = unsafe { 903da5c369Sopenharmony_ci let mem = mmap( 913da5c369Sopenharmony_ci None, 923da5c369Sopenharmony_ci ten_one_k, 933da5c369Sopenharmony_ci ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, 943da5c369Sopenharmony_ci MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, 953da5c369Sopenharmony_ci -1, 963da5c369Sopenharmony_ci 0, 973da5c369Sopenharmony_ci ) 983da5c369Sopenharmony_ci .unwrap(); 993da5c369Sopenharmony_ci std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) 1003da5c369Sopenharmony_ci }; 1013da5c369Sopenharmony_ci assert_eq!(slice[ONE_K - 1], 0x00); 1023da5c369Sopenharmony_ci slice[ONE_K - 1] = 0xFF; 1033da5c369Sopenharmony_ci assert_eq!(slice[ONE_K - 1], 0xFF); 1043da5c369Sopenharmony_ci 1053da5c369Sopenharmony_ci let slice: &mut [u8] = unsafe { 1063da5c369Sopenharmony_ci let mem = mremap( 1073da5c369Sopenharmony_ci slice.as_mut_ptr() as *mut c_void, 1083da5c369Sopenharmony_ci ten_one_k.into(), 1093da5c369Sopenharmony_ci ONE_K, 1103da5c369Sopenharmony_ci MRemapFlags::empty(), 1113da5c369Sopenharmony_ci None, 1123da5c369Sopenharmony_ci ) 1133da5c369Sopenharmony_ci .unwrap(); 1143da5c369Sopenharmony_ci // Since we didn't supply MREMAP_MAYMOVE, the address should be the 1153da5c369Sopenharmony_ci // same. 1163da5c369Sopenharmony_ci assert_eq!(mem, slice.as_mut_ptr() as *mut c_void); 1173da5c369Sopenharmony_ci std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) 1183da5c369Sopenharmony_ci }; 1193da5c369Sopenharmony_ci 1203da5c369Sopenharmony_ci // The first KB should still be accessible and have the old data in it. 1213da5c369Sopenharmony_ci assert_eq!(slice[ONE_K - 1], 0xFF); 1223da5c369Sopenharmony_ci} 123