fixes to size computation.
[repair.git] / Repair / RepairCompiler / structextract / dumpstructures.c
1 /*
2    This file is part of Kvasir, a Valgrind skin that implements the
3    C language front-end for the Daikon Invariant Detection System
4
5    Copyright (C) 2004 Philip Guo, MIT CSAIL Program Analysis Group
6
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11 */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <ctype.h>
17
18 #include "dumpstructures.h"
19 #include "typedata.h"
20 #include "elf/dwarf2.h"
21
22
23 #define GETTYPE 1
24 #define POSTNAME 2
25
26 int process_elf_binary_data(char* filename);
27
28 int main(int argc, char **argv) {
29   if (argc<2)
30     return 0;
31   process_elf_binary_data(argv[1]);
32   daikon_preprocess_entry_array();
33 }
34
35 // Pre-processes global dwarf_entry_array in order to place
36 // the data in a form that can easily be turned into .decls
37 // and .dtrace files
38 void daikon_preprocess_entry_array()
39 {
40   initializeTypeArray();
41 }
42
43 int typecount=0;
44 int assigntype=0;
45 int entry_is_type(dwarf_entry *entry) {
46   if (entry->tag_name==DW_TAG_structure_type||
47       entry->tag_name==DW_TAG_union_type) {
48     collection_type* collection_ptr = (collection_type*)(entry->entry_ptr);
49     /*    if (collection_ptr->name==0&&assigntype) {
50       collection_ptr->name=(char*)malloc(100);
51       sprintf(collection_ptr->name,"TYPE%ld",typecount++);
52       }*/
53     return 1;
54   }
55   return 0;
56 }
57
58 int entry_is_valid_function(dwarf_entry *entry) {
59   if (tag_is_function(entry->tag_name)) {
60     function* funcPtr = (function*)(entry->entry_ptr);
61     if (funcPtr->start_pc != 0 && funcPtr->name != 0) {
62       return 1;
63     } else {
64 #ifdef SHOW_DEBUG
65       printf("Skipping invalid-looking function %s\n", funcPtr->name);
66 #endif
67     }
68   }
69   return 0;
70 }
71
72 struct valuepair {
73   int index;
74   int value;
75 };
76
77 void initializeTypeArray()
78 {
79   int i;
80   dwarf_entry * cur_entry;
81   struct genhashtable * ght=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
82   
83   for (i = 0; i < dwarf_entry_array_size; i++)
84     {
85       cur_entry = &dwarf_entry_array[i];
86       if (entry_is_type(cur_entry))
87         {
88           collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
89           int j=0;
90           int offset=0;
91           int value=0;
92           for(j=0;j<collection_ptr->num_members;j++) {
93             dwarf_entry *entry=collection_ptr->members[j];
94             if (entry->tag_name==DW_TAG_inheritance) {
95               value++;
96               continue;
97             }
98             {
99               member * member_ptr=(member *)entry->entry_ptr;
100               char *name=member_ptr->name;
101               dwarf_entry *type=member_ptr->type_ptr;
102               char *typestr=printname(type,GETTYPE);
103               char *poststr=printname(type,POSTNAME);
104               
105               if (typestr!=NULL)
106                 value++;
107             }
108           }
109           if (collection_ptr->name!=NULL) {
110             struct valuepair *vp=NULL;
111             if (gencontains(ght,collection_ptr->name))
112               vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
113             if (vp==NULL||vp->value<value) {
114               if (vp==NULL) {
115                 vp=(struct valuepair*)calloc(1,sizeof(struct valuepair));
116                 genputtable(ght,collection_ptr->name,vp);
117               }
118               vp->value=value;
119               vp->index=i;
120             }
121           }
122         }
123     }
124
125   assigntype=1;
126   for (i = 0; i < dwarf_entry_array_size; i++)
127     {
128       cur_entry = &dwarf_entry_array[i];
129       if (entry_is_type(cur_entry))
130         {
131           collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
132           int j=0;
133           int offset=0;
134           if (collection_ptr->name==NULL)
135             continue;
136           if (gencontains(ght,collection_ptr->name)) {
137             struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
138             if (vp->index!=i)
139               continue;
140           }
141           j=0;
142           printf("structure %s ",collection_ptr->name);
143
144           while(j<collection_ptr->num_members&&
145                 collection_ptr->members[j]->tag_name==DW_TAG_inheritance) {
146             inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
147             dwarf_entry *typeptr=in_ptr->target_ptr;
148             collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
149             if (j==0)
150               printf("subclasses ");
151             else
152               printf(", ");
153             printf("%s ",sub_ptr->name);
154             j++;
155           }
156           printf("{ \n");
157           
158           for(j=0;j<collection_ptr->num_members;j++) {
159             dwarf_entry *entry=collection_ptr->members[j];
160             if (entry->tag_name==DW_TAG_inheritance) {
161               inherit * inherit_ptr=(inherit *)entry->entry_ptr;
162               if (inherit_ptr->data_member_location>offset) {
163                 printf("   reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
164                 offset=inherit_ptr->data_member_location;
165               }
166               {
167                 dwarf_entry *type=inherit_ptr->target_ptr;
168                 collection_type *c_ptr=(collection_type*)type->entry_ptr;
169                 offset+=printtype(c_ptr,ght);
170               }
171             } else {
172               member * member_ptr=(member *)entry->entry_ptr;
173               char *name=member_ptr->name;
174               dwarf_entry *type=member_ptr->type_ptr;
175               char *typestr=printname(type,GETTYPE);
176               char *poststr=printname(type,POSTNAME);
177               if (member_ptr->data_member_location>offset) {
178                 printf("   reserved byte[%ld];\n",member_ptr->data_member_location-offset);
179                 offset=member_ptr->data_member_location;
180               }
181               offset+=getsize(type);
182               
183               printf("   %s %s%s;\n",typestr,name,poststr);
184             }
185           }
186           printf("}\n\n");
187         }
188     }
189 }
190
191 int printtype(collection_type *collection_ptr,struct genhashtable *ght)
192 {
193   int j=0;
194   int offset=0;
195   int value=0;
196   
197   struct valuepair *vp=NULL;
198   if (gencontains(ght,collection_ptr->name))
199     vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
200   if (vp!=NULL)
201     collection_ptr=(collection_type*) dwarf_entry_array[vp->index].entry_ptr;
202
203   for(j=0;j<collection_ptr->num_members;j++) {
204     dwarf_entry *entry=collection_ptr->members[j];
205     if (entry->tag_name==DW_TAG_inheritance) {
206       inherit * inherit_ptr=(inherit *)entry->entry_ptr;
207       if (inherit_ptr->data_member_location>offset) {
208         printf("   reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
209         offset=inherit_ptr->data_member_location;
210       }
211
212       {
213         dwarf_entry *type=inherit_ptr->target_ptr;
214         collection_type *c_ptr=(collection_type*)type->entry_ptr;
215         offset+=printtype(c_ptr,ght);
216       }
217     } else {
218       member * member_ptr=(member *)entry->entry_ptr;
219       char *name=member_ptr->name;
220       dwarf_entry *type=member_ptr->type_ptr;
221       char *typestr=printname(type,GETTYPE);
222       char *poststr=printname(type,POSTNAME);
223       if (member_ptr->data_member_location>offset) {
224         printf("   reserved byte[%ld];\n",member_ptr->data_member_location-offset);
225         offset=member_ptr->data_member_location;
226       }
227       offset+=getsize(type);
228       
229       printf("   %s %s%s;\n",typestr,name,poststr);
230     }
231   }
232   return offset;
233 }
234
235
236
237 int getsize(dwarf_entry *type) {
238   if (type==NULL)
239     return 0;
240   switch(type->tag_name) {
241   case DW_TAG_enumeration_type:
242     return 4;
243   case DW_TAG_array_type: {
244     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
245     int size=1;
246     int i;
247     for(i=0;i<modifier_ptr->num_array;i++) {
248       size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
249     }
250     return size*getsize(modifier_ptr->target_ptr);
251   }
252   case DW_TAG_const_type:
253     {
254       consttype * ctype_ptr=(consttype*)type->entry_ptr;
255       return getsize(ctype_ptr->target_ptr);
256     }
257     break;
258   case DW_TAG_base_type: {
259     base_type *base=(base_type*)type->entry_ptr;
260     return base->byte_size;
261   }
262   case DW_TAG_pointer_type: {
263     return 4;
264   }
265   case DW_TAG_union_type: 
266   case DW_TAG_structure_type: {
267     collection_type *ctype=(collection_type*)type->entry_ptr;
268     return ctype->byte_size;
269   }
270   case DW_TAG_subroutine_type: {
271     return 4;
272   }
273   case DW_TAG_typedef: 
274     {
275       tdef * tdef_ptr=(tdef*)type->entry_ptr;
276       return getsize(tdef_ptr->target_ptr);
277     }
278     break;
279
280   default:
281     return 0;
282   }
283 }
284
285 char * printname(dwarf_entry * type,int op) {
286   if (type==NULL) {
287     if (op==GETTYPE)
288       return NULL;
289   }
290
291   switch(type->tag_name) {
292   case DW_TAG_enumeration_type:
293     if (op==GETTYPE)
294       return "int";
295     break;
296   case DW_TAG_array_type: {
297     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
298     if (op==GETTYPE) {
299         char *typename=printname(modifier_ptr->target_ptr,op);
300         return typename;
301     } else if (op==POSTNAME) {
302       int i;
303       int size=1;
304       char *typename=printname(modifier_ptr->target_ptr,op);
305       char *newptr=(char *)malloc(200);
306       for(i=0;i<modifier_ptr->num_array;i++) {
307         size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
308       }
309       sprintf(newptr,"%s[%ld]",typename,size);
310       return newptr;
311     }
312   }
313     break;
314   case DW_TAG_const_type:
315     {
316       consttype * ctype_ptr=(consttype*)type->entry_ptr;
317       if (op==GETTYPE) {
318         char *typename=printname(ctype_ptr->target_ptr,op);
319         return typename;
320       }
321     }
322     break;
323   case DW_TAG_subroutine_type: {
324     return "void";
325   }
326   case DW_TAG_typedef: 
327     {
328       tdef * tdef_ptr=(tdef*)type->entry_ptr;
329       if (op==GETTYPE) {
330         char *typename=printname(tdef_ptr->target_ptr,op);
331         return typename;
332       }
333     }
334     break;
335   case DW_TAG_base_type: {
336     base_type *base=(base_type*)type->entry_ptr;
337     if (op==GETTYPE)
338       switch(base->byte_size) {
339       case 1:
340         return "byte";
341       case 2:
342         return "short";
343       case 4:
344         return "int";
345       default: {
346         char *m=(char*)malloc(100);
347         sprintf(m,"error%ld",base->byte_size);
348         return m;
349       }
350       }
351   }
352     break;
353   case DW_TAG_pointer_type: {
354     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
355     if (op==GETTYPE) {
356       if (modifier_ptr->target_ptr==NULL)
357         return "void *"; /* seems like a good guess */
358       {
359         char *typename=printname(modifier_ptr->target_ptr,op);
360         /* evil hack */
361         char *newptr=(char *)malloc(200);
362         sprintf(newptr,"%s *",typename);
363         return newptr;
364       }
365     }
366   }
367     break;
368   case DW_TAG_union_type:
369   case DW_TAG_structure_type: {
370     collection_type *ctype=(collection_type*)type->entry_ptr;
371     if (op==GETTYPE&&ctype->name==NULL&&assigntype) {
372       ctype->name=(char*)malloc(100);
373       sprintf(ctype->name,"TYPE%ld",typecount++);
374     }
375     if (op==GETTYPE)
376       return ctype->name;
377   }
378     break;
379   default:
380     if (op==GETTYPE) {
381       if (!assigntype)
382         return NULL;
383       else {
384         char * p=(char *)malloc(100);
385         sprintf(p,"0x%x",type->tag_name);
386         return p;
387       }
388     }
389   }
390   if (op==POSTNAME)
391     return "";
392   return "ERROR";
393 }
394
395