1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9 /**
10 * \file mmap_anon.c
11 * \brief Provide a compatible anonymous space mapping function
12 */
13
14 #include <stdio.h>
15
16 #include <fcntl.h>
17 #include <sys/mman.h>
18 #include <unistd.h>
19
20 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
21 #define MAP_ANONYMOUS MAP_ANON
22 #endif
23
24 /*
25 * mmap() anonymous space, depending on the system's mmap() style. On systems
26 * that use the /dev/zero mapping idiom, zerofd will be set to the file descriptor
27 * of the opened /dev/zero.
28 */
29
30 /**
31 * \brief mmap() anonymous space, depending on the system's mmap() style. On systems
32 * that use the /dev/zero mapping idiom, zerofd will be set to the file descriptor
33 * of the opened /dev/zero.
34 *
35 * \param addr address to map at.
36 * \param len number of bytes from addr to be mapped.
37 * \param prot protections (region accessibility).
38 * \param flags specifies the type of the mapped object.
39 * \param offset start mapping at byte offset.
40 * \param zerofd
41 * \return a pointer to the mapped region upon successful completion, -1 otherwise.
42 */
mmap_anon(void * addr,size_t len,int prot,int flags,off_t offset)43 void *mmap_anon(void *addr, size_t len, int prot, int flags, off_t offset)
44 {
45 void *result;
46
47 #ifndef MAP_ANONYMOUS
48 int fd;
49 #endif
50
51 /* From loader/ext.c:
52 * "Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap"
53 * Therefore we preserve the same behavior on all platforms, ie. no
54 * shared mappings of anon space (if the concepts are supported). */
55 #if defined(MAP_SHARED) && defined(MAP_PRIVATE)
56 flags = (flags & ~MAP_SHARED) | MAP_PRIVATE;
57 #endif /* defined(MAP_SHARED) && defined(MAP_PRIVATE) */
58
59 #ifdef MAP_ANONYMOUS
60 /* BSD-style anonymous mapping */
61 result = mmap(addr, len, prot, flags | MAP_ANONYMOUS, -1, offset);
62 #else
63 /* SysV-style anonymous mapping */
64 fd = open("/dev/zero", O_RDWR);
65 if(fd < 0){
66 perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: ");
67 return NULL;
68 }
69
70 result = mmap(addr, len, prot, flags, fd, offset);
71 close(fd);
72 #endif /* MAP_ANONYMOUS */
73
74 return result;
75 }
76