2 This file is part of Kvasir, a Valgrind skin that implements the
3 C language front-end for the Daikon Invariant Detection System
5 Copyright (C) 2004 Philip Guo, MIT CSAIL Program Analysis Group
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.
17 #include <sys/types.h>
21 #include "dumpstructures.h"
23 #include "elf/dwarf2.h"
31 struct genhashtable * arrayt=NULL;
32 struct genhashtable * arraytype=NULL;
33 int process_elf_binary_data(char* filename);
38 int main(int argc, char **argv) {
45 if (strcmp("-r",argv[i])==0)
47 if (strcmp("-a",argv[i])==0) {
52 process_elf_binary_data(argv[1]);
53 daikon_preprocess_entry_array();
56 // Pre-processes global dwarf_entry_array in order to place
57 // the data in a form that can easily be turned into .decls
59 void daikon_preprocess_entry_array()
61 initializeTypeArray();
66 int entry_is_type(dwarf_entry *entry) {
67 if (entry->tag_name==DW_TAG_structure_type||
68 entry->tag_name==DW_TAG_union_type) {
69 collection_type* collection_ptr = (collection_type*)(entry->entry_ptr);
70 /* if (collection_ptr->name==0&&assigntype) {
71 collection_ptr->name=(char*)malloc(100);
72 sprintf(collection_ptr->name,"TYPE%ld",typecount++);
79 int entry_is_valid_function(dwarf_entry *entry) {
80 if (tag_is_function(entry->tag_name)) {
81 function* funcPtr = (function*)(entry->entry_ptr);
82 if (funcPtr->start_pc != 0 && funcPtr->name != 0) {
86 printf("Skipping invalid-looking function %s\n", funcPtr->name);
98 void initializeTypeArray()
101 dwarf_entry * cur_entry;
102 struct genhashtable * ght=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
103 struct genhashtable * sht=NULL;
105 if (rootfile!=NULL) {
108 int fd=open(rootfile,O_RDONLY);
110 sht=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
112 if (read(fd,&a,1)>0) {
117 if (offset>0&&(a==13||a==10)) {
120 char *str=copystr(buf);
121 genputtable(sht,str,str);
128 if (arrayfile!=NULL) {
132 int fd=open(arrayfile,O_RDONLY);
136 arrayt=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
137 arraytype=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
139 if (read(fd,&a,1)<=0)
146 } else if (a!=13&&a!=10) {
153 if ((state==1)&&offset>0&&(a==13||a==10||!readmore)) {
157 char *str=copystr(buf);
158 char *sizestr=copystr(sizebuf);
159 genputtable(arrayt,str,sizestr);
166 for (i = 0; i < dwarf_entry_array_size; i++)
168 cur_entry = &dwarf_entry_array[i];
169 if (entry_is_type(cur_entry))
171 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
175 for(j=0;j<collection_ptr->num_members;j++) {
176 dwarf_entry *entry=collection_ptr->members[j];
177 if (entry->tag_name==DW_TAG_inheritance) {
180 member * member_ptr=(member *)entry->entry_ptr;
181 char *name=member_ptr->name;
182 dwarf_entry *type=member_ptr->type_ptr;
183 char *typestr=printname(type,GETTYPE);
184 char *poststr=printname(type,POSTNAME);
190 if (collection_ptr->name!=NULL) {
191 struct valuepair *vp=NULL;
192 if (gencontains(ght,collection_ptr->name))
193 vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
194 if (vp==NULL||vp->value<value) {
196 vp=(struct valuepair*)calloc(1,sizeof(struct valuepair));
197 genputtable(ght,collection_ptr->name,vp);
211 for (i = 0; i < dwarf_entry_array_size; i++) {
212 cur_entry = &dwarf_entry_array[i];
213 if (entry_is_type(cur_entry)) {
214 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
219 if (!gencontains(sht,collection_ptr->name))
221 if (gencontains(ght,collection_ptr->name)) {
222 struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
227 for(j=0;j<collection_ptr->num_members;j++) {
228 dwarf_entry *entry=collection_ptr->members[j];
229 if (entry->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 (!gencontains(sht,sub_ptr->name)) {
235 genputtable(sht,sub_ptr->name,sub_ptr->name);
238 member * member_ptr=(member *)entry->entry_ptr;
239 char *name=member_ptr->name;
240 dwarf_entry *type=member_ptr->type_ptr;
241 char *typestr=printname(type,GETJUSTTYPE);
242 if (typestr!=NULL&&!gencontains(sht,typestr)) {
244 genputtable(sht,typestr,typestr);
254 for (i = 0; i < dwarf_entry_array_size; i++)
256 cur_entry = &dwarf_entry_array[i];
257 if (entry_is_type(cur_entry))
259 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
262 if (collection_ptr->name==NULL)
264 if (sht!=NULL&&!gencontains(sht,collection_ptr->name))
266 if (gencontains(ght,collection_ptr->name)) {
267 struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
272 printf("structure %s ",collection_ptr->name);
274 while(j<collection_ptr->num_members&&
275 collection_ptr->members[j]->tag_name==DW_TAG_inheritance) {
276 inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
277 dwarf_entry *typeptr=in_ptr->target_ptr;
278 collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
280 printf("subclass of ");
283 printf("%s ",sub_ptr->name);
288 for(j=0;j<collection_ptr->num_members;j++) {
289 dwarf_entry *entry=collection_ptr->members[j];
290 if (entry->tag_name==DW_TAG_inheritance) {
291 inherit * inherit_ptr=(inherit *)entry->entry_ptr;
292 if (inherit_ptr->data_member_location>offset) {
293 printf(" reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
294 offset=inherit_ptr->data_member_location;
297 dwarf_entry *type=inherit_ptr->target_ptr;
298 collection_type *c_ptr=(collection_type*)type->entry_ptr;
299 offset+=printtype(c_ptr,ght);
302 member * member_ptr=(member *)entry->entry_ptr;
303 char *name=member_ptr->name;
304 dwarf_entry *type=member_ptr->type_ptr;
305 char *typestr=printname(type,GETTYPE);
306 char *poststr=printname(type,POSTNAME);
308 if (member_ptr->data_member_location>offset) {
309 printf(" reserved byte[%ld];\n",member_ptr->data_member_location-offset);
310 offset=member_ptr->data_member_location;
312 offset+=getsize(type);
313 newname=escapestr(name);
317 sprintf(buf, "%s.%s\0", collection_ptr->name,newname);
318 if (arrayt!=NULL&&gencontains(arrayt, &buf)) {
319 genputtable(arraytype, copystr(buf), typestr);
320 dtype=deref(typestr);
321 printf(" %s_array * %s%s;\n",dtype,newname,poststr);
324 printf(" %s %s%s;\n",typestr,newname,poststr);
329 if (offset<collection_ptr->byte_size)
330 printf(" reserved byte[%ld];\n",collection_ptr->byte_size-offset);
335 struct geniterator * gi=gengetiterator(arrayt);
337 char * str=(char *)gennext(gi);
343 size=(char *)gengettable(arrayt,str);
344 typestr=deref((char *)gengettable(arraytype,str));
346 printf("structure %s_array {\n",typestr);
347 printf(" %s elem[%s];\n",typestr,size);
356 int printtype(collection_type *collection_ptr,struct genhashtable *ght)
362 struct valuepair *vp=NULL;
363 if (gencontains(ght,collection_ptr->name))
364 vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
366 collection_ptr=(collection_type*) dwarf_entry_array[vp->index].entry_ptr;
368 for(j=0;j<collection_ptr->num_members;j++) {
369 dwarf_entry *entry=collection_ptr->members[j];
370 if (entry->tag_name==DW_TAG_inheritance) {
371 inherit * inherit_ptr=(inherit *)entry->entry_ptr;
372 if (inherit_ptr->data_member_location>offset) {
373 printf(" reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
374 offset=inherit_ptr->data_member_location;
378 dwarf_entry *type=inherit_ptr->target_ptr;
379 collection_type *c_ptr=(collection_type*)type->entry_ptr;
380 offset+=printtype(c_ptr,ght);
383 member * member_ptr=(member *)entry->entry_ptr;
384 char *name=member_ptr->name;
386 dwarf_entry *type=member_ptr->type_ptr;
387 char *typestr=printname(type,GETTYPE);
388 char *poststr=printname(type,POSTNAME);
389 if (member_ptr->data_member_location>offset) {
390 printf(" reserved byte[%ld];\n",member_ptr->data_member_location-offset);
391 offset=member_ptr->data_member_location;
393 offset+=getsize(type);
395 newname=escapestr(name);
399 sprintf(buf, "%s.%s\0", collection_ptr->name,newname);
400 if (arrayt!=NULL&&gencontains(arrayt, &buf)) {
401 genputtable(arraytype, buf, typestr);
402 dtype=deref(typestr);
403 printf(" %s_array * %s%s;\n",dtype,newname,poststr);
406 printf(" %s %s%s;\n",typestr,newname,poststr);
414 int getsize(dwarf_entry *type) {
417 switch(type->tag_name) {
418 case DW_TAG_enumeration_type:
420 case DW_TAG_array_type: {
421 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
424 for(i=0;i<modifier_ptr->num_array;i++) {
425 size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
427 return size*getsize(modifier_ptr->target_ptr);
429 case DW_TAG_const_type:
431 consttype * ctype_ptr=(consttype*)type->entry_ptr;
432 return getsize(ctype_ptr->target_ptr);
435 case DW_TAG_base_type: {
436 base_type *base=(base_type*)type->entry_ptr;
437 return base->byte_size;
439 case DW_TAG_pointer_type: {
442 case DW_TAG_union_type:
443 case DW_TAG_structure_type: {
444 collection_type *ctype=(collection_type*)type->entry_ptr;
445 return ctype->byte_size;
447 case DW_TAG_subroutine_type: {
452 tdef * tdef_ptr=(tdef*)type->entry_ptr;
453 return getsize(tdef_ptr->target_ptr);
462 char * deref(char *name) {
463 char *str=copystr(name);
465 for(;(*str)!=0;str++)
467 for(;(str!=initstr)&&((*str)!='*');str--)
472 for(;(str!=initstr)&&((*str)==' ');str--)
478 char * printname(dwarf_entry * type,int op) {
480 if (op==GETTYPE||op==GETJUSTTYPE)
484 switch(type->tag_name) {
485 case DW_TAG_enumeration_type:
489 case DW_TAG_array_type: {
490 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
491 if (op==GETTYPE||op==GETJUSTTYPE) {
492 char *typename=printname(modifier_ptr->target_ptr,op);
494 } else if (op==POSTNAME) {
497 char *typename=printname(modifier_ptr->target_ptr,op);
498 char *newptr=(char *)malloc(200);
499 for(i=0;i<modifier_ptr->num_array;i++) {
500 size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
502 sprintf(newptr,"%s[%ld]",typename,size);
507 case DW_TAG_const_type:
509 consttype * ctype_ptr=(consttype*)type->entry_ptr;
510 if (op==GETTYPE||op==GETJUSTTYPE) {
511 char *typename=printname(ctype_ptr->target_ptr,op);
516 case DW_TAG_subroutine_type: {
521 tdef * tdef_ptr=(tdef*)type->entry_ptr;
522 if (op==GETTYPE||op==GETJUSTTYPE) {
523 if (tdef_ptr->target_ptr==NULL)
524 return tdef_ptr->name;
525 if (tdef_ptr->target_ptr->tag_name==DW_TAG_union_type||
526 tdef_ptr->target_ptr->tag_name==DW_TAG_structure_type) {
527 collection_type *ctype=(collection_type*)tdef_ptr->target_ptr->entry_ptr;
528 if (ctype->name!=NULL)
530 ctype->name=tdef_ptr->name;
531 return tdef_ptr->name;
533 char *typename=printname(tdef_ptr->target_ptr,op);
538 case DW_TAG_base_type: {
539 base_type *base=(base_type*)type->entry_ptr;
541 switch(base->byte_size) {
549 char *m=(char*)malloc(100);
550 sprintf(m,"error%ld",base->byte_size);
556 case DW_TAG_pointer_type: {
557 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
559 if (modifier_ptr->target_ptr==NULL)
560 return "void *"; /* seems like a good guess */
562 char *typename=printname(modifier_ptr->target_ptr,op);
564 char *newptr=(char *)malloc(200);
565 sprintf(newptr,"%s *",typename);
568 } else if (op==GETJUSTTYPE) {
572 if (modifier_ptr->target_ptr==NULL)
575 char *typename=printname(modifier_ptr->target_ptr,op);
581 case DW_TAG_union_type:
582 case DW_TAG_structure_type: {
583 collection_type *ctype=(collection_type*)type->entry_ptr;
584 if (op==GETTYPE&&ctype->name==NULL&&assigntype) {
585 char *newb=(char *)malloc(1000);
589 newchars=sprintf(newb,"unnamed_",type->ID);
591 for(i=0;i<ctype->num_members;i++) {
592 dwarf_entry * de=ctype->members[i];
593 if (de->tag_name==DW_TAG_member) {
594 member * me=(member *)de->entry_ptr;
595 newchars=sprintf(newb,"%s",me->name);
602 if (op==GETJUSTTYPE&&ctype->name==NULL&&assigntype) {
603 char *newb=(char *)malloc(1000);
607 newchars=sprintf(newb,"unnamed_",type->ID);
609 for(i=0;i<ctype->num_members;i++) {
610 dwarf_entry * de=ctype->members[i];
611 if (de->tag_name==DW_TAG_member) {
612 member * me=(member *)de->entry_ptr;
613 newchars=sprintf(newb,"%s",me->name);
628 char * p=(char *)malloc(100);
629 sprintf(p,"0x%x",type->tag_name);