merge clone variants
[trinity.git] / syscalls / mmap.c
blob19ac4e984e3eb4b8cb1e405f98272de034ae1830
1 /*
2 * SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
3 unsigned long, prot, unsigned long, flags,
4 unsigned long, fd, unsigned long, offset)
6 * sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff)
7 */
8 #include <stdlib.h>
9 #include <string.h>
10 #include <sys/mman.h>
11 #include "maps.h"
12 #include "sanitise.h"
13 #include "shm.h"
14 #include "arch.h"
15 #include "compat.h"
16 #include "random.h"
17 #include "utils.h" //ARRAY_SIZE
18 #include "utils.h"
20 #ifdef __x86_64__
21 #define NUM_FLAGS 13
22 #else
23 #define NUM_FLAGS 12
24 #endif
26 // need this to actually get MAP_UNINITIALIZED defined
27 #define CONFIG_MMAP_ALLOW_UNINITIALIZED
29 static void do_anon(int childno)
31 /* no fd if anonymous mapping. */
32 shm->a5[childno] = -1;
33 shm->a6[childno] = 0;
36 static void sanitise_mmap(int childno)
38 unsigned int i;
39 unsigned int flagvals[NUM_FLAGS] = { MAP_FIXED, MAP_ANONYMOUS,
40 MAP_GROWSDOWN, MAP_DENYWRITE, MAP_EXECUTABLE, MAP_LOCKED,
41 MAP_NORESERVE, MAP_POPULATE, MAP_NONBLOCK, MAP_STACK,
42 MAP_HUGETLB, MAP_UNINITIALIZED,
43 #ifdef __x86_64__
44 MAP_32BIT,
45 #endif
47 unsigned int numflags = rand() % NUM_FLAGS;
48 unsigned long sizes[] = {
49 -1, /* over-written with page_size below */
50 1 * MB, 2 * MB, 4 * MB, 10 * MB,
51 1 * GB,
54 sizes[0] = page_size;
56 /* Don't actually set a hint right now. */
57 shm->a1[childno] = 0;
59 // set additional flags
60 for (i = 0; i < numflags; i++)
61 shm->a4[childno] |= flagvals[rand() % NUM_FLAGS];
63 if (shm->a4[childno] & MAP_ANONYMOUS) {
64 shm->a2[childno] = sizes[rand() % ARRAY_SIZE(sizes)];
65 do_anon(childno);
66 } else {
67 if (this_syscallname("mmap2", childno) == TRUE) {
68 /* mmap2 counts in 4K units */
69 shm->a6[childno] /= 4096;
70 } else {
71 /* page align non-anonymous mappings. */
72 shm->a6[childno] &= PAGE_MASK;
75 shm->a2[childno] = page_size;
79 static void post_mmap(int childno)
81 char *p;
82 struct list_head *list;
83 struct map *new;
85 p = (void *) shm->retval[childno];
86 if (p == MAP_FAILED)
87 return;
89 new = zmalloc(sizeof(struct map));
90 new->name = strdup("misc");
91 new->size = shm->a2[childno];
92 new->prot = shm->a3[childno];
93 //TODO: store fd if !anon
94 new->ptr = p;
95 new->type = MAP_LOCAL;
97 // Add this to a list for use by subsequent syscalls.
98 list = &shm->mappings[childno]->list;
99 list_add_tail(&new->list, list);
100 shm->num_mappings[childno]++;
102 /* Sometimes dirty the mapping. */
103 if (rand_bool())
104 dirty_mapping(new);
107 static char * decode_mmap(int argnum, int childno)
109 char *buf;
111 if (argnum == 3) {
112 int flags = shm->a3[childno];
113 char *p;
115 p = buf = zmalloc(80);
116 p += sprintf(buf, "[");
118 if (flags == 0) {
119 p += sprintf(p, "PROT_NONE]");
120 return buf;
122 if (flags & PROT_READ)
123 p += sprintf(p, "PROT_READ|");
124 if (flags & PROT_WRITE)
125 p += sprintf(p, "PROT_WRITE|");
126 if (flags & PROT_EXEC)
127 p += sprintf(p, "PROT_EXEC|");
128 if (flags & PROT_SEM)
129 p += sprintf(p, "PROT_SEM ");
130 p--;
131 sprintf(p, "]");
133 return buf;
135 return NULL;
138 struct syscallentry syscall_mmap = {
139 .name = "mmap",
140 .num_args = 6,
142 .sanitise = sanitise_mmap,
143 .post = post_mmap,
144 .decode = decode_mmap,
146 .arg1name = "addr",
147 .arg2name = "len",
148 .arg2type = ARG_LEN,
149 .arg3name = "prot",
150 .arg3type = ARG_LIST,
151 .arg3list = {
152 .num = 4,
153 .values = { PROT_READ, PROT_WRITE, PROT_EXEC, PROT_SEM },
155 .arg4name = "flags",
156 .arg4type = ARG_OP,
157 .arg4list = {
158 .num = 2,
159 .values = { MAP_SHARED, MAP_PRIVATE },
161 .arg5name = "fd",
162 .arg5type = ARG_FD,
163 .arg6name = "off",
164 .arg6type = ARG_LEN,
166 .group = GROUP_VM,
167 .flags = NEED_ALARM,
170 struct syscallentry syscall_mmap2 = {
171 .name = "mmap2",
172 .num_args = 6,
174 .sanitise = sanitise_mmap,
175 .post = post_mmap,
176 .decode = decode_mmap,
178 .arg1name = "addr",
179 .arg2name = "len",
180 .arg2type = ARG_LEN,
181 .arg3name = "prot",
182 .arg3type = ARG_LIST,
183 .arg3list = {
184 .num = 4,
185 .values = { PROT_READ, PROT_WRITE, PROT_EXEC, PROT_SEM },
187 .arg4name = "flags",
188 .arg4type = ARG_OP,
189 .arg4list = {
190 .num = 2,
191 .values = { MAP_SHARED, MAP_PRIVATE },
193 .arg5name = "fd",
194 .arg5type = ARG_FD,
195 .arg6name = "pgoff",
196 .arg6type = ARG_LEN,
198 .group = GROUP_VM,
199 .flags = NEED_ALARM,