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);
168 for (i = 0; i < dwarf_entry_array_size; i++)
170 cur_entry = &dwarf_entry_array[i];
171 if (entry_is_type(cur_entry))
173 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
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) {
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);
196 for (i = 0; i < dwarf_entry_array_size; i++)
198 cur_entry = &dwarf_entry_array[i];
199 if (entry_is_type(cur_entry))
201 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
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) {
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);
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) {
228 vp=(struct valuepair*)calloc(1,sizeof(struct valuepair));
229 genputtable(ght,collection_ptr->name,vp);
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);
252 if (!gencontains(sht,collection_ptr->name))
254 if (gencontains(ght,collection_ptr->name)) {
255 struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
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)) {
268 genputtable(sht,sub_ptr->name,sub_ptr->name);
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)) {
277 genputtable(sht,typestr,typestr);
287 for (i = 0; i < dwarf_entry_array_size; i++)
289 cur_entry = &dwarf_entry_array[i];
290 if (entry_is_type(cur_entry))
292 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
295 if (collection_ptr->name==NULL)
297 if (sht!=NULL&&!gencontains(sht,collection_ptr->name))
299 if (gencontains(ght,collection_ptr->name)) {
300 struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
305 printf("structure %s ",collection_ptr->name);
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);
313 printf("subclass of ");
316 printf("%s ",sub_ptr->name);
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;
330 dwarf_entry *type=inherit_ptr->target_ptr;
331 collection_type *c_ptr=(collection_type*)type->entry_ptr;
332 offset+=printtype(c_ptr,ght);
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);
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;
345 offset+=getsize(type);
346 newname=escapestr(name);
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);
357 printf(" %s %s%s;\n",typestr,newname,poststr);
362 if (offset<collection_ptr->byte_size)
363 printf(" reserved byte[%ld];\n",collection_ptr->byte_size-offset);
368 struct geniterator * gi=gengetiterator(arrayt);
370 char * str=(char *)gennext(gi);
376 size=(char *)gengettable(arrayt,str);
377 typestr=deref((char *)gengettable(arraytype,str));
379 printf("structure %s_array {\n",typestr);
380 printf(" %s elem[%s];\n",typestr,size);
389 int printtype(collection_type *collection_ptr,struct genhashtable *ght)
395 struct valuepair *vp=NULL;
396 if (gencontains(ght,collection_ptr->name))
397 vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
399 collection_ptr=(collection_type*) dwarf_entry_array[vp->index].entry_ptr;
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;
411 dwarf_entry *type=inherit_ptr->target_ptr;
412 collection_type *c_ptr=(collection_type*)type->entry_ptr;
413 offset+=printtype(c_ptr,ght);
416 member * member_ptr=(member *)entry->entry_ptr;
417 char *name=member_ptr->name;
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;
426 offset+=getsize(type);
428 newname=escapestr(name);
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);
439 printf(" %s %s%s;\n",typestr,newname,poststr);
447 int getsize(dwarf_entry *type) {
450 switch(type->tag_name) {
451 case DW_TAG_enumeration_type:
453 case DW_TAG_array_type: {
454 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
457 for(i=0;i<modifier_ptr->num_array;i++) {
458 size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
460 return size*getsize(modifier_ptr->target_ptr);
462 case DW_TAG_const_type:
464 consttype * ctype_ptr=(consttype*)type->entry_ptr;
465 return getsize(ctype_ptr->target_ptr);
468 case DW_TAG_base_type: {
469 base_type *base=(base_type*)type->entry_ptr;
470 return base->byte_size;
472 case DW_TAG_pointer_type: {
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;
480 case DW_TAG_subroutine_type: {
485 tdef * tdef_ptr=(tdef*)type->entry_ptr;
486 return getsize(tdef_ptr->target_ptr);
495 char * deref(char *name) {
496 char *str=copystr(name);
498 for(;(*str)!=0;str++)
500 for(;(str!=initstr)&&((*str)!='*');str--)
505 for(;(str!=initstr)&&((*str)==' ');str--)
511 char * printname(dwarf_entry * type,int op) {
513 if (op==GETTYPE||op==GETJUSTTYPE)
517 switch(type->tag_name) {
518 case DW_TAG_enumeration_type:
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);
527 } else if (op==POSTNAME) {
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;
535 sprintf(newptr,"%s[%ld]",typename,size);
540 case DW_TAG_const_type:
542 consttype * ctype_ptr=(consttype*)type->entry_ptr;
543 if (op==GETTYPE||op==GETJUSTTYPE) {
544 char *typename=printname(ctype_ptr->target_ptr,op);
549 case DW_TAG_subroutine_type: {
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)
563 ctype->name=tdef_ptr->name;
564 return tdef_ptr->name;
566 char *typename=printname(tdef_ptr->target_ptr,op);
571 case DW_TAG_base_type: {
572 base_type *base=(base_type*)type->entry_ptr;
574 switch(base->byte_size) {
582 char *m=(char*)malloc(100);
583 sprintf(m,"error%ld",base->byte_size);
589 case DW_TAG_pointer_type: {
590 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
592 if (modifier_ptr->target_ptr==NULL)
593 return "void *"; /* seems like a good guess */
595 char *typename=printname(modifier_ptr->target_ptr,op);
597 char *newptr=(char *)malloc(200);
598 sprintf(newptr,"%s *",typename);
601 } else if (op==GETJUSTTYPE) {
605 if (modifier_ptr->target_ptr==NULL)
608 char *typename=printname(modifier_ptr->target_ptr,op);
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);
622 newchars=sprintf(newb,"unnamed_",type->ID);
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);
635 if (op==GETJUSTTYPE&&ctype->name==NULL&&assigntype) {
636 char *newb=(char *)malloc(1000);
640 newchars=sprintf(newb,"unnamed_",type->ID);
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);
661 char * p=(char *)malloc(100);
662 sprintf(p,"0x%x",type->tag_name);