1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/mman.h>
4 #include <unistd.h>
5 #include <fcntl.h>
6
7 /* This file includes a simple set of memory allocation calls that
8 * a user space program can use to allocate/free or move memory mappings.
9 * The intent of this program is to make it easier to verify if the kernel
10 * internal mappings are correct.
11 */
12
13 #define PAGE_SHIFT 12
14
15 #define ROUND_PAGES(memsize) ((memsize >> (PAGE_SHIFT)) << PAGE_SHIFT)
16
17 /* approximately half of memsize, page aligned */
18 #define HALF_MEM(memsize) ((memsize >> (PAGE_SHIFT))<<(PAGE_SHIFT - 1))
19
waitnext()20 inline void waitnext() {
21 fflush(NULL);
22 getchar();
23 }
24
main(int argc,char * argv[])25 int main(int argc, char *argv[]) {
26 unsigned int memsize;
27 char *mem;
28 int i, numpages, fd;
29
30 if (argc != 2) {
31 printf("Usage: %s <memory_size>\n", argv[0]);
32 exit(EXIT_FAILURE);
33 }
34
35 memsize = strtoul(argv[1], NULL, 10);
36
37 memsize = ROUND_PAGES(memsize);
38
39 /* We should be limited to < 4G so any size other than 0 is ok */
40 if (memsize == 0) {
41 printf("Invalid memsize\n");
42 exit(EXIT_FAILURE);
43 }
44
45
46 numpages = memsize >> PAGE_SHIFT;
47
48 mlockall(MCL_FUTURE);
49
50 mem = sbrk(memsize);
51
52 if (mem == (void*) -1) {
53 perror("Failed to allocate memory using sbrk\n");
54 exit(EXIT_FAILURE);
55 }
56
57 printf("Successfully allocated sbrk memory %d bytes @%p\n",
58 memsize, mem);
59
60 waitnext();
61
62 sbrk(-(memsize));
63
64 mem = mmap(0, memsize, PROT_READ | PROT_WRITE,
65 MAP_PRIVATE| MAP_ANONYMOUS,
66 -1, 0);
67
68 if (mem == (void*) -1) {
69 perror("Failed to allocate anon private memory using mmap\n");
70 exit(EXIT_FAILURE);
71 }
72
73 printf("Successfully allocated anon mmap memory %d bytes @%p\n",
74 memsize, mem);
75
76 waitnext();
77
78 if (-1 == mprotect(mem, HALF_MEM(memsize), PROT_READ)) {
79 perror("Failed to W protect memory using mprotect\n");
80 exit(EXIT_FAILURE);
81 }
82
83 printf("Successfully write protected %d bytes @%p\n",
84 HALF_MEM(memsize), mem);
85
86 waitnext();
87
88 if (-1 == mprotect(mem, HALF_MEM(memsize),
89 PROT_READ | PROT_WRITE)) {
90 perror("Failed to RW protect memory using mprotect\n");
91 exit(EXIT_FAILURE);
92 }
93
94 printf("Successfully cleared write protected %d bytes @%p\n",
95 memsize, mem);
96 waitnext();
97
98 /* Mark all pages with a specific pattern */
99 for (i = 0; i < numpages; i++) {
100 int *ptr = (int *)(mem + i*4096);
101 *ptr = i;
102 }
103
104 mem = mremap(mem , memsize,
105 memsize + HALF_MEM(memsize),
106 1 /* MREMAP_MAYMOVE */);
107
108 if (mem == MAP_FAILED) {
109 perror("Failed to remap expand anon private memory\n");
110 exit(EXIT_FAILURE);
111 }
112
113 printf("Successfully remapped %d bytes @%p\n",
114 memsize + HALF_MEM(memsize), mem);
115
116 waitnext();
117
118 /* Mark all pages with a specific pattern */
119 for (i = 0; i < numpages; i++) {
120 int value = *(int*)(mem + i*4096);
121 if (value != i) {
122 printf("remap error expected %d got %d\n",
123 i, value);
124 exit(EXIT_FAILURE);
125 }
126 }
127
128 if (munmap(mem, memsize + HALF_MEM(memsize))) {
129 perror("Could not unmap and free memory\n");
130 exit(EXIT_FAILURE);
131 }
132
133
134 fd = open("/dev/zero", O_RDONLY);
135
136 mem = mmap(0, memsize, PROT_READ | PROT_WRITE,
137 MAP_PRIVATE,
138 fd, 0);
139
140 if (mem == (void*) -1) {
141 perror("Failed to allocate file backed memory using mmap\n");
142 exit(EXIT_FAILURE);
143 }
144
145 printf("Successfully allocated file backed mmap memory %d bytes @%p\n",
146 memsize, mem);
147 waitnext();
148
149 if (munmap(mem, memsize)) {
150 perror("Could not unmap and free file backed memory\n");
151 exit(EXIT_FAILURE);
152 }
153
154 exit(EXIT_SUCCESS);
155 }
156