missing change
[c11tester.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 void *system_malloc( size_t size ){
72         static void *(*mallocp)(size_t size);
73         char *error;
74         void *ptr;
75
76         /* get address of libc malloc */
77         if (!mallocp) {
78                 mallocp = ( void * ( * )( size_t ) )dlsym(RTLD_NEXT, "malloc");
79                 if ((error = dlerror()) != NULL) {
80                         fputs(error, stderr);
81                         exit(EXIT_FAILURE);
82                 }
83         }
84         ptr = mallocp(size);
85         return ptr;
86 }
87
88 void system_free( void * ptr ){
89         static void (*freep)(void *);
90         char *error;
91
92         /* get address of libc free */
93         if (!freep) {
94                 freep = ( void  ( * )( void * ) )dlsym(RTLD_NEXT, "free");
95                 if ((error = dlerror()) != NULL) {
96                         fputs(error, stderr);
97                         exit(EXIT_FAILURE);
98                 }
99         }
100         freep(ptr);
101 }
102
103 /** Non-snapshotting free for our use. */
104 void model_free(void *ptr) {
105 #if USE_MPROTECT_SNAPSHOT
106         static void (*freep)(void *);
107         char *error;
108
109         /* get address of libc free */
110         if (!freep) {
111                 freep = ( void  ( * )( void * ) )dlsym(RTLD_NEXT, "free");
112                 if ((error = dlerror()) != NULL) {
113                         fputs(error, stderr);
114                         exit(EXIT_FAILURE);
115                 }
116         }
117         freep(ptr);
118 #else
119         mspace_free( sStaticSpace, ptr );
120 #endif
121 }
122
123
124 /** This global references the mspace for the snapshotting heap */
125 mspace mySpace = NULL;
126
127 /** This global references the unaligned memory address that was malloced for the snapshotting heap */
128 void * basemySpace = 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 /** Snapshotting malloc implementation for user programs. */
160 void *malloc( size_t size ) {
161         if (mySpace) {
162                 void *tmp=mspace_malloc( mySpace, size );
163                 ASSERT(tmp);
164                 return tmp;
165         }       else
166                 return HandleEarlyAllocationRequest( size );
167 }
168
169 /** Snapshotting free implementation for user programs. */
170 void free( void * ptr ){
171         if( DontFree( ptr ) ) return;
172         mspace_free( mySpace, ptr );
173 }
174
175 /** Snapshotting realloc implementation for user programs. */
176 void *realloc( void *ptr, size_t size ){
177         void *tmp=mspace_realloc( mySpace, ptr, size );
178         ASSERT(tmp);
179         return tmp;
180 }
181
182 /** Snapshotting calloc implementation for user programs. */
183 void * calloc( size_t num, size_t size ){
184         if (mySpace) {
185                 void *tmp=mspace_calloc( mySpace, num, size );
186                 ASSERT(tmp);
187                 return tmp;
188         } else {
189                 void *tmp=HandleEarlyAllocationRequest( size * num );
190                 std::memset( tmp, 0, size * num );
191                 return tmp;
192         }
193 }
194
195 /** Snapshotting new operator for user programs. */
196 void * operator new(size_t size) throw(std::bad_alloc) {
197         return malloc(size);
198 }
199
200 /** Snapshotting delete operator for user programs. */
201 void operator delete(void *p) throw() {
202         free(p);
203 }
204
205 /** Snapshotting new[] operator for user programs. */
206 void * operator new[](size_t size) throw(std::bad_alloc) {
207         return malloc(size);
208 }
209
210 /** Snapshotting delete[] operator for user programs. */
211 void operator delete[](void *p, size_t size) {
212         free(p);
213 }