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();
57 // Pre-processes global dwarf_entry_array in order to place
58 // the data in a form that can easily be turned into .decls
60 void daikon_preprocess_entry_array()
62 initializeTypeArray();
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++);
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) {
87 printf("Skipping invalid-looking function %s\n", funcPtr->name);
99 void initializeTypeArray()
102 dwarf_entry * cur_entry;
103 struct genhashtable * ght=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
104 struct genhashtable * sht=NULL;
106 if (rootfile!=NULL) {
109 int fd=open(rootfile,O_RDONLY);
111 sht=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
113 if (read(fd,&a,1)>0) {
118 if (offset>0&&(a==13||a==10)) {
121 char *str=copystr(buf);
122 genputtable(sht,str,str);
129 if (arrayfile!=NULL) {
133 int fd=open(arrayfile,O_RDONLY);
137 arrayt=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
138 arraytype=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
140 if (read(fd,&a,1)<=0)
147 } else if (a!=13&&a!=10) {
154 if ((state==1)&&offset>0&&(a==13||a==10||!readmore)) {
158 char *str=copystr(buf);
159 char *sizestr=copystr(sizebuf);
160 genputtable(arrayt,str,sizestr);
167 for (i = 0; i < dwarf_entry_array_size; i++)
169 cur_entry = &dwarf_entry_array[i];
170 if (entry_is_type(cur_entry))
172 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
176 for(j=0;j<collection_ptr->num_members;j++) {
177 dwarf_entry *entry=collection_ptr->members[j];
178 if (entry->tag_name==DW_TAG_inheritance) {
181 member * member_ptr=(member *)entry->entry_ptr;
182 char *name=member_ptr->name;
183 dwarf_entry *type=member_ptr->type_ptr;
184 char *typestr=printname(type,GETTYPE);
185 char *poststr=printname(type,POSTNAME);
191 if (collection_ptr->name!=NULL) {
192 struct valuepair *vp=NULL;
193 if (gencontains(ght,collection_ptr->name))
194 vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
195 if (vp==NULL||vp->value<value) {
197 vp=(struct valuepair*)calloc(1,sizeof(struct valuepair));
198 genputtable(ght,collection_ptr->name,vp);
212 for (i = 0; i < dwarf_entry_array_size; i++) {
213 cur_entry = &dwarf_entry_array[i];
214 if (entry_is_type(cur_entry)) {
215 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
220 if (!gencontains(sht,collection_ptr->name))
222 if (gencontains(ght,collection_ptr->name)) {
223 struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
228 for(j=0;j<collection_ptr->num_members;j++) {
229 dwarf_entry *entry=collection_ptr->members[j];
230 if (entry->tag_name==DW_TAG_inheritance) {
231 inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
232 dwarf_entry *typeptr=in_ptr->target_ptr;
233 collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
234 if (!gencontains(sht,sub_ptr->name)) {
236 genputtable(sht,sub_ptr->name,sub_ptr->name);
239 member * member_ptr=(member *)entry->entry_ptr;
240 char *name=member_ptr->name;
241 dwarf_entry *type=member_ptr->type_ptr;
242 char *typestr=printname(type,GETJUSTTYPE);
243 if (typestr!=NULL&&!gencontains(sht,typestr)) {
245 genputtable(sht,typestr,typestr);
255 for (i = 0; i < dwarf_entry_array_size; i++)
257 cur_entry = &dwarf_entry_array[i];
258 if (entry_is_type(cur_entry))
260 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
263 if (collection_ptr->name==NULL)
265 if (sht!=NULL&&!gencontains(sht,collection_ptr->name))
267 if (gencontains(ght,collection_ptr->name)) {
268 struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
273 printf("structure %s ",collection_ptr->name);
275 while(j<collection_ptr->num_members&&
276 collection_ptr->members[j]->tag_name==DW_TAG_inheritance) {
277 inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
278 dwarf_entry *typeptr=in_ptr->target_ptr;
279 collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
281 printf("subclass of ");
284 printf("%s ",sub_ptr->name);
289 for(j=0;j<collection_ptr->num_members;j++) {
290 dwarf_entry *entry=collection_ptr->members[j];
291 if (entry->tag_name==DW_TAG_inheritance) {
292 inherit * inherit_ptr=(inherit *)entry->entry_ptr;
293 if (inherit_ptr->data_member_location>offset) {
294 printf(" reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
295 offset=inherit_ptr->data_member_location;
298 dwarf_entry *type=inherit_ptr->target_ptr;
299 collection_type *c_ptr=(collection_type*)type->entry_ptr;
300 offset+=printtype(c_ptr,ght);
303 member * member_ptr=(member *)entry->entry_ptr;
304 char *name=member_ptr->name;
305 dwarf_entry *type=member_ptr->type_ptr;
306 char *typestr=printname(type,GETTYPE);
307 char *poststr=printname(type,POSTNAME);
309 if (member_ptr->data_member_location>offset) {
310 printf(" reserved byte[%ld];\n",member_ptr->data_member_location-offset);
311 offset=member_ptr->data_member_location;
313 offset+=getsize(type);
314 newname=escapestr(name);
318 sprintf(buf, "%s.%s\0", collection_ptr->name,newname);
319 if (arrayt!=NULL&&gencontains(arrayt, &buf)) {
320 genputtable(arraytype, copystr(buf), typestr);
321 dtype=deref(typestr);
322 printf(" %s_array * %s%s;\n",dtype,newname,poststr);
325 printf(" %s %s%s;\n",typestr,newname,poststr);
330 if (offset<collection_ptr->byte_size)
331 printf(" reserved byte[%ld];\n",collection_ptr->byte_size-offset);
336 struct geniterator * gi=gengetiterator(arrayt);
338 char * str=(char *)gennext(gi);
344 size=(char *)gengettable(arrayt,str);
345 typestr=deref((char *)gengettable(arraytype,str));
347 printf("structure %s_array {\n",typestr);
348 printf(" %s elem[%s];\n",typestr,size);
357 int printtype(collection_type *collection_ptr,struct genhashtable *ght)
363 struct valuepair *vp=NULL;
364 if (gencontains(ght,collection_ptr->name))
365 vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
367 collection_ptr=(collection_type*) dwarf_entry_array[vp->index].entry_ptr;
369 for(j=0;j<collection_ptr->num_members;j++) {
370 dwarf_entry *entry=collection_ptr->members[j];
371 if (entry->tag_name==DW_TAG_inheritance) {
372 inherit * inherit_ptr=(inherit *)entry->entry_ptr;
373 if (inherit_ptr->data_member_location>offset) {
374 printf(" reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
375 offset=inherit_ptr->data_member_location;
379 dwarf_entry *type=inherit_ptr->target_ptr;
380 collection_type *c_ptr=(collection_type*)type->entry_ptr;
381 offset+=printtype(c_ptr,ght);
384 member * member_ptr=(member *)entry->entry_ptr;
385 char *name=member_ptr->name;
387 dwarf_entry *type=member_ptr->type_ptr;
388 char *typestr=printname(type,GETTYPE);
389 char *poststr=printname(type,POSTNAME);
390 if (member_ptr->data_member_location>offset) {
391 printf(" reserved byte[%ld];\n",member_ptr->data_member_location-offset);
392 offset=member_ptr->data_member_location;
394 offset+=getsize(type);
396 newname=escapestr(name);
400 sprintf(buf, "%s.%s\0", collection_ptr->name,newname);
401 if (arrayt!=NULL&&gencontains(arrayt, &buf)) {
402 genputtable(arraytype, buf, typestr);
403 dtype=deref(typestr);
404 printf(" %s_array * %s%s;\n",dtype,newname,poststr);
407 printf(" %s %s%s;\n",typestr,newname,poststr);
415 int getsize(dwarf_entry *type) {
418 switch(type->tag_name) {
419 case DW_TAG_enumeration_type:
421 case DW_TAG_array_type: {
422 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
425 for(i=0;i<modifier_ptr->num_array;i++) {
426 size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
428 return size*getsize(modifier_ptr->target_ptr);
430 case DW_TAG_const_type:
432 consttype * ctype_ptr=(consttype*)type->entry_ptr;
433 return getsize(ctype_ptr->target_ptr);
436 case DW_TAG_base_type: {
437 base_type *base=(base_type*)type->entry_ptr;
438 return base->byte_size;
440 case DW_TAG_pointer_type: {
443 case DW_TAG_union_type:
444 case DW_TAG_structure_type: {
445 collection_type *ctype=(collection_type*)type->entry_ptr;
446 return ctype->byte_size;
448 case DW_TAG_subroutine_type: {
453 tdef * tdef_ptr=(tdef*)type->entry_ptr;
454 return getsize(tdef_ptr->target_ptr);
463 char * deref(char *name) {
464 char *str=copystr(name);
466 for(;(*str)!=0;str++)
468 for(;(str!=initstr)&&((*str)!='*');str--)
473 for(;(str!=initstr)&&((*str)==' ');str--)
479 char * printname(dwarf_entry * type,int op) {
481 if (op==GETTYPE||op==GETJUSTTYPE)
485 switch(type->tag_name) {
486 case DW_TAG_enumeration_type:
490 case DW_TAG_array_type: {
491 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
492 if (op==GETTYPE||op==GETJUSTTYPE) {
493 char *typename=printname(modifier_ptr->target_ptr,op);
495 } else if (op==POSTNAME) {
498 char *typename=printname(modifier_ptr->target_ptr,op);
499 char *newptr=(char *)malloc(200);
500 for(i=0;i<modifier_ptr->num_array;i++) {
501 size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
503 sprintf(newptr,"%s[%ld]",typename,size);
508 case DW_TAG_const_type:
510 consttype * ctype_ptr=(consttype*)type->entry_ptr;
511 if (op==GETTYPE||op==GETJUSTTYPE) {
512 char *typename=printname(ctype_ptr->target_ptr,op);
517 case DW_TAG_subroutine_type: {
522 tdef * tdef_ptr=(tdef*)type->entry_ptr;
523 if (op==GETTYPE||op==GETJUSTTYPE) {
524 if (tdef_ptr->target_ptr==NULL)
525 return tdef_ptr->name;
526 if (tdef_ptr->target_ptr->tag_name==DW_TAG_union_type||
527 tdef_ptr->target_ptr->tag_name==DW_TAG_structure_type) {
528 collection_type *ctype=(collection_type*)tdef_ptr->target_ptr->entry_ptr;
529 if (ctype->name!=NULL)
531 ctype->name=tdef_ptr->name;
532 return tdef_ptr->name;
534 char *typename=printname(tdef_ptr->target_ptr,op);
539 case DW_TAG_base_type: {
540 base_type *base=(base_type*)type->entry_ptr;
542 switch(base->byte_size) {
550 char *m=(char*)malloc(100);
551 sprintf(m,"error%ld",base->byte_size);
557 case DW_TAG_pointer_type: {
558 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
560 if (modifier_ptr->target_ptr==NULL)
561 return "void *"; /* seems like a good guess */
563 char *typename=printname(modifier_ptr->target_ptr,op);
565 char *newptr=(char *)malloc(200);
566 sprintf(newptr,"%s *",typename);
569 } else if (op==GETJUSTTYPE) {
573 if (modifier_ptr->target_ptr==NULL)
576 char *typename=printname(modifier_ptr->target_ptr,op);
582 case DW_TAG_union_type:
583 case DW_TAG_structure_type: {
584 collection_type *ctype=(collection_type*)type->entry_ptr;
585 if (op==GETTYPE&&ctype->name==NULL&&assigntype) {
586 char *newb=(char *)malloc(1000);
590 newchars=sprintf(newb,"unnamed_",type->ID);
592 for(i=0;i<ctype->num_members;i++) {
593 dwarf_entry * de=ctype->members[i];
594 if (de->tag_name==DW_TAG_member) {
595 member * me=(member *)de->entry_ptr;
596 newchars=sprintf(newb,"%s",me->name);
603 if (op==GETJUSTTYPE&&ctype->name==NULL&&assigntype) {
604 char *newb=(char *)malloc(1000);
608 newchars=sprintf(newb,"unnamed_",type->ID);
610 for(i=0;i<ctype->num_members;i++) {
611 dwarf_entry * de=ctype->members[i];
612 if (de->tag_name==DW_TAG_member) {
613 member * me=(member *)de->entry_ptr;
614 newchars=sprintf(newb,"%s",me->name);
629 char * p=(char *)malloc(100);
630 sprintf(p,"0x%x",type->tag_name);