common: remove excess semicolon
[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 void system_free( void * ptr ){
107         static void (*freep)(void *);
108         char *error;
109
110         /* get address of libc free */
111         if (!freep) {
112                 freep = ( void  ( * )( void * ) )dlsym(RTLD_NEXT, "free");
113                 if ((error = dlerror()) != NULL) {
114                         fputs(error, stderr);
115                         exit(EXIT_FAILURE);
116                 }
117         }
118         freep(ptr);
119 }
120
121 /** Non-snapshotting free for our use. */
122 void model_free(void *ptr) {
123 #if USE_MPROTECT_SNAPSHOT
124         static void (*freep)(void *);
125         char *error;
126
127         /* get address of libc free */
128         if (!freep) {
129                 freep = ( void  ( * )( void * ) )dlsym(RTLD_NEXT, "free");
130                 if ((error = dlerror()) != NULL) {
131                         fputs(error, stderr);
132                         exit(EXIT_FAILURE);
133                 }
134         }
135         freep(ptr);
136 #else
137         mspace_free( sStaticSpace, ptr );
138 #endif
139 }
140
141
142 /** This global references the mspace for the snapshotting heap */
143 mspace mySpace = NULL;
144
145 /** This global references the unaligned memory address that was malloced for the snapshotting heap */
146 void * basemySpace = NULL;
147
148 /** Bootstrap allocation.  Problem is that the dynamic linker calls
149  *  require calloc to work and calloc requires the dynamic linker to
150  *      work.  */
151
152 #define BOOTSTRAPBYTES 4096
153 char bootstrapmemory[BOOTSTRAPBYTES];
154 size_t offset=0;
155
156 void * HandleEarlyAllocationRequest( size_t sz ){
157         /*Align to 8 byte boundary*/
158         sz=(sz+7)&~7;
159
160         if (sz > (BOOTSTRAPBYTES-offset)) {
161                 printf("OUT OF BOOTSTRAP MEMORY\n");
162                 exit(EXIT_FAILURE);
163         }
164
165         void * pointer= (void *) & bootstrapmemory[offset];
166         offset+=sz;
167         return pointer;
168 }
169
170 /** Check whether this is bootstrapped memory that we should not
171                 free. */
172
173 bool DontFree( void * ptr ){
174         return (ptr>=(&bootstrapmemory[0])&&ptr<(&bootstrapmemory[BOOTSTRAPBYTES]));
175 }
176
177 /** Snapshotting malloc implementation for user programs. */
178 void *malloc( size_t size ) {
179         if (mySpace) {
180                 void *tmp=mspace_malloc( mySpace, size );
181                 ASSERT(tmp);
182                 return tmp;
183         }       else
184                 return HandleEarlyAllocationRequest( size );
185 }
186
187 /** Snapshotting free implementation for user programs. */
188 void free( void * ptr ){
189         if( DontFree( ptr ) ) return;
190         mspace_free( mySpace, ptr );
191 }
192
193 /** Snapshotting realloc implementation for user programs. */
194 void *realloc( void *ptr, size_t size ){
195         void *tmp=mspace_realloc( mySpace, ptr, size );
196         ASSERT(tmp);
197         return tmp;
198 }
199
200 /** Snapshotting calloc implementation for user programs. */
201 void * calloc( size_t num, size_t size ){
202         if (mySpace) {
203                 void *tmp=mspace_calloc( mySpace, num, size );
204                 ASSERT(tmp);
205                 return tmp;
206         } else {
207                 void *tmp=HandleEarlyAllocationRequest( size * num );
208                 std::memset( tmp, 0, size * num );
209                 return tmp;
210         }
211 }
212
213 /** Snapshotting new operator for user programs. */
214 void * operator new(size_t size) throw(std::bad_alloc) {
215         return malloc(size);
216 }
217
218 /** Snapshotting delete operator for user programs. */
219 void operator delete(void *p) throw() {
220         free(p);
221 }
222
223 /** Snapshotting new[] operator for user programs. */
224 void * operator new[](size_t size) throw(std::bad_alloc) {
225         return malloc(size);
226 }
227
228 /** Snapshotting delete[] operator for user programs. */
229 void operator delete[](void *p, size_t size) {
230         free(p);
231 }