return flag to indicate errors
[repair.git] / Repair / RepairCompiler / MCC / CRuntime / tmap.c
1 #include <stdio.h>
2 #include "tmap.h"
3 #include "size.h"
4 #include "stack.h"
5 #include <stdlib.h>
6
7 #ifndef COMMANDLINEFLAGS
8 #define CHECKTYPE
9 #define CHECKMEMORY
10 #endif
11
12 struct typemap * allocatetypemap() {
13 #ifdef CHECKTYPE||CHECKMEMORY
14   struct typemap *thisvar=(struct typemap *) malloc(sizeof(struct typemap));
15   thisvar->alloctree=rbinit();
16   thisvar->typetree=rbinit();
17   thisvar->low=GC_linux_stack_base();
18   return thisvar;
19 #else
20   return NULL;
21 #endif
22 }
23
24 void freefunction(void *ptr) {
25   if(ptr!=NULL) {
26     freestructuremap((struct structuremap *)ptr);
27   }
28 }
29
30 void freetypemap(struct typemap * ptr) {
31   rbdestroy(ptr->typetree,freefunction);
32   rbdestroy(ptr->alloctree,freefunction);
33   free(ptr);
34 }
35
36 void typemapreset(struct typemap *ptr) {
37 #ifdef CHECKTYPE||CHECKMEMORY
38   rbdestroy(ptr->typetree,freefunction);
39   ptr->typetree=rbinit();
40   if (ptr->low<ptr->high)
41     rbdelete(ptr->low,ptr->alloctree);
42   else
43     rbdelete(ptr->high,ptr->alloctree);
44 #endif
45 }
46
47 void initializetypemapstack(struct typemap * ptr, void *high) {
48 #ifdef CHECKTYPE||CHECKMEMORY
49   ptr->high=high;
50   if (ptr->low<ptr->high)
51     rbinsert(ptr->low,ptr->high,NULL,ptr->alloctree);
52   else
53     rbinsert(ptr->high,ptr->low,NULL,ptr->alloctree);
54 #endif
55 }
56
57 struct structuremap * allocatestructuremap(int s) {
58   struct structuremap *ptr=(struct structuremap *)malloc(sizeof(struct structuremap));
59   ptr->str=s;
60   ptr->typetree=rbinit();
61   return ptr;
62 }
63
64 void freestructuremap(struct structuremap *ptr) {
65   rbdestroy(ptr->typetree,freefunction);
66   free(ptr);
67 }
68
69 bool typemapasserttype(struct typemap *thisvar, void *ptr, int s) {
70   int toadd=sizeBytes(s);
71   return typemapasserttypeB(thisvar, ptr,((char *) ptr)+toadd,s);
72 }
73
74 bool typemapasserttypeB(struct typemap * thisvar, void *ptr, void *high, int s) {
75 #ifdef CHECKTYPE
76   bool b=typemapchecktype(thisvar,true,ptr,s);
77   if (!b) {
78     printf("Assertion failure\n");
79     {
80       bool testb=typemapchecktype(thisvar,true,ptr,s);
81     }
82   }
83   return b;
84 #endif
85   return typemapassertvalidmemoryB(thisvar,ptr, high);
86 }
87
88 bool typemapassertvalidmemory(struct typemap * thisvar, void* low, int s) {
89   int toadd=sizeBytes(s);
90   return typemapassertvalidmemoryB(thisvar, low,((char *)low)+toadd);
91 }
92
93 bool typemapassertexactmemory(struct typemap * thisvar, void* low, int s) {
94   int toadd=sizeBytes(s);
95 #ifdef CHECKMEMORY
96   {
97     void * high=((char *)low)+toadd;
98     struct pair allocp=rbfind(low,high,thisvar->alloctree);
99     if (allocp.low == NULL) {
100       return false;
101     } else if ((allocp.low != low) || (allocp.high != high)) {
102     /* make sure this block exactly lines up */
103       return false;
104     } else {
105       return true;
106     }
107   }
108 #else
109   return true;
110 #endif
111 }
112
113 bool typemapassertvalidmemoryB(struct typemap * thisvar, void* low, void* high) {
114 #ifdef CHECKMEMORY
115   return typemapcheckmemory(thisvar, low, high);
116 #endif
117   return true;
118 }
119
120 bool typemapistype(struct typemap *thisvar, void *ptr, void *high, int s) {
121 #ifdef CHECKTYPE
122   bool b=typemapchecktype(thisvar, false,ptr,s);
123   if (!b) {
124     printf("Verify failure\n");
125     {
126       bool testb=typemapchecktype(thisvar, false,ptr,s);
127     }
128   }
129   return b;
130 #endif
131   return typemapassertvalidmemoryB(thisvar, ptr, high);
132 }
133
134 void typemapallocate(struct typemap *thisvar,void *ptr, int size) {
135   void *low=ptr;
136   void *high=((char *)ptr)+size;
137   int val=rbinsert(low,high,NULL,thisvar->alloctree);
138   if (val==0)
139     printf("Error\n");
140 }
141
142 inline int sizeinbytes(unsigned int bits) {
143   int bytes=bits>>3;
144   if (bits %8)
145     bytes++;
146   return bytes;
147 }
148
149 int typemapfindoffsetstructure(struct typemap * thisvar, int s, int offset) {
150   int count=0;
151   int i;
152   int increment;
153   for(i=0;i<getnumfields(s);i++) {
154     int mult=1;
155     int ttype=getfield(s,i);
156     if (isArray(s,i)) {
157       mult=numElements(s,i);
158     }
159     increment=size(ttype);
160     if (increment%8) {
161       int delt=offset-count;
162       int byteincrement=increment/8;
163       if (delt<mult*byteincrement) {
164         if (delt%byteincrement==0) {
165           return ttype;
166         } else
167           return -1;
168       }
169     } else {
170       if ((count+sizeinbytes(mult*increment))>offset)
171         return -1;
172     }
173     count+=sizeinbytes(mult*increment);
174   }
175   return -1;
176 }
177
178 void typemapdeallocate(struct typemap * thisvar,void *ptr) {
179   if (rbdelete(ptr,thisvar->alloctree)==NULL)
180     printf("Freeing unallocated memory\n");
181 }
182
183 bool typemapcheckmemory(struct typemap *thisvar, void* low, void* high) {
184   struct pair allocp=rbfind(low,high,thisvar->alloctree);
185   if (allocp.low == NULL) {
186     return false;
187   } else if ((allocp.low > low) || (allocp.high < high)) { /* make sure this block is used */
188     return false;
189   } else {
190     return true;
191   }
192 }
193
194 void * typemapgetendofblock(struct typemap *thisvar, void* low) {
195   struct pair allocp=rbfind(low,((char*)low)+1,thisvar->alloctree);
196   if (allocp.low == NULL) {
197     return NULL;
198   } else if ((allocp.low > low)||(allocp.high <= allocp.low)) { /* make sure this block is used */
199     return NULL;
200   } else {
201     return (void *)allocp.high;
202   }
203 }
204
205
206 bool typemapchecktype(struct typemap *thisvar, bool doaction,void *ptr, int structure) {
207   int ssize=sizeBytes(structure);
208   void *low=ptr;
209   void *high=((char *)low)+ssize;
210   struct pair allocp=rbfind(low,high,thisvar->alloctree);
211   if (allocp.low==NULL)
212     return false;
213   if (allocp.low>low||allocp.high<high) /* make sure this block is used */
214     return false;
215   {
216     struct pair typep=rbfind(low,high,thisvar->typetree);
217     struct structuremap *smap=(struct structuremap *)rblookup(low,high,thisvar->typetree);
218     if (typep.low==NULL) {
219       if(!doaction)
220         return true;
221       {
222         struct structuremap *sm=allocatestructuremap(structure);
223         int flag=rbinsert(low, high, sm, thisvar->typetree);
224         if (flag==0) {
225           printf("Error in asserttype\n");
226           return false;
227         } else
228           return true;
229       }
230     }
231     return typemapchecktypeB(thisvar, doaction, low,high, structure, thisvar->typetree);
232   }
233 }
234
235 bool typemapchecktypeB(struct typemap *thisvar, bool doaction, void *low, void *high, int structure, struct rbtree *ttree) {
236   struct pair typep=rbfind(low,high,ttree);
237   struct structuremap *smap=(struct structuremap *)rblookup(low,high,ttree);
238   if (typep.low==low&&typep.high==high) {
239     /* Recast */
240     if (issubtype(structure,smap->str)) {
241       /* narrowing cast */
242       if (!doaction)
243         return true;
244       smap->str=structure;
245       return true;
246     } else if (issubtype(smap->str,structure)) {
247       /* widening cast */
248       return true;
249     } else
250       return false; /* incompatible types */
251   } else if (typep.low<=low&&typep.high>=high) {
252     /* See if it matches up with structure inside typep */
253     if (rbsearch(low,high,smap->typetree)) {
254       /* recurse */
255       return typemapchecktypeB(thisvar,doaction,low,high, structure, smap->typetree);
256     } else {
257       /* check to see if data lines up correctly */
258       int offset=((char *)low)-((char *)typep.low);
259       int st=typemapfindoffsetstructure(thisvar, smap->str,offset);
260       if (st==-1)
261         return false;
262       if (issubtype(structure,st)) {
263         if (!doaction)
264           return true;
265         {
266           struct structuremap *newsm=allocatestructuremap(structure);
267           int flag=rbinsert(low, high, newsm, smap->typetree);
268           return (flag==1);
269         }
270       } else if (issubtype(st,structure)) {
271         if (!doaction)
272           return true;
273         {
274           struct structuremap *newsm=allocatestructuremap(st);
275           int flag=rbinsert(low, high, newsm, smap->typetree);
276           return (flag==1);
277         }
278       } else
279         return false;
280     }
281   } else
282     return false;
283 }