mymemory: kill system_free()
[model-checker.git] / mymemory.cc
1 #include "mymemory.h"
2 #include "snapshot.h"
3 #include "snapshotimp.h"
4 #include <stdio.h>
5 #include <dlfcn.h>
6 #include <unistd.h>
7 #include <cstring>
8 #include "common.h"
9 #define REQUESTS_BEFORE_ALLOC 1024
10 size_t allocatedReqs[ REQUESTS_BEFORE_ALLOC ] = { 0 };
11 int nextRequest = 0;
12 int howManyFreed = 0;
13 #if !USE_MPROTECT_SNAPSHOT
14 static mspace sStaticSpace = NULL;
15 #endif
16
17 /** Non-snapshotting calloc for our use. */
18 void *model_calloc(size_t count, size_t size) {
19 #if USE_MPROTECT_SNAPSHOT
20         static void *(*callocp)(size_t count, size_t size)=NULL;
21         char *error;
22         void *ptr;
23
24         /* get address of libc malloc */
25         if (!callocp) {
26                 callocp = ( void * ( * )( size_t, size_t ) )dlsym(RTLD_NEXT, "calloc");
27                 if ((error = dlerror()) != NULL) {
28                         fputs(error, stderr);
29                         exit(EXIT_FAILURE);
30                 }
31         }
32         ptr = callocp(count, size);
33         return ptr;
34 #else
35         if( !snapshotrecord) {
36                 createSharedMemory();
37         }
38         if( NULL == sStaticSpace )
39                 sStaticSpace = create_mspace_with_base( ( void * )( snapshotrecord->mSharedMemoryBase ), SHARED_MEMORY_DEFAULT -sizeof( struct SnapShot ), 1 );
40         return mspace_calloc( sStaticSpace, count, size );
41 #endif
42 }
43
44 /** Non-snapshotting malloc for our use. */
45 void *model_malloc(size_t size) {
46 #if USE_MPROTECT_SNAPSHOT
47         static void *(*mallocp)(size_t size)=NULL;
48         char *error;
49         void *ptr;
50
51         /* get address of libc malloc */
52         if (!mallocp) {
53                 mallocp = ( void * ( * )( size_t ) )dlsym(RTLD_NEXT, "malloc");
54                 if ((error = dlerror()) != NULL) {
55                         fputs(error, stderr);
56                         exit(EXIT_FAILURE);
57                 }
58         }
59         ptr = mallocp(size);
60         return ptr;
61 #else
62         if( !snapshotrecord) {
63                 createSharedMemory();
64         }
65         if( NULL == sStaticSpace )
66                 sStaticSpace = create_mspace_with_base( ( void * )( snapshotrecord->mSharedMemoryBase ), SHARED_MEMORY_DEFAULT -sizeof( struct SnapShot ), 1 );
67         return mspace_malloc( sStaticSpace, size );
68 #endif
69 }
70
71 /** @brief Snapshotting malloc, for use by model-checker (not user progs) */
72 void * snapshot_malloc(size_t size)
73 {
74         return malloc(size);
75 }
76
77 /** @brief Snapshotting calloc, for use by model-checker (not user progs) */
78 void * snapshot_calloc(size_t count, size_t size)
79 {
80         return calloc(count, size);
81 }
82
83 /** @brief Snapshotting free, for use by model-checker (not user progs) */
84 void snapshot_free(void *ptr)
85 {
86         free(ptr);
87 }
88
89 void *system_malloc( size_t size ){
90         static void *(*mallocp)(size_t size);
91         char *error;
92         void *ptr;
93
94         /* get address of libc malloc */
95         if (!mallocp) {
96                 mallocp = ( void * ( * )( size_t ) )dlsym(RTLD_NEXT, "malloc");
97                 if ((error = dlerror()) != NULL) {
98                         fputs(error, stderr);
99                         exit(EXIT_FAILURE);
100                 }
101         }
102         ptr = mallocp(size);
103         return ptr;
104 }
105
106 /** Non-snapshotting free for our use. */
107 void model_free(void *ptr) {
108 #if USE_MPROTECT_SNAPSHOT
109         static void (*freep)(void *);
110         char *error;
111
112         /* get address of libc free */
113         if (!freep) {
114                 freep = ( void  ( * )( void * ) )dlsym(RTLD_NEXT, "free");
115                 if ((error = dlerror()) != NULL) {
116                         fputs(error, stderr);
117                         exit(EXIT_FAILURE);
118                 }
119         }
120         freep(ptr);
121 #else
122         mspace_free( sStaticSpace, ptr );
123 #endif
124 }
125
126
127 /** @brief Global mspace reference for the snapshotting heap */
128 mspace mySpace = NULL;
129
130 /** Bootstrap allocation.  Problem is that the dynamic linker calls
131  *  require calloc to work and calloc requires the dynamic linker to
132  *      work.  */
133
134 #define BOOTSTRAPBYTES 4096
135 char bootstrapmemory[BOOTSTRAPBYTES];
136 size_t offset=0;
137
138 void * HandleEarlyAllocationRequest( size_t sz ){
139         /*Align to 8 byte boundary*/
140         sz=(sz+7)&~7;
141
142         if (sz > (BOOTSTRAPBYTES-offset)) {
143                 printf("OUT OF BOOTSTRAP MEMORY\n");
144                 exit(EXIT_FAILURE);
145         }
146
147         void * pointer= (void *) & bootstrapmemory[offset];
148         offset+=sz;
149         return pointer;
150 }
151
152 /** Check whether this is bootstrapped memory that we should not
153                 free. */
154
155 bool DontFree( void * ptr ){
156         return (ptr>=(&bootstrapmemory[0])&&ptr<(&bootstrapmemory[BOOTSTRAPBYTES]));
157 }
158
159 /** @brief Snapshotting malloc implementation for user programs */
160 void *malloc( size_t size )
161 {
162         if (mySpace) {
163                 void *tmp=mspace_malloc( mySpace, size );
164                 ASSERT(tmp);
165                 return tmp;
166         } else
167                 return HandleEarlyAllocationRequest( size );
168 }
169
170 /** @brief Snapshotting free implementation for user programs */
171 void free( void * ptr ){
172         if (!DontFree(ptr))
173                 mspace_free(mySpace, ptr);
174 }
175
176 /** @brief Snapshotting realloc implementation for user programs */
177 void *realloc( void *ptr, size_t size )
178 {
179         void *tmp = mspace_realloc(mySpace, ptr, size);
180         ASSERT(tmp);
181         return tmp;
182 }
183
184 /** @brief Snapshotting calloc implementation for user programs */
185 void * calloc( size_t num, size_t size )
186 {
187         if (mySpace) {
188                 void *tmp = mspace_calloc(mySpace, num, size);
189                 ASSERT(tmp);
190                 return tmp;
191         } else {
192                 void *tmp=HandleEarlyAllocationRequest( size * num );
193                 std::memset( tmp, 0, size * num );
194                 return tmp;
195         }
196 }
197
198 /** @brief Snapshotting new operator for user programs */
199 void * operator new(size_t size) throw(std::bad_alloc)
200 {
201         return malloc(size);
202 }
203
204 /** @brief Snapshotting delete operator for user programs */
205 void operator delete(void *p) throw()
206 {
207         free(p);
208 }
209
210 /** @brief Snapshotting new[] operator for user programs */
211 void * operator new[](size_t size) throw(std::bad_alloc)
212 {
213         return malloc(size);
214 }
215
216 /** @brief Snapshotting delete[] operator for user programs */
217 void operator delete[](void *p, size_t size)
218 {
219         free(p);
220 }