#include #include #include #include #include /* This file includes a simple set of memory allocation calls that * a user space program can use to allocate/free or move memory mappings. * The intent of this program is to make it easier to verify if the kernel * internal mappings are correct. */ #define PAGE_SHIFT 12 #define ROUND_PAGES(memsize) ((memsize >> (PAGE_SHIFT)) << PAGE_SHIFT) /* approximately half of memsize, page aligned */ #define HALF_MEM(memsize) ((memsize >> (PAGE_SHIFT))<<(PAGE_SHIFT - 1)) inline void waitnext() { fflush(NULL); getchar(); } int main(int argc, char *argv[]) { unsigned int memsize; char *mem; int i, numpages, fd; if (argc != 2) { printf("Usage: %s \n", argv[0]); exit(EXIT_FAILURE); } memsize = strtoul(argv[1], NULL, 10); memsize = ROUND_PAGES(memsize); /* We should be limited to < 4G so any size other than 0 is ok */ if (memsize == 0) { printf("Invalid memsize\n"); exit(EXIT_FAILURE); } numpages = memsize >> PAGE_SHIFT; mlockall(MCL_FUTURE); mem = sbrk(memsize); if (mem == (void*) -1) { perror("Failed to allocate memory using sbrk\n"); exit(EXIT_FAILURE); } printf("Successfully allocated sbrk memory %d bytes @%p\n", memsize, mem); waitnext(); sbrk(-(memsize)); mem = mmap(0, memsize, PROT_READ | PROT_WRITE, MAP_PRIVATE| MAP_ANONYMOUS, -1, 0); if (mem == (void*) -1) { perror("Failed to allocate anon private memory using mmap\n"); exit(EXIT_FAILURE); } printf("Successfully allocated anon mmap memory %d bytes @%p\n", memsize, mem); waitnext(); if (-1 == mprotect(mem, HALF_MEM(memsize), PROT_READ)) { perror("Failed to W protect memory using mprotect\n"); exit(EXIT_FAILURE); } printf("Successfully write protected %d bytes @%p\n", HALF_MEM(memsize), mem); waitnext(); if (-1 == mprotect(mem, HALF_MEM(memsize), PROT_READ | PROT_WRITE)) { perror("Failed to RW protect memory using mprotect\n"); exit(EXIT_FAILURE); } printf("Successfully cleared write protected %d bytes @%p\n", memsize, mem); waitnext(); /* Mark all pages with a specific pattern */ for (i = 0; i < numpages; i++) { int *ptr = (int *)(mem + i*4096); *ptr = i; } mem = mremap(mem , memsize, memsize + HALF_MEM(memsize), 1 /* MREMAP_MAYMOVE */); if (mem == MAP_FAILED) { perror("Failed to remap expand anon private memory\n"); exit(EXIT_FAILURE); } printf("Successfully remapped %d bytes @%p\n", memsize + HALF_MEM(memsize), mem); waitnext(); /* Mark all pages with a specific pattern */ for (i = 0; i < numpages; i++) { int value = *(int*)(mem + i*4096); if (value != i) { printf("remap error expected %d got %d\n", i, value); exit(EXIT_FAILURE); } } if (munmap(mem, memsize + HALF_MEM(memsize))) { perror("Could not unmap and free memory\n"); exit(EXIT_FAILURE); } fd = open("/dev/zero", O_RDONLY); mem = mmap(0, memsize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (mem == (void*) -1) { perror("Failed to allocate file backed memory using mmap\n"); exit(EXIT_FAILURE); } printf("Successfully allocated file backed mmap memory %d bytes @%p\n", memsize, mem); waitnext(); if (munmap(mem, memsize)) { perror("Could not unmap and free file backed memory\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }