correct
[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 struct genhashtable * arrayt=NULL;
32 struct genhashtable * arraytype=NULL;
33 int process_elf_binary_data(char* filename);
34
35 char *rootfile=NULL;
36 char *arrayfile=NULL;
37
38 int main(int argc, char **argv) {
39   int i;
40   if (argc<2)
41     return 1;
42   if (argc>=3)
43     rootfile=argv[2];
44   for(i=3;i<argc;i++) {
45     if (strcmp("-r",argv[i])==0)
46       FOLLOW_PTRS=1;
47     if (strcmp("-a",argv[i])==0) {
48       i++;
49       arrayfile=argv[i];
50     }
51   }
52   process_elf_binary_data(argv[1]);
53   daikon_preprocess_entry_array();
54   return 0;
55 }
56
57 // Pre-processes global dwarf_entry_array in order to place
58 // the data in a form that can easily be turned into .decls
59 // and .dtrace files
60 void daikon_preprocess_entry_array()
61 {
62   initializeTypeArray();
63 }
64
65 int typecount=0;
66 int assigntype=1;
67 int entry_is_type(dwarf_entry *entry) {
68   if (entry->tag_name==DW_TAG_structure_type||
69       entry->tag_name==DW_TAG_union_type) {
70     collection_type* collection_ptr = (collection_type*)(entry->entry_ptr);
71     /*    if (collection_ptr->name==0&&assigntype) {
72       collection_ptr->name=(char*)malloc(100);
73       sprintf(collection_ptr->name,"TYPE%ld",typecount++);
74       }*/
75     return 1;
76   }
77   return 0;
78 }
79
80 int entry_is_valid_function(dwarf_entry *entry) {
81   if (tag_is_function(entry->tag_name)) {
82     function* funcPtr = (function*)(entry->entry_ptr);
83     if (funcPtr->start_pc != 0 && funcPtr->name != 0) {
84       return 1;
85     } else {
86 #ifdef SHOW_DEBUG
87       printf("Skipping invalid-looking function %s\n", funcPtr->name);
88 #endif
89     }
90   }
91   return 0;
92 }
93
94 struct valuepair {
95   int index;
96   int value;
97 };
98
99 void initializeTypeArray()
100 {
101   int i;
102   dwarf_entry * cur_entry;
103   struct genhashtable * ght=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
104   struct genhashtable * sht=NULL;
105
106   if (rootfile!=NULL) {
107     char buf[512];
108     char a;
109     int fd=open(rootfile,O_RDONLY);
110     int offset=0;
111     sht=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
112     while(1) {
113       if (read(fd,&a,1)>0) {
114         if (a!=13&&a!=10)
115           buf[offset++]=a;
116       } else
117           break;
118       if (offset>0&&(a==13||a==10)) {
119         buf[offset++]=0;
120         {
121           char *str=copystr(buf);
122           genputtable(sht,str,str);
123         }
124         offset=0;
125       }
126     }
127   }
128
129   if (arrayfile!=NULL) {
130     char buf[512];
131     char sizebuf[512];
132     char a;
133     int fd=open(arrayfile,O_RDONLY);
134     int offset=0;
135     int readmore=1;
136     int state=0;
137     arrayt=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
138     arraytype=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
139     while(readmore) {
140       if (read(fd,&a,1)<=0)
141         readmore=0;
142       if (readmore) {
143         if (a==' ') {
144           state=1;
145           buf[offset]=0;
146           offset=0;
147         } else if (a!=13&&a!=10) {
148           if (state==0)
149             buf[offset++]=a;
150           else
151             sizebuf[offset++]=a;
152         }
153       }
154       if ((state==1)&&offset>0&&(a==13||a==10||!readmore)) {
155         state=0;
156         sizebuf[offset]=0;
157         {
158           char *str=copystr(buf);
159           char *sizestr=copystr(sizebuf);
160           genputtable(arrayt,str,sizestr);
161         }
162         offset=0;
163       }
164     }
165   }
166
167   /* Assign names */
168   for (i = 0; i < dwarf_entry_array_size; i++)
169     {
170       cur_entry = &dwarf_entry_array[i];
171       if (entry_is_type(cur_entry))
172         {
173           collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
174           int j=0;
175           int offset=0;
176           int value=0;
177           
178           for(j=0;j<collection_ptr->num_members;j++) {
179             dwarf_entry *entry=collection_ptr->members[j];
180             if (entry->tag_name==DW_TAG_inheritance) {
181               value++;
182             } else {
183               member * member_ptr=(member *)entry->entry_ptr;
184               char *name=member_ptr->name;
185               dwarf_entry *type=member_ptr->type_ptr;
186               char *typestr=printname(type,GETTYPE);
187               char *poststr=printname(type,POSTNAME);
188
189               if (typestr!=NULL)
190                 value++;
191             }
192           }
193         }
194     }
195
196   for (i = 0; i < dwarf_entry_array_size; i++)
197     {
198       cur_entry = &dwarf_entry_array[i];
199       if (entry_is_type(cur_entry))
200         {
201           collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
202           int j=0;
203           int offset=0;
204           int value=0;
205           
206           for(j=0;j<collection_ptr->num_members;j++) {
207             dwarf_entry *entry=collection_ptr->members[j];
208             if (entry->tag_name==DW_TAG_inheritance) {
209               value++;
210             } else {
211               member * member_ptr=(member *)entry->entry_ptr;
212               char *name=member_ptr->name;
213               dwarf_entry *type=member_ptr->type_ptr;
214               char *typestr=printname(type,GETTYPE);
215               char *poststr=printname(type,POSTNAME);
216
217               if (typestr!=NULL)
218                 value++;
219             }
220           }
221
222           if (collection_ptr->name!=NULL) {
223             struct valuepair *vp=NULL;
224             if (gencontains(ght,collection_ptr->name))
225               vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
226             if (vp==NULL||vp->value<value) {
227               if (vp==NULL) {
228                 vp=(struct valuepair*)calloc(1,sizeof(struct valuepair));
229                 genputtable(ght,collection_ptr->name,vp);
230               }
231               vp->value=value;
232               vp->index=i;
233             }
234           }
235         }
236     }
237
238   assigntype=1;
239   if (sht!=NULL) {
240     int repeat=1;
241     while(repeat) {
242       repeat=0;
243       for (i = 0; i < dwarf_entry_array_size; i++) {
244         cur_entry = &dwarf_entry_array[i];
245         if (entry_is_type(cur_entry)) {
246           collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
247
248           int j=0;
249           int offset=0;
250           int value=0;
251
252           if (!gencontains(sht,collection_ptr->name))
253             continue;
254           if (gencontains(ght,collection_ptr->name)) {
255             struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
256             if (vp->index!=i)
257               continue;
258           }
259
260           for(j=0;j<collection_ptr->num_members;j++) {
261             dwarf_entry *entry=collection_ptr->members[j];
262             if (entry->tag_name==DW_TAG_inheritance) {
263               inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
264               dwarf_entry *typeptr=in_ptr->target_ptr;
265               collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
266               if (!gencontains(sht,sub_ptr->name)) {
267                 repeat=1;
268                 genputtable(sht,sub_ptr->name,sub_ptr->name);
269               }
270             } else {
271               member * member_ptr=(member *)entry->entry_ptr;
272               char *name=member_ptr->name;
273               dwarf_entry *type=member_ptr->type_ptr;
274               char *typestr=printname(type,GETJUSTTYPE);
275               if (typestr!=NULL&&!gencontains(sht,typestr)) {
276                 repeat=1;
277                 genputtable(sht,typestr,typestr);
278               }
279             }
280           }
281         }
282       }
283     }
284   }
285
286
287   for (i = 0; i < dwarf_entry_array_size; i++)
288     {
289       cur_entry = &dwarf_entry_array[i];
290       if (entry_is_type(cur_entry))
291         {
292           collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
293           int j=0;
294           int offset=0;
295           if (collection_ptr->name==NULL)
296             continue;
297           if (sht!=NULL&&!gencontains(sht,collection_ptr->name))
298             continue;
299           if (gencontains(ght,collection_ptr->name)) {
300             struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
301             if (vp->index!=i)
302               continue;
303           }
304           j=0;
305           printf("structure %s ",collection_ptr->name);
306
307           while(j<collection_ptr->num_members&&
308                 collection_ptr->members[j]->tag_name==DW_TAG_inheritance) {
309             inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
310             dwarf_entry *typeptr=in_ptr->target_ptr;
311             collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
312             if (j==0)
313               printf("subclass of ");
314             else
315               printf(", ");
316             printf("%s ",sub_ptr->name);
317             j++;
318           }
319           printf("{ \n");
320
321           for(j=0;j<collection_ptr->num_members;j++) {
322             dwarf_entry *entry=collection_ptr->members[j];
323             if (entry->tag_name==DW_TAG_inheritance) {
324               inherit * inherit_ptr=(inherit *)entry->entry_ptr;
325               if (inherit_ptr->data_member_location>offset) {
326                 printf("   reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
327                 offset=inherit_ptr->data_member_location;
328               }
329               {
330                 dwarf_entry *type=inherit_ptr->target_ptr;
331                 collection_type *c_ptr=(collection_type*)type->entry_ptr;
332                 offset+=printtype(c_ptr,ght);
333               }
334             } else {
335               member * member_ptr=(member *)entry->entry_ptr;
336               char *name=member_ptr->name;
337               dwarf_entry *type=member_ptr->type_ptr;
338               char *typestr=printname(type,GETTYPE);
339               char *poststr=printname(type,POSTNAME);
340               char *newname=NULL;
341               if (member_ptr->data_member_location>offset) {
342                 printf("   reserved byte[%ld];\n",member_ptr->data_member_location-offset);
343                 offset=member_ptr->data_member_location;
344               }
345               offset+=getsize(type);
346               newname=escapestr(name);
347               {
348                 char buf[512];
349                 char *dtype;
350                 sprintf(buf, "%s.%s\0", collection_ptr->name,newname);
351                 if (arrayt!=NULL&&gencontains(arrayt, &buf)) {
352                   genputtable(arraytype, copystr(buf), typestr);
353                   dtype=deref(typestr);
354                   printf("   %s_array * %s%s;\n",dtype,newname,poststr);
355                   free(dtype);
356                 } else
357                   printf("   %s %s%s;\n",typestr,newname,poststr);
358               }
359               free(newname);
360             }
361           }
362           if (offset<collection_ptr->byte_size)
363             printf("   reserved byte[%ld];\n",collection_ptr->byte_size-offset);
364           printf("}\n\n");
365         }
366     }
367   if (arrayt!=NULL) {
368     struct geniterator * gi=gengetiterator(arrayt);
369     while(1) {
370       char * str=(char *)gennext(gi);
371       char *size=NULL;
372       char *typestr=NULL;
373       if (str==NULL)
374         break;
375
376       size=(char *)gengettable(arrayt,str);
377       typestr=deref((char *)gengettable(arraytype,str));
378
379       printf("structure %s_array {\n",typestr);
380       printf("  %s elem[%s];\n",typestr,size);
381       printf("}\n");
382       free(typestr);
383     }
384     genfreeiterator(gi);
385   }
386
387 }
388
389 int printtype(collection_type *collection_ptr,struct genhashtable *ght)
390 {
391   int j=0;
392   int offset=0;
393   int value=0;
394
395   struct valuepair *vp=NULL;
396   if (gencontains(ght,collection_ptr->name))
397     vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
398   if (vp!=NULL)
399     collection_ptr=(collection_type*) dwarf_entry_array[vp->index].entry_ptr;
400
401   for(j=0;j<collection_ptr->num_members;j++) {
402     dwarf_entry *entry=collection_ptr->members[j];
403     if (entry->tag_name==DW_TAG_inheritance) {
404       inherit * inherit_ptr=(inherit *)entry->entry_ptr;
405       if (inherit_ptr->data_member_location>offset) {
406         printf("   reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
407         offset=inherit_ptr->data_member_location;
408       }
409
410       {
411         dwarf_entry *type=inherit_ptr->target_ptr;
412         collection_type *c_ptr=(collection_type*)type->entry_ptr;
413         offset+=printtype(c_ptr,ght);
414       }
415     } else {
416       member * member_ptr=(member *)entry->entry_ptr;
417       char *name=member_ptr->name;
418       char *newname=NULL;
419       dwarf_entry *type=member_ptr->type_ptr;
420       char *typestr=printname(type,GETTYPE);
421       char *poststr=printname(type,POSTNAME);
422       if (member_ptr->data_member_location>offset) {
423         printf("   reserved byte[%ld];\n",member_ptr->data_member_location-offset);
424         offset=member_ptr->data_member_location;
425       }
426       offset+=getsize(type);
427
428       newname=escapestr(name);
429       {
430         char buf[512];
431         char *dtype;
432         sprintf(buf, "%s.%s\0", collection_ptr->name,newname);
433         if (arrayt!=NULL&&gencontains(arrayt, &buf)) {
434           genputtable(arraytype, buf, typestr);
435           dtype=deref(typestr);
436           printf("   %s_array * %s%s;\n",dtype,newname,poststr);
437           free(dtype);
438         } else
439           printf("   %s %s%s;\n",typestr,newname,poststr);
440       }
441       free(newname);
442     }
443   }
444   return offset;
445 }
446
447 int getsize(dwarf_entry *type) {
448   if (type==NULL)
449     return 0;
450   switch(type->tag_name) {
451   case DW_TAG_enumeration_type:
452     return 4;
453   case DW_TAG_array_type: {
454     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
455     int size=1;
456     int i;
457     for(i=0;i<modifier_ptr->num_array;i++) {
458       size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
459     }
460     return size*getsize(modifier_ptr->target_ptr);
461   }
462   case DW_TAG_const_type:
463     {
464       consttype * ctype_ptr=(consttype*)type->entry_ptr;
465       return getsize(ctype_ptr->target_ptr);
466     }
467     break;
468   case DW_TAG_base_type: {
469     base_type *base=(base_type*)type->entry_ptr;
470     return base->byte_size;
471   }
472   case DW_TAG_pointer_type: {
473     return 4;
474   }
475   case DW_TAG_union_type:
476   case DW_TAG_structure_type: {
477     collection_type *ctype=(collection_type*)type->entry_ptr;
478     return ctype->byte_size;
479   }
480   case DW_TAG_subroutine_type: {
481     return 4;
482   }
483   case DW_TAG_typedef:
484     {
485       tdef * tdef_ptr=(tdef*)type->entry_ptr;
486       return getsize(tdef_ptr->target_ptr);
487     }
488     break;
489
490   default:
491     return 0;
492   }
493 }
494
495 char * deref(char *name) {
496   char *str=copystr(name);
497   char *initstr=str;
498   for(;(*str)!=0;str++)
499     ;
500   for(;(str!=initstr)&&((*str)!='*');str--)
501     ;
502   if ((*str)=='*') {
503     (*str)=0;
504     str--;
505     for(;(str!=initstr)&&((*str)==' ');str--)
506       (*str)=0;
507   }
508   return initstr;
509 }
510
511 char * printname(dwarf_entry * type,int op) {
512   if (type==NULL) {
513     if (op==GETTYPE||op==GETJUSTTYPE)
514       return NULL;
515   }
516
517   switch(type->tag_name) {
518   case DW_TAG_enumeration_type:
519     if (op==GETTYPE)
520       return "int";
521     break;
522   case DW_TAG_array_type: {
523     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
524     if (op==GETTYPE||op==GETJUSTTYPE) {
525         char *typename=printname(modifier_ptr->target_ptr,op);
526         return typename;
527     } else if (op==POSTNAME) {
528       int i;
529       int size=1;
530       char *typename=printname(modifier_ptr->target_ptr,op);
531       char *newptr=(char *)malloc(200);
532       for(i=0;i<modifier_ptr->num_array;i++) {
533         size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
534       }
535       sprintf(newptr,"%s[%ld]",typename,size);
536       return newptr;
537     }
538   }
539     break;
540   case DW_TAG_const_type:
541     {
542       consttype * ctype_ptr=(consttype*)type->entry_ptr;
543       if (op==GETTYPE||op==GETJUSTTYPE) {
544         char *typename=printname(ctype_ptr->target_ptr,op);
545         return typename;
546       }
547     }
548     break;
549   case DW_TAG_subroutine_type: {
550     return "void";
551   }
552   case DW_TAG_typedef:
553     {
554       tdef * tdef_ptr=(tdef*)type->entry_ptr;
555       if (op==GETTYPE||op==GETJUSTTYPE) {
556         if (tdef_ptr->target_ptr==NULL)
557           return tdef_ptr->name;
558         if (tdef_ptr->target_ptr->tag_name==DW_TAG_union_type||
559             tdef_ptr->target_ptr->tag_name==DW_TAG_structure_type) {
560           collection_type *ctype=(collection_type*)tdef_ptr->target_ptr->entry_ptr;
561           if (ctype->name!=NULL)
562             return ctype->name;
563           ctype->name=tdef_ptr->name;
564           return tdef_ptr->name;
565         }
566         char *typename=printname(tdef_ptr->target_ptr,op);
567         return typename;
568       }
569     }
570     break;
571   case DW_TAG_base_type: {
572     base_type *base=(base_type*)type->entry_ptr;
573     if (op==GETTYPE)
574       switch(base->byte_size) {
575       case 1:
576         return "byte";
577       case 2:
578         return "short";
579       case 4:
580         return "int";
581       default: {
582         char *m=(char*)malloc(100);
583         sprintf(m,"error%ld",base->byte_size);
584         return m;
585       }
586       }
587   }
588     break;
589   case DW_TAG_pointer_type: {
590     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
591     if (op==GETTYPE) {
592       if (modifier_ptr->target_ptr==NULL)
593         return "void *"; /* seems like a good guess */
594       {
595         char *typename=printname(modifier_ptr->target_ptr,op);
596         /* evil hack */
597         char *newptr=(char *)malloc(200);
598         sprintf(newptr,"%s *",typename);
599         return newptr;
600       }
601     } else if (op==GETJUSTTYPE) {
602       if (!FOLLOW_PTRS)
603         return NULL;
604
605       if (modifier_ptr->target_ptr==NULL)
606         return NULL;
607       {
608         char *typename=printname(modifier_ptr->target_ptr,op);
609         return typename;
610       }
611     }
612   }
613     break;
614   case DW_TAG_union_type:
615   case DW_TAG_structure_type: {
616     collection_type *ctype=(collection_type*)type->entry_ptr;
617     if (op==GETTYPE&&ctype->name==NULL&&assigntype) {
618       char *newb=(char *)malloc(1000);
619       int newchars=0;
620       int i;
621       ctype->name=newb;
622       newchars=sprintf(newb,"unnamed_",type->ID);
623       newb+=newchars;
624       for(i=0;i<ctype->num_members;i++) {
625         dwarf_entry * de=ctype->members[i];
626         if (de->tag_name==DW_TAG_member) {
627           member * me=(member *)de->entry_ptr;
628           newchars=sprintf(newb,"%s",me->name);
629           newb+=newchars;
630         }
631       }
632     }
633     if (op==GETTYPE)
634       return ctype->name;
635     if (op==GETJUSTTYPE&&ctype->name==NULL&&assigntype) {
636       char *newb=(char *)malloc(1000);
637       int newchars=0;
638       int i;
639       ctype->name=newb;
640       newchars=sprintf(newb,"unnamed_",type->ID);
641       newb+=newchars;
642       for(i=0;i<ctype->num_members;i++) {
643         dwarf_entry * de=ctype->members[i];
644         if (de->tag_name==DW_TAG_member) {
645           member * me=(member *)de->entry_ptr;
646           newchars=sprintf(newb,"%s",me->name);
647           newb+=newchars;
648         }
649       }
650     }
651     if (op==GETJUSTTYPE)
652       return ctype->name;
653
654   }
655     break;
656   default:
657     if (op==GETTYPE) {
658       if (!assigntype)
659         return NULL;
660       else {
661         char * p=(char *)malloc(100);
662         sprintf(p,"0x%x",type->tag_name);
663         return p;
664       }
665     }
666   }
667   if (op==POSTNAME)
668     return "";
669   if (op==GETJUSTTYPE)
670     return NULL;
671   return "ERROR";
672 }