1 /* 2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <sys/mman.h> 7 8 #include <errno.h> 9 10 #include <OS.h> 11 12 #include <syscall_utils.h> 13 #include <syscalls.h> 14 #include <vm.h> 15 16 17 void* 18 mmap(void* address, size_t length, int protection, int flags, int fd, 19 off_t offset) 20 { 21 // offset and length must be page-aligned 22 if (length == 0 || offset % B_PAGE_SIZE != 0) { 23 errno = B_BAD_VALUE; 24 return MAP_FAILED; 25 } 26 27 // check anonymous mapping 28 if ((flags & MAP_ANONYMOUS) != 0) { 29 fd = -1; 30 } else if (fd < 0) { 31 errno = EBADF; 32 return MAP_FAILED; 33 } 34 35 // either MAP_SHARED or MAP_PRIVATE must be specified 36 if (((flags & MAP_SHARED) != 0) == ((flags & MAP_PRIVATE) != 0)) { 37 errno = B_BAD_VALUE; 38 return MAP_FAILED; 39 } 40 41 // translate mapping, address specification, and protection 42 int mapping = (flags & MAP_SHARED) != 0 43 ? REGION_NO_PRIVATE_MAP : REGION_PRIVATE_MAP; 44 45 uint32 addressSpec = B_ANY_ADDRESS; 46 if ((flags & MAP_FIXED) != 0) 47 addressSpec = B_EXACT_ADDRESS; 48 49 uint32 areaProtection = 0; 50 if ((protection & PROT_READ) != 0) 51 areaProtection |= B_READ_AREA; 52 if ((protection & PROT_WRITE) != 0) 53 areaProtection |= B_WRITE_AREA; 54 if ((protection & PROT_EXEC) != 0) 55 areaProtection |= B_EXECUTE_AREA; 56 57 // ask the kernel to map 58 area_id area = _kern_map_file("mmap area", &address, addressSpec, 59 length, areaProtection, mapping, fd, offset); 60 if (area < 0) { 61 errno = area; 62 return MAP_FAILED; 63 } 64 65 return address; 66 } 67 68 69 int 70 munmap(void* address, size_t length) 71 { 72 RETURN_AND_SET_ERRNO(_kern_unmap_memory(address, length)); 73 } 74