2b51bdc59c81e5f606abb3eb6944556ddf511d75
[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 #include "common.h"
22 #include "GenericHashtable.h"
23
24 #define GETTYPE 1
25 #define POSTNAME 2
26
27 int process_elf_binary_data(char* filename);
28
29 int main(int argc, char **argv) {
30   if (argc<2)
31     return 0;
32   process_elf_binary_data(argv[1]);
33   daikon_preprocess_entry_array();
34 }
35
36 // Pre-processes global dwarf_entry_array in order to place
37 // the data in a form that can easily be turned into .decls
38 // and .dtrace files
39 void daikon_preprocess_entry_array()
40 {
41   initializeTypeArray();
42 }
43
44 int typecount=0;
45 int assigntype=0;
46 int entry_is_type(dwarf_entry *entry) {
47   if (entry->tag_name==DW_TAG_structure_type||
48       entry->tag_name==DW_TAG_union_type) {
49     collection_type* collection_ptr = (collection_type*)(entry->entry_ptr);
50     /*    if (collection_ptr->name==0&&assigntype) {
51       collection_ptr->name=(char*)malloc(100);
52       sprintf(collection_ptr->name,"TYPE%ld",typecount++);
53       }*/
54     return 1;
55   }
56   return 0;
57 }
58
59 int entry_is_valid_function(dwarf_entry *entry) {
60   if (tag_is_function(entry->tag_name)) {
61     function* funcPtr = (function*)(entry->entry_ptr);
62     if (funcPtr->start_pc != 0 && funcPtr->name != 0) {
63       return 1;
64     } else {
65 #ifdef SHOW_DEBUG
66       printf("Skipping invalid-looking function %s\n", funcPtr->name);
67 #endif
68     }
69   }
70   return 0;
71 }
72
73 struct valuepair {
74   int index;
75   int value;
76 };
77
78 void initializeTypeArray()
79 {
80   int i;
81   dwarf_entry * cur_entry;
82   struct genhashtable * ght=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
83   
84   for (i = 0; i < dwarf_entry_array_size; i++)
85     {
86       cur_entry = &dwarf_entry_array[i];
87       if (entry_is_type(cur_entry))
88         {
89           collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
90           int j=0;
91           int offset=0;
92           int value=0;
93           for(j=0;j<collection_ptr->num_members;j++) {
94             dwarf_entry *entry=collection_ptr->members[j];
95             member * member_ptr=(member *)entry->entry_ptr;
96             char *name=member_ptr->name;
97             dwarf_entry *type=member_ptr->type_ptr;
98             char *typestr=printname(type,GETTYPE);
99             char *poststr=printname(type,POSTNAME);
100
101             if (typestr!=NULL)
102               value++;
103           }
104           if (collection_ptr->name!=NULL) {
105             struct valuepair *vp=NULL;
106             if (gencontains(ght,collection_ptr->name))
107               vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
108             if (vp==NULL||vp->value<value) {
109               vp=(struct valuepair*)calloc(1,sizeof(struct valuepair));
110               vp->value=value;
111               vp->index=i;
112               genputtable(ght,collection_ptr->name,vp);
113             }
114           }
115         }
116     }
117
118   assigntype=1;
119   for (i = 0; i < dwarf_entry_array_size; i++)
120     {
121       cur_entry = &dwarf_entry_array[i];
122       if (entry_is_type(cur_entry))
123         {
124           collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
125           int j=0;
126           int offset=0;
127           if (collection_ptr->name==NULL)
128             continue;
129           if (gencontains(ght,collection_ptr->name)) {
130             struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
131             if (vp->index!=i)
132               continue;
133           }
134           printf("structure %s {\n",collection_ptr->name);
135           
136           for(j=0;j<collection_ptr->num_members;j++) {
137             dwarf_entry *entry=collection_ptr->members[j];
138             member * member_ptr=(member *)entry->entry_ptr;
139             char *name=member_ptr->name;
140             dwarf_entry *type=member_ptr->type_ptr;
141             char *typestr=printname(type,GETTYPE);
142             char *poststr=printname(type,POSTNAME);
143             if (member_ptr->data_member_location>offset) {
144               printf("   reserved byte[%ld];\n",member_ptr->data_member_location-offset);
145               offset=member_ptr->data_member_location;
146             }
147             offset+=getsize(type);
148
149             printf("   %s %s%s;\n",typestr,name,poststr);
150           }
151           printf("}\n\n");
152         }
153     }
154 }
155
156 int getsize(dwarf_entry *type) {
157   if (type==NULL)
158     return 0;
159   switch(type->tag_name) {
160   case DW_TAG_enumeration_type:
161     return 4;
162   case DW_TAG_array_type: {
163     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
164     int size=((array_bound*)modifier_ptr->array_ptr[0]->entry_ptr)->upperbound+1;
165     return size*getsize(modifier_ptr->target_ptr);
166   }
167   case DW_TAG_base_type: {
168     base_type *base=(base_type*)type->entry_ptr;
169     return base->byte_size;
170   }
171   case DW_TAG_pointer_type: {
172     return 4;
173   }
174   case DW_TAG_structure_type: {
175     collection_type *ctype=(collection_type*)type->entry_ptr;
176     return ctype->byte_size;
177   }
178   default:
179     return 0;
180   }
181 }
182
183 char * printname(dwarf_entry * type,int op) {
184   if (type==NULL) {
185     if (op==GETTYPE)
186       return NULL;
187   }
188
189   switch(type->tag_name) {
190   case DW_TAG_enumeration_type:
191     if (op==GETTYPE)
192       return "int";
193     break;
194   case DW_TAG_array_type: {
195     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
196     if (op==GETTYPE) {
197         char *typename=printname(modifier_ptr->target_ptr,op);
198         return typename;
199     } else if (op==POSTNAME) {
200       int size=((array_bound*)modifier_ptr->array_ptr[0]->entry_ptr)->upperbound+1;
201       char *typename=printname(modifier_ptr->target_ptr,op);
202       char *newptr=(char *)malloc(200);
203       sprintf(newptr,"%s[%ld]",typename,size);
204       return newptr;
205     }
206   }
207     break;
208   case DW_TAG_const_type:
209     {
210       consttype * ctype_ptr=(consttype*)type->entry_ptr;
211       if (op==GETTYPE) {
212         char *typename=printname(ctype_ptr->target_ptr,op);
213         return typename;
214       }
215     }
216     break;
217   case DW_TAG_subroutine_type: {
218     return "void";
219   }
220   case DW_TAG_typedef: 
221     {
222       tdef * tdef_ptr=(tdef*)type->entry_ptr;
223       if (op==GETTYPE) {
224         char *typename=printname(tdef_ptr->target_ptr,op);
225         return typename;
226       }
227     }
228     break;
229   case DW_TAG_base_type: {
230     base_type *base=(base_type*)type->entry_ptr;
231     if (op==GETTYPE)
232       switch(base->byte_size) {
233       case 1:
234         return "byte";
235       case 2:
236         return "short";
237       case 4:
238         return "int";
239       default: {
240         char *m=(char*)malloc(100);
241         sprintf(m,"error%ld",base->byte_size);
242         return m;
243       }
244       }
245   }
246     break;
247   case DW_TAG_pointer_type: {
248     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
249     if (op==GETTYPE) {
250       if (modifier_ptr->target_ptr==NULL)
251         return "void *"; /* seems like a good guess */
252       {
253         char *typename=printname(modifier_ptr->target_ptr,op);
254         /* evil hack */
255         char *newptr=(char *)malloc(200);
256         sprintf(newptr,"%s *",typename);
257         return newptr;
258       }
259     }
260   }
261     break;
262   case DW_TAG_union_type:
263   case DW_TAG_structure_type: {
264     collection_type *ctype=(collection_type*)type->entry_ptr;
265     if (op==GETTYPE&&ctype->name==NULL&&assigntype) {
266       ctype->name=(char*)malloc(100);
267       sprintf(ctype->name,"TYPE%ld",typecount++);
268     }
269     if (op==GETTYPE)
270       return ctype->name;
271   }
272     break;
273   default:
274     if (op==GETTYPE) {
275       if (!assigntype)
276         return NULL;
277       else {
278         char * p=(char *)malloc(100);
279         sprintf(p,"0x%x",type->tag_name);
280         return p;
281       }
282     }
283   }
284   if (op==POSTNAME)
285     return "";
286   return "ERROR";
287 }
288
289