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