59 |
|
#endif |
60 |
|
static char * next_address = (char *)MAP_BASE; |
61 |
|
#ifdef HAVE_MMAP_ANON |
62 |
< |
#define map_flags (MAP_PRIVATE | MAP_ANON | MAP_EXTRA_FLAGS) |
62 |
> |
#define map_flags (MAP_ANON | MAP_EXTRA_FLAGS) |
63 |
|
#define zero_fd -1 |
64 |
|
#else |
65 |
|
#ifdef HAVE_MMAP_ANONYMOUS |
66 |
< |
#define map_flags (MAP_PRIVATE | MAP_ANONYMOUS | MAP_EXTRA_FLAGS) |
66 |
> |
#define map_flags (MAP_ANONYMOUS | MAP_EXTRA_FLAGS) |
67 |
|
#define zero_fd -1 |
68 |
|
#else |
69 |
|
#ifdef HAVE_FCNTL_H |
70 |
|
#include <fcntl.h> |
71 |
|
#endif |
72 |
< |
#define map_flags (MAP_PRIVATE | MAP_EXTRA_FLAGS) |
72 |
> |
#define map_flags (MAP_EXTRA_FLAGS) |
73 |
|
static int zero_fd = -1; |
74 |
|
#endif |
75 |
|
#endif |
76 |
|
#endif |
77 |
|
|
78 |
+ |
/* Translate generic VM map flags to host values. */ |
79 |
+ |
|
80 |
+ |
#ifdef HAVE_MMAP_VM |
81 |
+ |
static int translate_map_flags(int vm_flags) |
82 |
+ |
{ |
83 |
+ |
int flags = 0; |
84 |
+ |
if (vm_flags & VM_MAP_SHARED) |
85 |
+ |
flags |= MAP_SHARED; |
86 |
+ |
if (vm_flags & VM_MAP_PRIVATE) |
87 |
+ |
flags |= MAP_PRIVATE; |
88 |
+ |
if (vm_flags & VM_MAP_FIXED) |
89 |
+ |
flags |= MAP_FIXED; |
90 |
+ |
if (vm_flags & VM_MAP_32BIT) |
91 |
+ |
flags |= MAP_32BIT; |
92 |
+ |
return flags; |
93 |
+ |
} |
94 |
+ |
#endif |
95 |
+ |
|
96 |
|
/* Initialize the VM system. Returns 0 if successful, -1 for errors. */ |
97 |
|
|
98 |
|
int vm_init(void) |
122 |
|
and default protection bits are read / write. The return value |
123 |
|
is the actual mapping address chosen or VM_MAP_FAILED for errors. */ |
124 |
|
|
125 |
< |
void * vm_acquire(size_t size) |
125 |
> |
void * vm_acquire(size_t size, int options) |
126 |
|
{ |
127 |
|
void * addr; |
128 |
< |
|
128 |
> |
|
129 |
> |
// VM_MAP_FIXED are to be used with vm_acquire_fixed() only |
130 |
> |
if (options & VM_MAP_FIXED) |
131 |
> |
return VM_MAP_FAILED; |
132 |
> |
|
133 |
|
#ifdef HAVE_MACH_VM |
134 |
|
// vm_allocate() returns a zero-filled memory region |
135 |
|
if (vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, TRUE) != KERN_SUCCESS) |
136 |
|
return VM_MAP_FAILED; |
137 |
|
#else |
138 |
|
#ifdef HAVE_MMAP_VM |
139 |
< |
if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, map_flags, zero_fd, 0)) == MAP_FAILED) |
139 |
> |
const int extra_map_flags = translate_map_flags(options); |
140 |
> |
|
141 |
> |
if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, extra_map_flags | map_flags, zero_fd, 0)) == MAP_FAILED) |
142 |
|
return VM_MAP_FAILED; |
143 |
|
|
144 |
+ |
// Sanity checks for 64-bit platforms |
145 |
+ |
if (sizeof(void *) == 8 && (options & VM_MAP_32BIT) && !((char *)addr <= (char *)0xffffffff)) |
146 |
+ |
return VM_MAP_FAILED; |
147 |
+ |
|
148 |
|
next_address = (char *)addr + size; |
149 |
|
|
150 |
|
// Since I don't know the standard behavior of mmap(), zero-fill here |
170 |
|
/* Allocate zero-filled memory at exactly ADDR (which must be page-aligned). |
171 |
|
Retuns 0 if successful, -1 on errors. */ |
172 |
|
|
173 |
< |
int vm_acquire_fixed(void * addr, size_t size) |
173 |
> |
int vm_acquire_fixed(void * addr, size_t size, int options) |
174 |
|
{ |
175 |
+ |
// Fixed mappings are required to be private |
176 |
+ |
if (options & VM_MAP_SHARED) |
177 |
+ |
return -1; |
178 |
+ |
|
179 |
|
#ifdef HAVE_MACH_VM |
180 |
|
// vm_allocate() returns a zero-filled memory region |
181 |
|
if (vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, 0) != KERN_SUCCESS) |
182 |
|
return -1; |
183 |
|
#else |
184 |
|
#ifdef HAVE_MMAP_VM |
185 |
< |
if (mmap((caddr_t)addr, size, VM_PAGE_DEFAULT, map_flags | MAP_FIXED, zero_fd, 0) == MAP_FAILED) |
185 |
> |
const int extra_map_flags = translate_map_flags(options); |
186 |
> |
|
187 |
> |
if (mmap((caddr_t)addr, size, VM_PAGE_DEFAULT, extra_map_flags | map_flags | MAP_FIXED, zero_fd, 0) == MAP_FAILED) |
188 |
|
return -1; |
189 |
|
|
190 |
|
// Since I don't know the standard behavior of mmap(), zero-fill here |