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"
32 int process_elf_binary_data(char* filename);
36 int main(int argc, char **argv) {
41 if (argc==4&&(strcmp("-r",argv[3])==0))
44 process_elf_binary_data(argv[1]);
45 daikon_preprocess_entry_array();
48 // Pre-processes global dwarf_entry_array in order to place
49 // the data in a form that can easily be turned into .decls
51 void daikon_preprocess_entry_array()
53 initializeTypeArray();
58 int entry_is_type(dwarf_entry *entry) {
59 if (entry->tag_name==DW_TAG_structure_type||
60 entry->tag_name==DW_TAG_union_type) {
61 collection_type* collection_ptr = (collection_type*)(entry->entry_ptr);
62 /* if (collection_ptr->name==0&&assigntype) {
63 collection_ptr->name=(char*)malloc(100);
64 sprintf(collection_ptr->name,"TYPE%ld",typecount++);
71 int entry_is_valid_function(dwarf_entry *entry) {
72 if (tag_is_function(entry->tag_name)) {
73 function* funcPtr = (function*)(entry->entry_ptr);
74 if (funcPtr->start_pc != 0 && funcPtr->name != 0) {
78 printf("Skipping invalid-looking function %s\n", funcPtr->name);
90 void initializeTypeArray()
93 dwarf_entry * cur_entry;
94 struct genhashtable * ght=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
95 struct genhashtable * sht=NULL;
100 int fd=open(rootfile,O_RDONLY);
102 sht=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
104 if (read(fd,&a,1)>0) {
109 if (offset>0&&(a==13||a==10)) {
112 char *str=copystr(buf);
113 genputtable(sht,str,str);
120 for (i = 0; i < dwarf_entry_array_size; i++)
122 cur_entry = &dwarf_entry_array[i];
123 if (entry_is_type(cur_entry))
125 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
129 for(j=0;j<collection_ptr->num_members;j++) {
130 dwarf_entry *entry=collection_ptr->members[j];
131 if (entry->tag_name==DW_TAG_inheritance) {
134 member * member_ptr=(member *)entry->entry_ptr;
135 char *name=member_ptr->name;
136 dwarf_entry *type=member_ptr->type_ptr;
137 char *typestr=printname(type,GETTYPE);
138 char *poststr=printname(type,POSTNAME);
144 if (collection_ptr->name!=NULL) {
145 struct valuepair *vp=NULL;
146 if (gencontains(ght,collection_ptr->name))
147 vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
148 if (vp==NULL||vp->value<value) {
150 vp=(struct valuepair*)calloc(1,sizeof(struct valuepair));
151 genputtable(ght,collection_ptr->name,vp);
165 for (i = 0; i < dwarf_entry_array_size; i++) {
166 cur_entry = &dwarf_entry_array[i];
167 if (entry_is_type(cur_entry)) {
168 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
173 if (!gencontains(sht,collection_ptr->name))
175 if (gencontains(ght,collection_ptr->name)) {
176 struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
181 for(j=0;j<collection_ptr->num_members;j++) {
182 dwarf_entry *entry=collection_ptr->members[j];
183 if (entry->tag_name==DW_TAG_inheritance) {
184 inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
185 dwarf_entry *typeptr=in_ptr->target_ptr;
186 collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
187 if (!gencontains(sht,sub_ptr->name)) {
189 genputtable(sht,sub_ptr->name,sub_ptr->name);
192 member * member_ptr=(member *)entry->entry_ptr;
193 char *name=member_ptr->name;
194 dwarf_entry *type=member_ptr->type_ptr;
195 char *typestr=printname(type,GETJUSTTYPE);
196 if (typestr!=NULL&&!gencontains(sht,typestr)) {
198 genputtable(sht,typestr,typestr);
208 for (i = 0; i < dwarf_entry_array_size; i++)
210 cur_entry = &dwarf_entry_array[i];
211 if (entry_is_type(cur_entry))
213 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
216 if (collection_ptr->name==NULL)
218 if (sht!=NULL&&!gencontains(sht,collection_ptr->name))
220 if (gencontains(ght,collection_ptr->name)) {
221 struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
226 printf("structure %s ",collection_ptr->name);
228 while(j<collection_ptr->num_members&&
229 collection_ptr->members[j]->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);
234 printf("subclass of ");
237 printf("%s ",sub_ptr->name);
242 for(j=0;j<collection_ptr->num_members;j++) {
243 dwarf_entry *entry=collection_ptr->members[j];
244 if (entry->tag_name==DW_TAG_inheritance) {
245 inherit * inherit_ptr=(inherit *)entry->entry_ptr;
246 if (inherit_ptr->data_member_location>offset) {
247 printf(" reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
248 offset=inherit_ptr->data_member_location;
251 dwarf_entry *type=inherit_ptr->target_ptr;
252 collection_type *c_ptr=(collection_type*)type->entry_ptr;
253 offset+=printtype(c_ptr,ght);
256 member * member_ptr=(member *)entry->entry_ptr;
257 char *name=member_ptr->name;
258 dwarf_entry *type=member_ptr->type_ptr;
259 char *typestr=printname(type,GETTYPE);
260 char *poststr=printname(type,POSTNAME);
262 if (member_ptr->data_member_location>offset) {
263 printf(" reserved byte[%ld];\n",member_ptr->data_member_location-offset);
264 offset=member_ptr->data_member_location;
266 offset+=getsize(type);
267 newname=escapestr(name);
268 printf(" %s %s%s;\n",typestr,newname,poststr);
272 if (offset<collection_ptr->byte_size)
273 printf(" reserved byte[%ld];\n",collection_ptr->byte_size-offset);
279 int printtype(collection_type *collection_ptr,struct genhashtable *ght)
285 struct valuepair *vp=NULL;
286 if (gencontains(ght,collection_ptr->name))
287 vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
289 collection_ptr=(collection_type*) dwarf_entry_array[vp->index].entry_ptr;
291 for(j=0;j<collection_ptr->num_members;j++) {
292 dwarf_entry *entry=collection_ptr->members[j];
293 if (entry->tag_name==DW_TAG_inheritance) {
294 inherit * inherit_ptr=(inherit *)entry->entry_ptr;
295 if (inherit_ptr->data_member_location>offset) {
296 printf(" reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
297 offset=inherit_ptr->data_member_location;
301 dwarf_entry *type=inherit_ptr->target_ptr;
302 collection_type *c_ptr=(collection_type*)type->entry_ptr;
303 offset+=printtype(c_ptr,ght);
306 member * member_ptr=(member *)entry->entry_ptr;
307 char *name=member_ptr->name;
309 dwarf_entry *type=member_ptr->type_ptr;
310 char *typestr=printname(type,GETTYPE);
311 char *poststr=printname(type,POSTNAME);
312 if (member_ptr->data_member_location>offset) {
313 printf(" reserved byte[%ld];\n",member_ptr->data_member_location-offset);
314 offset=member_ptr->data_member_location;
316 offset+=getsize(type);
318 newname=escapestr(name);
319 printf(" %s %s%s;\n",typestr,newname,poststr);
326 int getsize(dwarf_entry *type) {
329 switch(type->tag_name) {
330 case DW_TAG_enumeration_type:
332 case DW_TAG_array_type: {
333 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
336 for(i=0;i<modifier_ptr->num_array;i++) {
337 size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
339 return size*getsize(modifier_ptr->target_ptr);
341 case DW_TAG_const_type:
343 consttype * ctype_ptr=(consttype*)type->entry_ptr;
344 return getsize(ctype_ptr->target_ptr);
347 case DW_TAG_base_type: {
348 base_type *base=(base_type*)type->entry_ptr;
349 return base->byte_size;
351 case DW_TAG_pointer_type: {
354 case DW_TAG_union_type:
355 case DW_TAG_structure_type: {
356 collection_type *ctype=(collection_type*)type->entry_ptr;
357 return ctype->byte_size;
359 case DW_TAG_subroutine_type: {
364 tdef * tdef_ptr=(tdef*)type->entry_ptr;
365 return getsize(tdef_ptr->target_ptr);
374 char * printname(dwarf_entry * type,int op) {
376 if (op==GETTYPE||op==GETJUSTTYPE)
380 switch(type->tag_name) {
381 case DW_TAG_enumeration_type:
385 case DW_TAG_array_type: {
386 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
387 if (op==GETTYPE||op==GETJUSTTYPE) {
388 char *typename=printname(modifier_ptr->target_ptr,op);
390 } else if (op==POSTNAME) {
393 char *typename=printname(modifier_ptr->target_ptr,op);
394 char *newptr=(char *)malloc(200);
395 for(i=0;i<modifier_ptr->num_array;i++) {
396 size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
398 sprintf(newptr,"%s[%ld]",typename,size);
403 case DW_TAG_const_type:
405 consttype * ctype_ptr=(consttype*)type->entry_ptr;
406 if (op==GETTYPE||op==GETJUSTTYPE) {
407 char *typename=printname(ctype_ptr->target_ptr,op);
412 case DW_TAG_subroutine_type: {
417 tdef * tdef_ptr=(tdef*)type->entry_ptr;
418 if (op==GETTYPE||op==GETJUSTTYPE) {
419 char *typename=printname(tdef_ptr->target_ptr,op);
424 case DW_TAG_base_type: {
425 base_type *base=(base_type*)type->entry_ptr;
427 switch(base->byte_size) {
435 char *m=(char*)malloc(100);
436 sprintf(m,"error%ld",base->byte_size);
442 case DW_TAG_pointer_type: {
443 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
445 if (modifier_ptr->target_ptr==NULL)
446 return "void *"; /* seems like a good guess */
448 char *typename=printname(modifier_ptr->target_ptr,op);
450 char *newptr=(char *)malloc(200);
451 sprintf(newptr,"%s *",typename);
454 } else if (op==GETJUSTTYPE) {
458 if (modifier_ptr->target_ptr==NULL)
461 char *typename=printname(modifier_ptr->target_ptr,op);
467 case DW_TAG_union_type:
468 case DW_TAG_structure_type: {
469 collection_type *ctype=(collection_type*)type->entry_ptr;
470 if (op==GETTYPE&&ctype->name==NULL&&assigntype) {
471 ctype->name=(char*)malloc(100);
472 sprintf(ctype->name,"TYPE%ld",typecount++);
476 if (op==GETJUSTTYPE&&ctype->name==NULL&&assigntype) {
477 ctype->name=(char*)malloc(100);
478 sprintf(ctype->name,"TYPE%ld",typecount++);
490 char * p=(char *)malloc(100);
491 sprintf(p,"0x%x",type->tag_name);