Accidentally checked this file in...removing it now.
[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 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20
21 #include "dumpstructures.h"
22 #include "typedata.h"
23 #include "elf/dwarf2.h"
24 #include <string.h>
25
26 #define GETTYPE 1
27 #define POSTNAME 2
28 #define GETJUSTTYPE 3
29
30 int FOLLOW_PTRS=0;
31
32 int process_elf_binary_data(char* filename);
33
34 char *rootfile=NULL;
35
36 int main(int argc, char **argv) {
37   if (argc<2)
38     return 0;
39   if (argc>=3)
40     rootfile=argv[2];
41   if (argc==4&&(strcmp("-r",argv[3])==0))
42     FOLLOW_PTRS=1;
43
44   process_elf_binary_data(argv[1]);
45   daikon_preprocess_entry_array();
46 }
47
48 // Pre-processes global dwarf_entry_array in order to place
49 // the data in a form that can easily be turned into .decls
50 // and .dtrace files
51 void daikon_preprocess_entry_array()
52 {
53   initializeTypeArray();
54 }
55
56 int typecount=0;
57 int assigntype=0;
58 int entry_is_type(dwarf_entry *entry) {
59   if (entry->tag_name==DW_TAG_structure_type||
60       entry->tag_name==DW_TAG_union_type) {
61     collection_type* collection_ptr = (collection_type*)(entry->entry_ptr);
62     /*    if (collection_ptr->name==0&&assigntype) {
63       collection_ptr->name=(char*)malloc(100);
64       sprintf(collection_ptr->name,"TYPE%ld",typecount++);
65       }*/
66     return 1;
67   }
68   return 0;
69 }
70
71 int entry_is_valid_function(dwarf_entry *entry) {
72   if (tag_is_function(entry->tag_name)) {
73     function* funcPtr = (function*)(entry->entry_ptr);
74     if (funcPtr->start_pc != 0 && funcPtr->name != 0) {
75       return 1;
76     } else {
77 #ifdef SHOW_DEBUG
78       printf("Skipping invalid-looking function %s\n", funcPtr->name);
79 #endif
80     }
81   }
82   return 0;
83 }
84
85 struct valuepair {
86   int index;
87   int value;
88 };
89
90 void initializeTypeArray()
91 {
92   int i;
93   dwarf_entry * cur_entry;
94   struct genhashtable * ght=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
95   struct genhashtable * sht=NULL;
96
97   if (rootfile!=NULL) {
98     char buf[512];
99     char a;
100     int fd=open(rootfile,O_RDONLY);
101     int offset=0;
102     sht=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
103     while(1) {
104       if (read(fd,&a,1)>0) {
105         if (a!=13&&a!=10)
106           buf[offset++]=a;
107       } else
108           break;
109       if (offset>0&&(a==13||a==10)) {
110         buf[offset++]=0;
111         {
112           char *str=copystr(buf);
113           genputtable(sht,str,str);
114         }
115         offset=0;
116       }
117     }
118   }
119
120   for (i = 0; i < dwarf_entry_array_size; i++)
121     {
122       cur_entry = &dwarf_entry_array[i];
123       if (entry_is_type(cur_entry))
124         {
125           collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
126           int j=0;
127           int offset=0;
128           int value=0;
129           for(j=0;j<collection_ptr->num_members;j++) {
130             dwarf_entry *entry=collection_ptr->members[j];
131             if (entry->tag_name==DW_TAG_inheritance) {
132               value++;
133             } else {
134               member * member_ptr=(member *)entry->entry_ptr;
135               char *name=member_ptr->name;
136               dwarf_entry *type=member_ptr->type_ptr;
137               char *typestr=printname(type,GETTYPE);
138               char *poststr=printname(type,POSTNAME);
139
140               if (typestr!=NULL)
141                 value++;
142             }
143           }
144           if (collection_ptr->name!=NULL) {
145             struct valuepair *vp=NULL;
146             if (gencontains(ght,collection_ptr->name))
147               vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
148             if (vp==NULL||vp->value<value) {
149               if (vp==NULL) {
150                 vp=(struct valuepair*)calloc(1,sizeof(struct valuepair));
151                 genputtable(ght,collection_ptr->name,vp);
152               }
153               vp->value=value;
154               vp->index=i;
155             }
156           }
157         }
158     }
159
160   assigntype=1;
161   if (sht!=NULL) {
162     int repeat=1;
163     while(repeat) {
164       repeat=0;
165       for (i = 0; i < dwarf_entry_array_size; i++) {
166         cur_entry = &dwarf_entry_array[i];
167         if (entry_is_type(cur_entry)) {
168           collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
169           int j=0;
170           int offset=0;
171           int value=0;
172
173           if (!gencontains(sht,collection_ptr->name))
174             continue;
175           if (gencontains(ght,collection_ptr->name)) {
176             struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
177             if (vp->index!=i)
178               continue;
179           }
180
181           for(j=0;j<collection_ptr->num_members;j++) {
182             dwarf_entry *entry=collection_ptr->members[j];
183             if (entry->tag_name==DW_TAG_inheritance) {
184               inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
185               dwarf_entry *typeptr=in_ptr->target_ptr;
186               collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
187               if (!gencontains(sht,sub_ptr->name)) {
188                 repeat=1;
189                 genputtable(sht,sub_ptr->name,sub_ptr->name);
190               }
191             } else {
192               member * member_ptr=(member *)entry->entry_ptr;
193               char *name=member_ptr->name;
194               dwarf_entry *type=member_ptr->type_ptr;
195               char *typestr=printname(type,GETJUSTTYPE);
196               if (typestr!=NULL&&!gencontains(sht,typestr)) {
197                 repeat=1;
198                 genputtable(sht,typestr,typestr);
199               }
200             }
201           }
202         }
203       }
204     }
205   }
206
207
208   for (i = 0; i < dwarf_entry_array_size; i++)
209     {
210       cur_entry = &dwarf_entry_array[i];
211       if (entry_is_type(cur_entry))
212         {
213           collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
214           int j=0;
215           int offset=0;
216           if (collection_ptr->name==NULL)
217             continue;
218           if (sht!=NULL&&!gencontains(sht,collection_ptr->name))
219             continue;
220           if (gencontains(ght,collection_ptr->name)) {
221             struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
222             if (vp->index!=i)
223               continue;
224           }
225           j=0;
226           printf("structure %s ",collection_ptr->name);
227
228           while(j<collection_ptr->num_members&&
229                 collection_ptr->members[j]->tag_name==DW_TAG_inheritance) {
230             inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
231             dwarf_entry *typeptr=in_ptr->target_ptr;
232             collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
233             if (j==0)
234               printf("subclass of ");
235             else
236               printf(", ");
237             printf("%s ",sub_ptr->name);
238             j++;
239           }
240           printf("{ \n");
241
242           for(j=0;j<collection_ptr->num_members;j++) {
243             dwarf_entry *entry=collection_ptr->members[j];
244             if (entry->tag_name==DW_TAG_inheritance) {
245               inherit * inherit_ptr=(inherit *)entry->entry_ptr;
246               if (inherit_ptr->data_member_location>offset) {
247                 printf("   reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
248                 offset=inherit_ptr->data_member_location;
249               }
250               {
251                 dwarf_entry *type=inherit_ptr->target_ptr;
252                 collection_type *c_ptr=(collection_type*)type->entry_ptr;
253                 offset+=printtype(c_ptr,ght);
254               }
255             } else {
256               member * member_ptr=(member *)entry->entry_ptr;
257               char *name=member_ptr->name;
258               dwarf_entry *type=member_ptr->type_ptr;
259               char *typestr=printname(type,GETTYPE);
260               char *poststr=printname(type,POSTNAME);
261               char *newname=NULL;
262               if (member_ptr->data_member_location>offset) {
263                 printf("   reserved byte[%ld];\n",member_ptr->data_member_location-offset);
264                 offset=member_ptr->data_member_location;
265               }
266               offset+=getsize(type);
267               newname=escapestr(name);
268               printf("   %s %s%s;\n",typestr,newname,poststr);
269               free(newname);
270             }
271           }
272           if (offset<collection_ptr->byte_size)
273             printf("   reserved byte[%ld];\n",collection_ptr->byte_size-offset);
274           printf("}\n\n");
275         }
276     }
277 }
278
279 int printtype(collection_type *collection_ptr,struct genhashtable *ght)
280 {
281   int j=0;
282   int offset=0;
283   int value=0;
284
285   struct valuepair *vp=NULL;
286   if (gencontains(ght,collection_ptr->name))
287     vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
288   if (vp!=NULL)
289     collection_ptr=(collection_type*) dwarf_entry_array[vp->index].entry_ptr;
290
291   for(j=0;j<collection_ptr->num_members;j++) {
292     dwarf_entry *entry=collection_ptr->members[j];
293     if (entry->tag_name==DW_TAG_inheritance) {
294       inherit * inherit_ptr=(inherit *)entry->entry_ptr;
295       if (inherit_ptr->data_member_location>offset) {
296         printf("   reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
297         offset=inherit_ptr->data_member_location;
298       }
299
300       {
301         dwarf_entry *type=inherit_ptr->target_ptr;
302         collection_type *c_ptr=(collection_type*)type->entry_ptr;
303         offset+=printtype(c_ptr,ght);
304       }
305     } else {
306       member * member_ptr=(member *)entry->entry_ptr;
307       char *name=member_ptr->name;
308       char *newname=NULL;
309       dwarf_entry *type=member_ptr->type_ptr;
310       char *typestr=printname(type,GETTYPE);
311       char *poststr=printname(type,POSTNAME);
312       if (member_ptr->data_member_location>offset) {
313         printf("   reserved byte[%ld];\n",member_ptr->data_member_location-offset);
314         offset=member_ptr->data_member_location;
315       }
316       offset+=getsize(type);
317
318       newname=escapestr(name);
319       printf("   %s %s%s;\n",typestr,newname,poststr);
320       free(newname);
321     }
322   }
323   return offset;
324 }
325
326 int getsize(dwarf_entry *type) {
327   if (type==NULL)
328     return 0;
329   switch(type->tag_name) {
330   case DW_TAG_enumeration_type:
331     return 4;
332   case DW_TAG_array_type: {
333     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
334     int size=1;
335     int i;
336     for(i=0;i<modifier_ptr->num_array;i++) {
337       size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
338     }
339     return size*getsize(modifier_ptr->target_ptr);
340   }
341   case DW_TAG_const_type:
342     {
343       consttype * ctype_ptr=(consttype*)type->entry_ptr;
344       return getsize(ctype_ptr->target_ptr);
345     }
346     break;
347   case DW_TAG_base_type: {
348     base_type *base=(base_type*)type->entry_ptr;
349     return base->byte_size;
350   }
351   case DW_TAG_pointer_type: {
352     return 4;
353   }
354   case DW_TAG_union_type:
355   case DW_TAG_structure_type: {
356     collection_type *ctype=(collection_type*)type->entry_ptr;
357     return ctype->byte_size;
358   }
359   case DW_TAG_subroutine_type: {
360     return 4;
361   }
362   case DW_TAG_typedef:
363     {
364       tdef * tdef_ptr=(tdef*)type->entry_ptr;
365       return getsize(tdef_ptr->target_ptr);
366     }
367     break;
368
369   default:
370     return 0;
371   }
372 }
373
374 char * printname(dwarf_entry * type,int op) {
375   if (type==NULL) {
376     if (op==GETTYPE||op==GETJUSTTYPE)
377       return NULL;
378   }
379
380   switch(type->tag_name) {
381   case DW_TAG_enumeration_type:
382     if (op==GETTYPE)
383       return "int";
384     break;
385   case DW_TAG_array_type: {
386     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
387     if (op==GETTYPE||op==GETJUSTTYPE) {
388         char *typename=printname(modifier_ptr->target_ptr,op);
389         return typename;
390     } else if (op==POSTNAME) {
391       int i;
392       int size=1;
393       char *typename=printname(modifier_ptr->target_ptr,op);
394       char *newptr=(char *)malloc(200);
395       for(i=0;i<modifier_ptr->num_array;i++) {
396         size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
397       }
398       sprintf(newptr,"%s[%ld]",typename,size);
399       return newptr;
400     }
401   }
402     break;
403   case DW_TAG_const_type:
404     {
405       consttype * ctype_ptr=(consttype*)type->entry_ptr;
406       if (op==GETTYPE||op==GETJUSTTYPE) {
407         char *typename=printname(ctype_ptr->target_ptr,op);
408         return typename;
409       }
410     }
411     break;
412   case DW_TAG_subroutine_type: {
413     return "void";
414   }
415   case DW_TAG_typedef:
416     {
417       tdef * tdef_ptr=(tdef*)type->entry_ptr;
418       if (op==GETTYPE||op==GETJUSTTYPE) {
419         char *typename=printname(tdef_ptr->target_ptr,op);
420         return typename;
421       }
422     }
423     break;
424   case DW_TAG_base_type: {
425     base_type *base=(base_type*)type->entry_ptr;
426     if (op==GETTYPE)
427       switch(base->byte_size) {
428       case 1:
429         return "byte";
430       case 2:
431         return "short";
432       case 4:
433         return "int";
434       default: {
435         char *m=(char*)malloc(100);
436         sprintf(m,"error%ld",base->byte_size);
437         return m;
438       }
439       }
440   }
441     break;
442   case DW_TAG_pointer_type: {
443     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
444     if (op==GETTYPE) {
445       if (modifier_ptr->target_ptr==NULL)
446         return "void *"; /* seems like a good guess */
447       {
448         char *typename=printname(modifier_ptr->target_ptr,op);
449         /* evil hack */
450         char *newptr=(char *)malloc(200);
451         sprintf(newptr,"%s *",typename);
452         return newptr;
453       }
454     } else if (op==GETJUSTTYPE) {
455       if (!FOLLOW_PTRS)
456         return NULL;
457
458       if (modifier_ptr->target_ptr==NULL)
459         return NULL;
460       {
461         char *typename=printname(modifier_ptr->target_ptr,op);
462         return typename;
463       }
464     }
465   }
466     break;
467   case DW_TAG_union_type:
468   case DW_TAG_structure_type: {
469     collection_type *ctype=(collection_type*)type->entry_ptr;
470     if (op==GETTYPE&&ctype->name==NULL&&assigntype) {
471       ctype->name=(char*)malloc(100);
472       sprintf(ctype->name,"TYPE%ld",typecount++);
473     }
474     if (op==GETTYPE)
475       return ctype->name;
476     if (op==GETJUSTTYPE&&ctype->name==NULL&&assigntype) {
477       ctype->name=(char*)malloc(100);
478       sprintf(ctype->name,"TYPE%ld",typecount++);
479     }
480     if (op==GETJUSTTYPE)
481       return ctype->name;
482
483   }
484     break;
485   default:
486     if (op==GETTYPE) {
487       if (!assigntype)
488         return NULL;
489       else {
490         char * p=(char *)malloc(100);
491         sprintf(p,"0x%x",type->tag_name);
492         return p;
493       }
494     }
495   }
496   if (op==POSTNAME)
497     return "";
498   if (op==GETJUSTTYPE)
499     return NULL;
500   return "ERROR";
501 }