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.
18 #include "dumpstructures.h"
20 #include "elf/dwarf2.h"
26 int process_elf_binary_data(char* filename);
28 int main(int argc, char **argv) {
31 process_elf_binary_data(argv[1]);
32 daikon_preprocess_entry_array();
35 // Pre-processes global dwarf_entry_array in order to place
36 // the data in a form that can easily be turned into .decls
38 void daikon_preprocess_entry_array()
40 initializeTypeArray();
45 int entry_is_type(dwarf_entry *entry) {
46 if (entry->tag_name==DW_TAG_structure_type||
47 entry->tag_name==DW_TAG_union_type) {
48 collection_type* collection_ptr = (collection_type*)(entry->entry_ptr);
49 /* if (collection_ptr->name==0&&assigntype) {
50 collection_ptr->name=(char*)malloc(100);
51 sprintf(collection_ptr->name,"TYPE%ld",typecount++);
58 int entry_is_valid_function(dwarf_entry *entry) {
59 if (tag_is_function(entry->tag_name)) {
60 function* funcPtr = (function*)(entry->entry_ptr);
61 if (funcPtr->start_pc != 0 && funcPtr->name != 0) {
65 printf("Skipping invalid-looking function %s\n", funcPtr->name);
77 void initializeTypeArray()
80 dwarf_entry * cur_entry;
81 struct genhashtable * ght=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
83 for (i = 0; i < dwarf_entry_array_size; i++)
85 cur_entry = &dwarf_entry_array[i];
86 if (entry_is_type(cur_entry))
88 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
92 for(j=0;j<collection_ptr->num_members;j++) {
93 dwarf_entry *entry=collection_ptr->members[j];
94 if (entry->tag_name==DW_TAG_inheritance) {
99 member * member_ptr=(member *)entry->entry_ptr;
100 char *name=member_ptr->name;
101 dwarf_entry *type=member_ptr->type_ptr;
102 char *typestr=printname(type,GETTYPE);
103 char *poststr=printname(type,POSTNAME);
109 if (collection_ptr->name!=NULL) {
110 struct valuepair *vp=NULL;
111 if (gencontains(ght,collection_ptr->name))
112 vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
113 if (vp==NULL||vp->value<value) {
115 vp=(struct valuepair*)calloc(1,sizeof(struct valuepair));
116 genputtable(ght,collection_ptr->name,vp);
126 for (i = 0; i < dwarf_entry_array_size; i++)
128 cur_entry = &dwarf_entry_array[i];
129 if (entry_is_type(cur_entry))
131 collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
134 if (collection_ptr->name==NULL)
136 if (gencontains(ght,collection_ptr->name)) {
137 struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
142 printf("structure %s ",collection_ptr->name);
144 while(j<collection_ptr->num_members&&
145 collection_ptr->members[j]->tag_name==DW_TAG_inheritance) {
146 inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
147 dwarf_entry *typeptr=in_ptr->target_ptr;
148 collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
150 printf("subclasses ");
153 printf("%s ",sub_ptr->name);
158 for(j=0;j<collection_ptr->num_members;j++) {
159 dwarf_entry *entry=collection_ptr->members[j];
160 if (entry->tag_name==DW_TAG_inheritance) {
161 inherit * inherit_ptr=(inherit *)entry->entry_ptr;
162 if (inherit_ptr->data_member_location>offset) {
163 printf(" reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
164 offset=inherit_ptr->data_member_location;
167 dwarf_entry *type=inherit_ptr->target_ptr;
168 collection_type *c_ptr=(collection_type*)type->entry_ptr;
169 offset+=printtype(c_ptr,ght);
172 member * member_ptr=(member *)entry->entry_ptr;
173 char *name=member_ptr->name;
174 dwarf_entry *type=member_ptr->type_ptr;
175 char *typestr=printname(type,GETTYPE);
176 char *poststr=printname(type,POSTNAME);
177 if (member_ptr->data_member_location>offset) {
178 printf(" reserved byte[%ld];\n",member_ptr->data_member_location-offset);
179 offset=member_ptr->data_member_location;
181 offset+=getsize(type);
183 printf(" %s %s%s;\n",typestr,name,poststr);
186 if (offset<collection_ptr->byte_size)
187 printf(" reserved byte[%ld];\n",collection_ptr->byte_size-offset);
193 int printtype(collection_type *collection_ptr,struct genhashtable *ght)
199 struct valuepair *vp=NULL;
200 if (gencontains(ght,collection_ptr->name))
201 vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
203 collection_ptr=(collection_type*) dwarf_entry_array[vp->index].entry_ptr;
205 for(j=0;j<collection_ptr->num_members;j++) {
206 dwarf_entry *entry=collection_ptr->members[j];
207 if (entry->tag_name==DW_TAG_inheritance) {
208 inherit * inherit_ptr=(inherit *)entry->entry_ptr;
209 if (inherit_ptr->data_member_location>offset) {
210 printf(" reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
211 offset=inherit_ptr->data_member_location;
215 dwarf_entry *type=inherit_ptr->target_ptr;
216 collection_type *c_ptr=(collection_type*)type->entry_ptr;
217 offset+=printtype(c_ptr,ght);
220 member * member_ptr=(member *)entry->entry_ptr;
221 char *name=member_ptr->name;
222 dwarf_entry *type=member_ptr->type_ptr;
223 char *typestr=printname(type,GETTYPE);
224 char *poststr=printname(type,POSTNAME);
225 if (member_ptr->data_member_location>offset) {
226 printf(" reserved byte[%ld];\n",member_ptr->data_member_location-offset);
227 offset=member_ptr->data_member_location;
229 offset+=getsize(type);
231 printf(" %s %s%s;\n",typestr,name,poststr);
239 int getsize(dwarf_entry *type) {
242 switch(type->tag_name) {
243 case DW_TAG_enumeration_type:
245 case DW_TAG_array_type: {
246 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
249 for(i=0;i<modifier_ptr->num_array;i++) {
250 size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
252 return size*getsize(modifier_ptr->target_ptr);
254 case DW_TAG_const_type:
256 consttype * ctype_ptr=(consttype*)type->entry_ptr;
257 return getsize(ctype_ptr->target_ptr);
260 case DW_TAG_base_type: {
261 base_type *base=(base_type*)type->entry_ptr;
262 return base->byte_size;
264 case DW_TAG_pointer_type: {
267 case DW_TAG_union_type:
268 case DW_TAG_structure_type: {
269 collection_type *ctype=(collection_type*)type->entry_ptr;
270 return ctype->byte_size;
272 case DW_TAG_subroutine_type: {
277 tdef * tdef_ptr=(tdef*)type->entry_ptr;
278 return getsize(tdef_ptr->target_ptr);
287 char * printname(dwarf_entry * type,int op) {
293 switch(type->tag_name) {
294 case DW_TAG_enumeration_type:
298 case DW_TAG_array_type: {
299 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
301 char *typename=printname(modifier_ptr->target_ptr,op);
303 } else if (op==POSTNAME) {
306 char *typename=printname(modifier_ptr->target_ptr,op);
307 char *newptr=(char *)malloc(200);
308 for(i=0;i<modifier_ptr->num_array;i++) {
309 size*=((array_bound*)modifier_ptr->array_ptr[i]->entry_ptr)->upperbound+1;
311 sprintf(newptr,"%s[%ld]",typename,size);
316 case DW_TAG_const_type:
318 consttype * ctype_ptr=(consttype*)type->entry_ptr;
320 char *typename=printname(ctype_ptr->target_ptr,op);
325 case DW_TAG_subroutine_type: {
330 tdef * tdef_ptr=(tdef*)type->entry_ptr;
332 char *typename=printname(tdef_ptr->target_ptr,op);
337 case DW_TAG_base_type: {
338 base_type *base=(base_type*)type->entry_ptr;
340 switch(base->byte_size) {
348 char *m=(char*)malloc(100);
349 sprintf(m,"error%ld",base->byte_size);
355 case DW_TAG_pointer_type: {
356 modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
358 if (modifier_ptr->target_ptr==NULL)
359 return "void *"; /* seems like a good guess */
361 char *typename=printname(modifier_ptr->target_ptr,op);
363 char *newptr=(char *)malloc(200);
364 sprintf(newptr,"%s *",typename);
370 case DW_TAG_union_type:
371 case DW_TAG_structure_type: {
372 collection_type *ctype=(collection_type*)type->entry_ptr;
373 if (op==GETTYPE&&ctype->name==NULL&&assigntype) {
374 ctype->name=(char*)malloc(100);
375 sprintf(ctype->name,"TYPE%ld",typecount++);
386 char * p=(char *)malloc(100);
387 sprintf(p,"0x%x",type->tag_name);