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