1bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh#include <unistd.h> 283b62cbbab29bde83eba40231f307c2a311e73c8njn#include "tests/sys_mman.h" 3bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh#include <assert.h> 4bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh#include <stdlib.h> 5bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 6bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh#include "../memcheck.h" 7bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 8bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh#define SUPERBLOCK_SIZE 100000 9bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh#define REDZONE_SIZE 8 10bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 11bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalshstatic const int USE_MMAP = 0; 12bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 13bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalshtypedef struct _level_list 14bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh{ 15bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh struct _level_list *next; 16bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh char *where; 1729a5c01528ca7cffe17880a038b4563de920f08dnjn // Padding ensures the struct is the same size on 32-bit and 64-bit 1829a5c01528ca7cffe17880a038b4563de920f08dnjn // machines. 1929a5c01528ca7cffe17880a038b4563de920f08dnjn char padding[16 - 2*sizeof(char*)]; 20bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh} level_list; 21bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 22bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalshtypedef struct _pool { 23bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh char *mem; 24bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh char *where; 25bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh level_list *levels; 2629a5c01528ca7cffe17880a038b4563de920f08dnjn int size, left; 2729a5c01528ca7cffe17880a038b4563de920f08dnjn // Padding ensures the struct is the same size on 32-bit and 64-bit 2829a5c01528ca7cffe17880a038b4563de920f08dnjn // machines. 2929a5c01528ca7cffe17880a038b4563de920f08dnjn char padding[24 - 3*sizeof(char*)]; 30bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh} pool; 31bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 32bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalshpool *make_pool() 33bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh{ 34bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh pool *p; 35bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 36bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh if(USE_MMAP) { 37bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh p = (pool *)mmap(0, sizeof(pool), PROT_READ|PROT_WRITE|PROT_EXEC, 38bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 39bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh p->where = p->mem = (char *)mmap(NULL, SUPERBLOCK_SIZE, 40bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh PROT_READ|PROT_WRITE|PROT_EXEC, 41bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 42bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh } else { 43bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh p = (pool *)malloc(sizeof(pool)); 44bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh p->where = p->mem = (char *)malloc(SUPERBLOCK_SIZE); 45bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh } 46bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 47bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh p->size = p->left = SUPERBLOCK_SIZE; 48bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh p->levels = NULL; 4906bc722457ffe12e056d2f40d0d2f5c8711b541fflorian (void) VALGRIND_MAKE_MEM_NOACCESS(p->where, SUPERBLOCK_SIZE); 50bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh return p; 51bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh} 52bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 53bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalshvoid push(pool *p) 54bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh{ 55bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh level_list *l; 56bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 57bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh if(USE_MMAP) 58bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh l = (level_list *)mmap(0, sizeof(level_list), 59bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh PROT_READ|PROT_WRITE|PROT_EXEC, 60bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 61bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh else 62bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh l = (level_list *)malloc(sizeof(level_list)); 63bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 64bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh l->next = p->levels; 65bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh l->where = p->where; 66bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh VALGRIND_CREATE_MEMPOOL(l->where, REDZONE_SIZE, 0); 67bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh p->levels = l; 68bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh} 69bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 70bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalshvoid pop(pool *p) 71bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh{ 72bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh level_list *l = p->levels; 73bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh p->levels = l->next; 74bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh VALGRIND_DESTROY_MEMPOOL(l->where); 7506bc722457ffe12e056d2f40d0d2f5c8711b541fflorian (void) VALGRIND_MAKE_MEM_NOACCESS(l->where, p->where-l->where); 76bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh p->where = l->where; 77bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh if(USE_MMAP) 78bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh munmap(l, sizeof(level_list)); 79bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh else 80bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh free(l); 81bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh} 82bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 83bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalshvoid destroy_pool(pool *p) 84bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh{ 85bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh level_list *l = p->levels; 86bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 87bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh while(l) { 88bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh pop(p); 89bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh } 90bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh if(USE_MMAP) { 91bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh munmap(p->mem, SUPERBLOCK_SIZE); 92bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh munmap(p, sizeof(pool)); 93bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh } else { 94bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh free(p->mem); 95bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh free(p); 96bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh } 97bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh} 98bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 99bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalshchar *allocate(pool *p, int size) 100bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh{ 101bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh char *where; 102bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh p->left -= size + (REDZONE_SIZE*2); 103bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh where = p->where + REDZONE_SIZE; 104bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh p->where += size + (REDZONE_SIZE*2); 105bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh VALGRIND_MEMPOOL_ALLOC(p->levels->where, where, size); 106bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh return where; 107bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh} 108bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 109bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh//------------------------------------------------------------------------- 110bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh// Rest 111bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh//------------------------------------------------------------------------- 112bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 113bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalshvoid test(void) 114bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh{ 115bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh char *x1, *x2, *x3, *x4, *x5; 116bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 117bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh pool *p = make_pool(); 118bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 119bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh push(p); 120bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 121bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh x1 = allocate(p, 10); 122bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh x2 = allocate(p, 20); 123bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh push(p); 124bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh x3 = allocate(p, 10); 125bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh x4 = allocate(p, 20); 126bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 127bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh *x1 = 'a'; // valid 128bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh *x2 = 'b'; // valid 129bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 130bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh x1[-1] = 'h'; // invalid 131bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh x1[10] = 'i'; // invalid 132bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 133bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh pop(p); 134bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 135bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh *x3 = 'c'; // invalid 136bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh *x4 = 'd'; // invalid 137bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 138bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh *x1 = 'e'; // valid 139bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh *x2 = 'f'; // valid 140bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 141bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh x5 = allocate(p, 10); 142bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 143bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh *x5 = 'g'; // valid 144bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 145bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh // pop(p); 146bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 147bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh // *x5 = 'g'; // invalid 148bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 149bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh // destroy_pool(p); 150bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh} 151bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh 152bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalshint main(void) 153bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh{ 154bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh test(); 155bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh return 0; 156bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh} 157