check if uid changes across syscalls.
[trinity.git] / maps.c
blob18b9bcb5771e6fa32d6ac4eff5c0ec2c70e6869a
1 #include <errno.h>
2 #include <fcntl.h>
3 #include <malloc.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/mman.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include "trinity.h" // page_size
12 #include "arch.h"
13 #include "maps.h"
14 #include "log.h"
15 #include "shm.h"
17 static unsigned int num_mappings = 0;
18 static struct map *maps_list;
20 char *page_zeros;
21 char *page_0xff;
22 char *page_rand;
23 char *page_allocs;
25 void * alloc_shared(unsigned int size)
27 void *ret;
29 ret = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
30 if (ret == MAP_FAILED)
31 return NULL;
33 return ret;
36 static struct map * alloc_map(void)
38 struct map *newmap;
40 newmap = malloc(sizeof(struct map));
41 if (!newmap) {
42 printf("Couldn't allocate maps list!\n");
43 exit(EXIT_FAILURE);
45 memset(newmap, 0, sizeof(struct map));
46 return newmap;
49 static void dump_maps(void)
51 struct map *tmpmap = maps_list;
52 unsigned int j;
54 output(2, "There are %d entries in the map table\n", num_mappings);
56 for (j = 0; j < num_mappings; j++) {
57 output(2, " start: %p name: %s\n", tmpmap->ptr, tmpmap->name);
58 tmpmap = tmpmap->next;
62 static void * alloc_zero_map(struct map *map, int prot, const char *name)
64 struct map *tmpmap = map;
65 int fd;
66 unsigned long size = 0;
68 if (!tmpmap)
69 tmpmap = alloc_map();
71 fd = open("/dev/zero", O_RDWR);
72 if (fd < 0) {
73 printf("open /dev/zero failure. %s\n", strerror(errno));
74 exit(EXIT_FAILURE);
77 /* Pick a random sized mmap. */
78 switch (rand() % 4) {
79 case 0: size = page_size;
80 break;
81 case 1: size = 1024*1024;
82 break;
83 case 2: size = 2 * (1024*1024);
84 break;
85 case 3: size = 4 * (1024*1024);
86 break;
87 default:
88 break;
91 /* page_size * 2, so we have a guard page afterwards.
92 * This is necessary for when we want to test page boundaries.
93 * see end of _get_address() for details.
95 size *= 2;
97 tmpmap->ptr = mmap(NULL, size, prot, MAP_ANONYMOUS|MAP_SHARED, fd, 0);
99 if (tmpmap->ptr == MAP_FAILED) {
100 printf("mmap /dev/zero failure\n");
101 exit(EXIT_FAILURE);
104 tmpmap->size = size;
106 tmpmap->name = malloc(80);
107 if (!tmpmap->name) {
108 fprintf(stderr, "malloc() failed in %s().", __func__);
109 exit(EXIT_FAILURE);
112 sprintf(tmpmap->name, "/dev/zero(%s)", name);
113 num_mappings++;
115 output(2, "mapping[%d]: (zeropage %s) %p (%lu bytes)\n",
116 num_mappings - 1, name, tmpmap->ptr, size);
118 if (fd >= 0)
119 close(fd);
120 return tmpmap;
123 void setup_maps(void)
125 struct map *tmpmap;
127 tmpmap = maps_list = alloc_map();
129 /* Add a bunch of /dev/zero mappings */
130 tmpmap->next = alloc_zero_map(tmpmap, PROT_READ | PROT_WRITE, "PROT_READ | PROT_WRITE");
131 tmpmap = tmpmap->next;
133 tmpmap->next = alloc_zero_map(NULL, PROT_READ, "PROT_READ");
134 tmpmap = tmpmap->next;
136 tmpmap->next = alloc_zero_map(NULL, PROT_WRITE, "PROT_WRITE");
138 output(2, "Added /dev/zero mappings.\n");
139 dump_maps();
142 void * get_map(void)
144 struct map *tmpmap = maps_list;
145 unsigned int i, j;
147 i = rand() % num_mappings;
148 for (j = 0; j < i; j++)
149 tmpmap = tmpmap->next;
151 return tmpmap->ptr;
154 void destroy_maps(void)
156 unsigned int i;
157 struct map *thismap = maps_list, *next;
159 for (i = 0; i < num_mappings; i++) {
160 next = thismap->next;
161 munmap(thismap->ptr, thismap->size);
162 free(thismap->name);
163 free(thismap);
164 thismap = next;
166 num_mappings = 0;
169 void init_buffers(void)
171 unsigned int i;
173 output(2, "shm is at %p\n", shm);
175 page_zeros = memalign(page_size, page_size * 2);
176 if (!page_zeros)
177 exit(EXIT_FAILURE);
178 memset(page_zeros, 0, page_size);
179 output(2, "page_zeros @ %p\n", page_zeros);
181 page_0xff = memalign(page_size, page_size * 2);
182 if (!page_0xff)
183 exit(EXIT_FAILURE);
184 memset(page_0xff, 0xff, page_size);
185 output(2, "page_0xff @ %p\n", page_0xff);
187 page_rand = memalign(page_size, page_size * 2);
188 if (!page_rand)
189 exit(EXIT_FAILURE);
190 memset(page_rand, 0x55, page_size); /* overwritten below */
191 output(2, "page_rand @ %p\n", page_rand);
193 page_allocs = memalign(page_size, page_size * 2);
194 if (!page_allocs)
195 exit(EXIT_FAILURE);
196 memset(page_allocs, 0xff, page_size);
197 output(2, "page_allocs @ %p\n", page_allocs);
199 for (i = 0; i < (page_size / sizeof(unsigned long *)); i++)
200 page_allocs[i] = (unsigned long) malloc(page_size);
202 setup_maps();
204 // generate_random_page may end up using maps, so has to be last.
205 generate_random_page(page_rand);