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.
14 This file contains functions that serve to complement readelf.c
15 and arrange the DWARF2 debugging information in an orderly
16 format within dwarf_entry_array
24 #include "elf/dwarf2.h"
26 // Global array of all dwarf entries, sorted (hopefully) by dwarf_entry.ID
27 // so that binary search is possible
28 // DO NOT MODIFY THIS POINTER MANUALLY!!!
29 // Representation invariants:
30 // 1. Every entry in dwarf_entry_array is sorted by ascending ID
31 // (This makes binary search possible)
32 // 2. dwarf_entry_array points to the beginning of the array
33 // 3. The size of the array is specified by dwarf_entry_array_size
34 // 4. All function entries are listed adjacent to their formal parameters
35 // 5. All struct, union, and enumeration entries are listed adjacent
37 // 6. All entries in the array belong to the file specified by the first
38 // compile_unit entry to its left (lower indices) in the array
39 dwarf_entry* dwarf_entry_array = 0;
41 // The size of this array
42 unsigned long dwarf_entry_array_size = 0;
45 /*----------------------------------------
46 Extracting type information from DWARF tag
47 -----------------------------------------*/
53 Returns: 1 if tag = {DW_TAG_base_type, _const_type, _enumerator,
54 _formal_parameter, _pointer_type, _array_type, _subprogram,
55 _union_type, _enumeration_type, _member,
56 _structure_type, _volatile_type, _compile_unit},
58 Effects: Used to determine which entries to record into a dwarf_entry structure;
59 All relevant entries should be included here
61 char tag_is_relevant_entry(unsigned long tag)
66 case DW_TAG_enumeration_type:
67 case DW_TAG_formal_parameter:
69 case DW_TAG_pointer_type:
70 case DW_TAG_structure_type:
71 case DW_TAG_union_type:
72 case DW_TAG_base_type:
74 case DW_TAG_const_type:
75 case DW_TAG_inheritance:
76 case DW_TAG_enumerator:
77 case DW_TAG_subprogram:
78 case DW_TAG_volatile_type:
79 case DW_TAG_compile_unit:
80 case DW_TAG_array_type:
81 case DW_TAG_subroutine_type:
82 case DW_TAG_subrange_type:
92 Returns: 1 if tag = {DW_TAG_pointer_type, _array_type, _const_type, _volatile_type},
94 Effects: Used to determine if the type is a modifier - modifier types
95 refer to another type within the dwarf_entry_array after
98 char tag_is_modifier_type(unsigned long tag)
102 case DW_TAG_pointer_type:
103 case DW_TAG_array_type:
104 case DW_TAG_const_type:
105 case DW_TAG_volatile_type:
115 Returns: 1 if tag = {DW_TAG_enumeration_type, _structure_type, _union_type},
117 Effects: Used to determine if the type is a collection of some sort -
118 collections have members and unique type names
120 char tag_is_collection_type(unsigned long tag)
124 case DW_TAG_enumeration_type:
125 case DW_TAG_structure_type:
126 case DW_TAG_union_type:
133 // The rest of these should be self-explanatory:
134 char tag_is_base_type(unsigned long tag)
136 return (tag == DW_TAG_base_type);
139 char tag_is_member(unsigned long tag)
141 return (tag == DW_TAG_member);
144 char tag_is_enumerator(unsigned long tag)
146 return (tag == DW_TAG_enumerator);
149 char tag_is_function(unsigned long tag)
151 return (tag == DW_TAG_subprogram);
154 char tag_is_formal_parameter(unsigned long tag)
156 return (tag == DW_TAG_formal_parameter);
159 char tag_is_compile_unit(unsigned long tag)
161 return (tag == DW_TAG_compile_unit);
164 char tag_is_function_type(unsigned long tag) {
165 return (tag == DW_TAG_subroutine_type);
172 // Each type stored in dwarf_entry.entry_ptr listens for particular
173 // attributes. e.g. collection_type listens for DW_AT_name and DW_AT_byte_size
175 // DW_AT_location: formal_parameter
176 // DW_AT_name: collection_type, member, enumerator, function, formal_parameter, compile_unit
177 // DW_AT_byte_size: base_type, collection_type, member
178 // DW_AT_bit_offset: base_type, member
179 // DW_AT_bit_size: base_type, member
180 // DW_AT_const_value: enumerator
181 // DW_AT_data_member_location: member
182 // DW_AT_type: modifier, member, function, formal_parameter
183 // DW_AT_encoding: base_type
184 // DW_AT_comp_dir: compile_unit
185 // DW_AT_external: function
186 // DW_AT_low_pc: function
188 // Returns: 1 if the entry has a type that is listening for the
189 // given attribute (attr), 0 otherwise
190 char entry_is_listening_for_attribute(dwarf_entry* e, unsigned long attr)
201 return tag_is_formal_parameter(tag);
203 return (tag_is_collection_type(tag) ||
204 tag_is_member(tag) ||
205 tag_is_enumerator(tag) ||
206 tag_is_function(tag) ||
207 tag_is_formal_parameter(tag) ||
208 tag_is_compile_unit(tag));
209 case DW_AT_byte_size:
210 return (tag_is_base_type(tag) ||
211 tag_is_collection_type(tag) ||
213 case DW_AT_bit_offset:
214 return (tag_is_base_type(tag) ||
217 return (tag_is_base_type(tag) ||
219 case DW_AT_const_value:
220 return tag_is_enumerator(tag);
221 case DW_AT_data_member_location:
222 return tag_is_member(tag)||tag==DW_TAG_inheritance;
224 return (tag_is_modifier_type(tag) ||
225 tag_is_member(tag) ||
226 tag_is_function(tag) ||
227 tag_is_formal_parameter(tag) ||
228 tag_is_function_type(tag)||
229 tag==DW_TAG_typedef||
230 tag==DW_TAG_const_type||
231 tag==DW_TAG_inheritance);
232 case DW_AT_upper_bound:
233 return (tag==DW_TAG_subrange_type);
235 return tag_is_base_type(tag);
237 return tag_is_compile_unit(tag);
239 return tag_is_function(tag);
241 return tag_is_function(tag);
250 // Harvest attribute values into the appropriate entry
251 // Returns a boolean to signal success or failure
252 // Remember to only harvest attribute value if the type is listening for it
254 char harvest_type_value(dwarf_entry* e, unsigned long value)
257 if ((e == 0) || (e->entry_ptr == 0))
262 if (tag ==DW_TAG_subrange_type) {
263 ((array_bound*)e->entry_ptr)->target_ID = value;
265 } else if (tag==DW_TAG_typedef) {
266 ((tdef*)e->entry_ptr)->target_ID = value;
268 } else if (tag==DW_TAG_inheritance) {
269 ((inherit*)e->entry_ptr)->target_ID = value;
271 } else if (tag==DW_TAG_const_type) {
272 ((consttype*)e->entry_ptr)->target_ID = value;
274 } else if (tag_is_modifier_type(tag))
276 ((modifier_type*)e->entry_ptr)->target_ID = value;
279 else if (tag_is_member(tag))
281 ((member*)e->entry_ptr)->type_ID = value;
284 else if (tag_is_function(tag))
286 ((function*)e->entry_ptr)->return_type_ID = value;
289 else if (tag_is_formal_parameter(tag))
291 ((formal_parameter*)e->entry_ptr)->type_ID = value;
294 else if (tag_is_function_type(tag))
296 ((function_type *)e->entry_ptr)->return_type_ID = value;
303 char harvest_byte_size_value(dwarf_entry* e, unsigned long value)
306 if ((e == 0) || (e->entry_ptr == 0))
311 if (tag_is_base_type(tag))
313 ((base_type*)e->entry_ptr)->byte_size = value;
316 else if (tag_is_collection_type(tag))
318 ((collection_type*)e->entry_ptr)->byte_size = value;
321 else if (tag_is_member(tag))
323 ((member*)e->entry_ptr)->byte_size = value;
330 char harvest_encoding_value(dwarf_entry* e, unsigned long value)
333 if ((e == 0) || (e->entry_ptr == 0))
338 if (tag_is_base_type(tag))
340 ((base_type*)e->entry_ptr)->encoding = value;
347 char harvest_bit_size_value(dwarf_entry* e, unsigned long value)
350 if ((e == 0) || (e->entry_ptr == 0))
355 if (tag_is_base_type(tag))
357 ((base_type*)e->entry_ptr)->bit_size = value;
360 else if (tag_is_member(tag))
362 ((member*)e->entry_ptr)->bit_size = value;
370 char harvest_bit_offset_value(dwarf_entry* e, unsigned long value)
373 if ((e == 0) || (e->entry_ptr == 0))
378 if (tag_is_base_type(tag))
380 ((base_type*)e->entry_ptr)->bit_offset = value;
383 else if (tag_is_member(tag))
385 ((member*)e->entry_ptr)->bit_offset = value;
392 char harvest_const_value(dwarf_entry* e, unsigned long value)
395 if ((e == 0) || (e->entry_ptr == 0))
400 if (tag_is_enumerator(tag))
402 ((enumerator*)e->entry_ptr)->const_value = value;
409 char harvest_upper_bound(dwarf_entry* e, unsigned long value)
412 if ((e == 0) || (e->entry_ptr == 0))
417 if (tag==DW_TAG_subrange_type)
419 ((array_bound*)e->entry_ptr)->upperbound = value;
426 // REMEMBER to use strdup to make a COPY of the string
427 // or else you will run into SERIOUS memory corruption
428 // problems when readelf.c frees those strings from memory!!!
429 char harvest_name(dwarf_entry* e, const char* str)
432 if ((e == 0) || (e->entry_ptr == 0))
437 if (tag_is_enumerator(tag))
439 ((enumerator*)e->entry_ptr)->name = strdup(str);
442 else if (tag_is_collection_type(tag))
444 ((collection_type*)e->entry_ptr)->name = strdup(str);
447 else if (tag_is_member(tag))
449 ((member*)e->entry_ptr)->name = strdup(str);
452 else if (tag_is_function(tag))
454 ((function*)e->entry_ptr)->name = strdup(str);
457 else if (tag_is_formal_parameter(tag))
459 ((formal_parameter*)e->entry_ptr)->name = strdup(str);
462 else if (tag_is_compile_unit(tag))
464 ((compile_unit*)e->entry_ptr)->filename = strdup(str);
471 char harvest_comp_dir(dwarf_entry* e, const char* str)
474 if ((e == 0) || (e->entry_ptr == 0))
479 if (tag_is_compile_unit(tag))
481 ((compile_unit*)e->entry_ptr)->comp_dir = strdup(str);
488 char harvest_location(dwarf_entry* e, long value)
491 if ((e == 0) || (e->entry_ptr == 0))
496 if (tag_is_formal_parameter(tag))
498 ((formal_parameter*)e->entry_ptr)->location = value;
505 char harvest_data_member_location(dwarf_entry* e, long value)
508 if ((e == 0) || (e->entry_ptr == 0))
513 if (tag_is_member(tag))
515 ((member*)e->entry_ptr)->data_member_location = value;
518 else if (tag==DW_TAG_inheritance) {
519 ((inherit*)e->entry_ptr)->data_member_location = value;
526 char harvest_string(dwarf_entry* e, unsigned long attr, const char* str)
528 if ((e == 0) || (e->entry_ptr == 0))
531 if (attr == DW_AT_name)
532 return harvest_name(e, str);
533 else if (attr == DW_AT_comp_dir)
534 return harvest_comp_dir(e, str);
539 char harvest_external_flag_value(dwarf_entry *e, unsigned long value) {
541 if ((e == 0) || (e->entry_ptr == 0))
546 if (tag_is_function(tag))
548 ((function*)e->entry_ptr)->is_external = value;
555 char harvest_address_value(dwarf_entry* e, unsigned long attr,
556 unsigned long value) {
558 if ((e == 0) || (e->entry_ptr == 0))
563 if (tag_is_function(tag) && attr == DW_AT_low_pc)
565 ((function*)e->entry_ptr)->start_pc = value;
573 char harvest_ordinary_unsigned_value(dwarf_entry* e, unsigned long attr, unsigned long value)
575 if ((e == 0) || (e->entry_ptr == 0))
579 // DW_AT_byte_size, DW_AT_encoding, DW_AT_const_value,
580 // DW_AT_bit_size, DW_AT_bit_offset and DW_AT_external
581 // return ordinary unsigned data
584 case DW_AT_byte_size:
585 return harvest_byte_size_value(e, value);
587 return harvest_encoding_value(e, value);
588 case DW_AT_const_value:
589 return harvest_const_value(e, value);
590 case DW_AT_upper_bound:
591 return harvest_upper_bound(e, value);
593 return harvest_bit_size_value(e, value);
594 case DW_AT_bit_offset:
595 return harvest_bit_offset_value(e, value);
597 return harvest_external_flag_value(e, value);
604 Requires: dwarf_entry_array initialized
607 Effects: Performs a binary search through dwarf_entry_array, looking for
608 the entry with the matching ID field (target_ID).
609 Stores the index of the matching entry in index_ptr
611 char binary_search_dwarf_entry_array(unsigned long target_ID, unsigned long* index_ptr)
613 unsigned long upper = dwarf_entry_array_size - 1;
614 unsigned long lower = 0;
616 // printf("--target_ID: 0x%x, index_ptr: 0x%x, upper.ID: 0x%x, lower.ID: 0x%x\n",
619 // dwarf_entry_array[upper].ID,
620 // dwarf_entry_array[lower].ID);
622 // First do boundary sanity check to save ourselves lots of useless work:
623 if ((target_ID > dwarf_entry_array[upper].ID) ||
624 (target_ID < dwarf_entry_array[lower].ID))
627 while (upper > lower)
629 unsigned long mid = (upper + lower) / 2;
630 unsigned long cur_ID = dwarf_entry_array[mid].ID;
632 // printf("**lower: %d, mid: %d, upper: %d, target_ID: 0x%x, cur_ID: 0x%x\n",
639 // Special case - (upper == (lower + 1)) - that means only 2 entries left to check:
640 if (upper == (lower + 1))
642 if (target_ID == dwarf_entry_array[lower].ID)
647 else if (target_ID == dwarf_entry_array[upper].ID)
654 // YOU LOSE! The target_ID is BETWEEN the lower and upper entries
658 else if (target_ID == cur_ID) // Right on!
663 else if (target_ID < cur_ID)
667 else if (target_ID > cur_ID)
673 // Return 0 if no answer found
678 Requires: dwarf_entry_array initialized
679 Modifies: certain fields within certain entries within dwarf_entry_array
680 (modifier_type::target_ptr, function::return_type,
681 member::type_ptr, formal_parameter::type_ptr)
683 Effects: Links every entry with a type_ID to the actual entry of that type
684 within dwarf_entry_array. Sets the appropriate type_ptr pointers to point
685 to entries within dwarf_entry_array where that type resides
686 (relevant for modifier_type, member, function, and formal_parameter entries)
688 void link_entries_to_type_entries()
691 dwarf_entry* cur_entry = 0;
693 for (idx = 0; idx < dwarf_entry_array_size; idx++)
696 cur_entry = &dwarf_entry_array[idx];
697 tag = cur_entry->tag_name;
699 if (tag_is_modifier_type(tag))
702 unsigned long target_index = 0;
703 modifier_type* modifier_ptr = (modifier_type*)(cur_entry->entry_ptr);
704 unsigned long target_ID = modifier_ptr->target_ID;
706 // Use a binary search to try to find the index of the entry in the
707 // array with the corresponding target_ID
708 success = binary_search_dwarf_entry_array(target_ID, &target_index);
711 modifier_ptr->target_ptr=&dwarf_entry_array[target_index];
713 if (tag==DW_TAG_array_type) {
714 int currentlevel=cur_entry->level;
715 dwarf_entry* tmp_entry = cur_entry+1;
716 int dist_to_end=dwarf_entry_array_size-idx;
718 while ((member_count < dist_to_end) // put this first! short-circuit eval.
719 && tmp_entry->level> currentlevel)
721 if (tmp_entry->tag_name==DW_TAG_subrange_type&&(tmp_entry->level==(currentlevel+1)))
725 modifier_ptr->array_ptr=(dwarf_entry**)calloc(1,member_count*sizeof(dwarf_entry*));
726 modifier_ptr->num_array=member_count;
728 tmp_entry=cur_entry+1;
729 while ((member_count < dist_to_end) // put this first! short-circuit eval.
730 && tmp_entry->level> currentlevel)
732 if (tmp_entry->tag_name==DW_TAG_subrange_type&&(tmp_entry->level==(currentlevel+1)))
733 modifier_ptr->array_ptr[member_count++]=tmp_entry;
738 else if (tag==DW_TAG_subrange_type) {
740 unsigned long target_index = 0;
741 array_bound* bound_ptr = (array_bound*)(cur_entry->entry_ptr);
742 unsigned long target_ID = bound_ptr->target_ID;
744 // Use a binary search to try to find the index of the entry in the
745 // array with the corresponding target_ID
746 success = binary_search_dwarf_entry_array(target_ID, &target_index);
749 bound_ptr->target_ptr=&dwarf_entry_array[target_index];
752 else if (tag==DW_TAG_typedef) {
754 unsigned long target_index = 0;
755 tdef* bound_ptr = (tdef*)(cur_entry->entry_ptr);
756 unsigned long target_ID = bound_ptr->target_ID;
758 // Use a binary search to try to find the index of the entry in the
759 // array with the corresponding target_ID
760 success = binary_search_dwarf_entry_array(target_ID, &target_index);
763 bound_ptr->target_ptr=&dwarf_entry_array[target_index];
766 else if (tag==DW_TAG_const_type) {
768 unsigned long target_index = 0;
769 consttype* bound_ptr = (consttype*)(cur_entry->entry_ptr);
770 unsigned long target_ID = bound_ptr->target_ID;
772 // Use a binary search to try to find the index of the entry in the
773 // array with the corresponding target_ID
774 success = binary_search_dwarf_entry_array(target_ID, &target_index);
777 bound_ptr->target_ptr=&dwarf_entry_array[target_index];
780 else if (tag==DW_TAG_inheritance) {
782 unsigned long target_index = 0;
783 inherit* bound_ptr = (inherit*)(cur_entry->entry_ptr);
784 unsigned long target_ID = bound_ptr->target_ID;
786 // Use a binary search to try to find the index of the entry in the
787 // array with the corresponding target_ID
788 success = binary_search_dwarf_entry_array(target_ID, &target_index);
791 bound_ptr->target_ptr=&dwarf_entry_array[target_index];
794 else if (tag_is_function(tag))
797 unsigned long target_index = 0;
798 function* function_ptr = (function*)(cur_entry->entry_ptr);
799 unsigned long target_ID = function_ptr->return_type_ID;
801 // Use a binary search to try to find the index of the entry in the
802 // array with the corresponding target_ID
803 success = binary_search_dwarf_entry_array(target_ID, &target_index);
806 function_ptr->return_type=&dwarf_entry_array[target_index];
809 else if (tag_is_function_type(tag))
812 unsigned long target_index = 0;
813 function_type *function_ptr
814 = (function_type *)(cur_entry->entry_ptr);
815 unsigned long target_ID = function_ptr->return_type_ID;
817 // Use a binary search to try to find the index of the entry in the
818 // array with the corresponding target_ID
819 success = binary_search_dwarf_entry_array(target_ID, &target_index);
822 function_ptr->return_type=&dwarf_entry_array[target_index];
825 else if (tag_is_member(tag))
828 unsigned long target_index = 0;
829 member* member_ptr = (member*)(cur_entry->entry_ptr);
830 unsigned long target_ID = member_ptr->type_ID;
832 // Use a binary search to try to find the index of the entry in the
833 // array with the corresponding target_ID
834 success = binary_search_dwarf_entry_array(target_ID, &target_index);
837 member_ptr->type_ptr=&dwarf_entry_array[target_index];
840 else if (tag_is_formal_parameter(tag))
843 unsigned long target_index = 0;
844 formal_parameter* formal_param_ptr = (formal_parameter*)(cur_entry->entry_ptr);
845 unsigned long target_ID = formal_param_ptr->type_ID;
847 // Use a binary search to try to find the index of the entry in the
848 // array with the corresponding target_ID
849 success = binary_search_dwarf_entry_array(target_ID, &target_index);
852 formal_param_ptr->type_ptr=&dwarf_entry_array[target_index];
859 Requires: dist_to_end indicates distance from e until end of dwarf_entry_array,
860 e points to an element of dwarf_entry_array
861 Modifies: e->num_members, e->members
863 Effects: Links the collection entry to its members, which are located
864 adjacent to it in the dwarf_entry array, making sure not to
865 accidentally segfault by indexing out of bounds
866 (indicated by dist_to_end param
867 which indicates distance until the end of the array)
869 void link_collection_to_members(dwarf_entry* e, unsigned long dist_to_end)
871 // 1. Figure out what kind of collection it is (struct, union, enumeration)
872 // 2. Traverse through subsequent entries, checking if the type_ID
873 // is the appropriate member type for that collection
874 // 3. Stop either when you hit a type_ID that is not a member OR
875 // when you are about to run out of array bounds
876 // 4. Store the subsequent array entry (e + 1) as pointer to first member
877 // (as long as its not out of bounds) and store the number of entries
878 // you traversed as the number of members
880 unsigned long member_count = 0;
881 unsigned int currentlevel=e->level;
882 dwarf_entry* cur_entry = e;
883 collection_type* collection_ptr = (collection_type*)(e->entry_ptr);
885 // If you are at the end of the array, you're screwed anyways
891 // enumerations expect DW_TAG_enumerator as members
892 case DW_TAG_enumeration_type:
893 cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
894 while ((member_count < dist_to_end) // put this first! short-circuit eval.
895 && cur_entry->level> currentlevel)
897 if (cur_entry->tag_name==DW_TAG_enumerator&&(cur_entry->level==(currentlevel+1)))
902 // structs and unions expect DW_TAG_member as members
903 case DW_TAG_structure_type:
904 case DW_TAG_union_type:
905 cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
906 while ((member_count < dist_to_end) // put this first! short-circuit eval.
907 && cur_entry->level>currentlevel)
909 if ((cur_entry->tag_name==DW_TAG_member||
910 cur_entry->tag_name==DW_TAG_inheritance)&&
911 cur_entry->level==(currentlevel+1))
920 collection_ptr->num_members = member_count;
921 collection_ptr->members = (dwarf_entry **)calloc(1,member_count*sizeof(dwarf_entry *));
927 // enumerations expect DW_TAG_enumerator as members
928 case DW_TAG_enumeration_type:
929 cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
930 while ((member_count < dist_to_end) // put this first! short-circuit eval.
931 && cur_entry->level> currentlevel)
933 if (cur_entry->tag_name==DW_TAG_enumerator&&(cur_entry->level==(currentlevel+1)))
934 collection_ptr->members[member_count++]=cur_entry;
938 // structs and unions expect DW_TAG_member as members
939 case DW_TAG_structure_type:
940 case DW_TAG_union_type:
941 cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
942 while ((member_count < dist_to_end) // put this first! short-circuit eval.
943 && cur_entry->level>currentlevel)
945 if ((cur_entry->tag_name==DW_TAG_member||
946 cur_entry->tag_name==DW_TAG_inheritance)
947 &&cur_entry->level==(currentlevel+1))
948 collection_ptr->members[member_count++]=cur_entry;
957 // Same as above except linking functions with formal parameters
958 void link_function_to_params(dwarf_entry* e, unsigned long dist_to_end)
960 unsigned long param_count = 0;
961 dwarf_entry* cur_entry = e;
962 function* function_ptr = (function*)(e->entry_ptr);
964 // If you are at the end of the array, you're screwed anyways
968 cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
969 // functions expect DW_TAG_formal_parameter as parameters
970 while ((param_count < dist_to_end) // important that this is first! short-circuit eval.
971 && cur_entry->tag_name == DW_TAG_formal_parameter)
977 function_ptr->num_formal_params = param_count;
978 function_ptr->params = (e + 1);
982 Requires: dwarf_entry_array is initialized
983 Modifies: ((function*)cur_entry->entry_ptr)->filename for function entries
985 Effects: Initialize the filename field of each function entry
986 by linearly traversing dwarf_entry_array and noting that every compile_unit
987 entry describes a file and all functions to the right of that entry
988 (but to the left of the next entry) belong to that file
989 e.g. [compile_unit foo.c][...][func1][...][func2][...][compile_unit bar.c][func3]
990 func1 and func2 belong to foo.c and func3 belongs to bar.c
992 void initialize_function_filenames()
996 dwarf_entry* cur_entry = 0;
998 for (idx = 0; idx < dwarf_entry_array_size; idx++)
1000 cur_entry = &dwarf_entry_array[idx];
1002 if (tag_is_compile_unit(cur_entry->tag_name))
1003 cur_file = ((compile_unit*)cur_entry->entry_ptr)->filename;
1004 else if (tag_is_function(cur_entry->tag_name))
1005 ((function*)cur_entry->entry_ptr)->filename = cur_file;
1010 Requires: dwarf_entry_array is initialized
1011 Modifies: function and collection entries within dwarf_entry_array
1013 Effects: Links function and collections entries to their respective members
1014 e.g. functions need to have a list of their formal parameters
1015 while structs, unions, and enumeration types need to have lists of members
1016 THIS ALGORITHM EXPLOITS THE FACT THAT MEMBERS/PARAMETERS ARE LISTED
1017 RIGHT AFTER THE RESPECTIVE FUNCTION OR STRUCT
1018 e.g. [function][param1][param2][param3][something_else]
1020 void link_array_entries_to_members()
1023 dwarf_entry* cur_entry = 0;
1025 // Linearly traverse the array and pick off function or collections
1026 // (struct, union, enumeration) entries to link to members:
1027 for (idx = 0; idx < dwarf_entry_array_size; idx++)
1029 cur_entry = &dwarf_entry_array[idx];
1030 if (tag_is_collection_type(cur_entry->tag_name))
1031 link_collection_to_members(cur_entry, dwarf_entry_array_size - idx - 1);
1032 else if (tag_is_function(cur_entry->tag_name))
1033 link_function_to_params(cur_entry, dwarf_entry_array_size - idx - 1);
1037 // Prints the contents of the entry depending on its type
1038 void print_dwarf_entry(dwarf_entry* e)
1042 printf("ERROR! Pointer e is null in print_dwarf_entry\n");
1046 printf("ID:0x%lx, TAG:%s\n", e->ID, get_TAG_name(e->tag_name));
1050 case DW_TAG_subprogram:
1052 function* function_ptr = (function*)(e->entry_ptr);
1053 printf(" Name: %s, Filename: %s, Return Type ID (addr): 0x%lx (%p), Num. params: %ld, 1st param addr: %p\n",
1055 function_ptr->filename,
1056 function_ptr->return_type_ID,
1057 function_ptr->return_type,
1058 function_ptr->num_formal_params,
1059 function_ptr->params);
1062 case DW_TAG_formal_parameter:
1064 formal_parameter* formal_param_ptr = (formal_parameter*)(e->entry_ptr);
1065 printf(" Name: %s, Type ID (addr): 0x%lx (%p), Location: %ld\n",
1066 formal_param_ptr->name,
1067 formal_param_ptr->type_ID,
1068 formal_param_ptr->type_ptr,
1069 formal_param_ptr->location);
1074 member* member_ptr = (member*)(e->entry_ptr);
1075 printf(" Name: %s, Type ID (addr): 0x%lx (%p), Data member location: %ld, Byte size: %ld, Bit offset: %ld, Bit size: %ld\n",
1077 member_ptr->type_ID,
1078 member_ptr->type_ptr,
1079 member_ptr->data_member_location,
1080 member_ptr->byte_size,
1081 member_ptr->bit_offset,
1082 member_ptr->bit_size);
1085 case DW_TAG_enumerator:
1087 enumerator* enumerator_ptr = (enumerator*)(e->entry_ptr);
1088 printf(" Name: %s, Const value: %ld\n",
1089 enumerator_ptr->name,
1090 enumerator_ptr->const_value);
1094 case DW_TAG_structure_type:
1095 case DW_TAG_union_type:
1096 case DW_TAG_enumeration_type:
1098 collection_type* collection_ptr = (collection_type*)(e->entry_ptr);
1099 printf(" Name: %s, Byte size: %ld, Num. members: %ld, 1st member addr: %p\n",
1100 collection_ptr->name,
1101 collection_ptr->byte_size,
1102 collection_ptr->num_members,
1103 collection_ptr->members);
1107 case DW_TAG_base_type:
1109 base_type* base_ptr = (base_type*)(e->entry_ptr);
1110 printf(" Byte size: %ld, Encoding: %ld ",
1111 base_ptr->byte_size,
1112 base_ptr->encoding);
1114 // More detailed encoding information
1115 switch (base_ptr->encoding)
1117 case DW_ATE_void: printf ("(void)"); break;
1118 case DW_ATE_address: printf ("(machine address)"); break;
1119 case DW_ATE_boolean: printf ("(boolean)"); break;
1120 case DW_ATE_complex_float: printf ("(complex float)"); break;
1121 case DW_ATE_float: printf ("(float)"); break;
1122 case DW_ATE_signed: printf ("(signed)"); break;
1123 case DW_ATE_signed_char: printf ("(signed char)"); break;
1124 case DW_ATE_unsigned: printf ("(unsigned)"); break;
1125 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
1126 /* DWARF 2.1 value. */
1127 case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
1129 if (base_ptr->encoding >= DW_ATE_lo_user
1130 && base_ptr->encoding <= DW_ATE_hi_user)
1132 printf ("(user defined type)");
1136 printf ("(unknown type)");
1141 printf(", Bit size: %ld, Bit offset: %ld\n",
1143 base_ptr->bit_offset);
1147 case DW_TAG_const_type:
1148 case DW_TAG_pointer_type:
1149 case DW_TAG_array_type:
1150 case DW_TAG_volatile_type:
1152 modifier_type* modifier_ptr = (modifier_type*)(e->entry_ptr);
1153 printf(" Target ID (addr): 0x%lx (%p)\n",
1154 modifier_ptr->target_ID,
1155 modifier_ptr->target_ptr);
1159 case DW_TAG_compile_unit:
1161 compile_unit* compile_ptr = (compile_unit*)(e->entry_ptr);
1162 printf(" Filename: %s, Compile dir: %s\n",
1163 compile_ptr->filename,
1164 compile_ptr->comp_dir);
1167 case DW_TAG_subroutine_type:
1169 function_type * func_type = (function_type *)(e->entry_ptr);
1170 printf(" Return type ID (addr): 0x%lx (%p)\n",
1171 func_type->return_type_ID, func_type->return_type);
1181 Modifies: dwarf_entry_array (initializes and blanks all entries to zero)
1183 Effects: Initializes sets up dwarf_entry_array to hold num_entries components
1185 void initialize_dwarf_entry_array(unsigned long num_entries)
1187 // use calloc to blank everything upon initialization
1188 dwarf_entry_array = calloc(num_entries, sizeof *dwarf_entry_array);
1192 Requires: dwarf_entry_array is initialized
1193 Modifies: dwarf_entry_array (free and set to 0)
1195 Effects: Destroys dwarf_entry_array and all entry_ptr fields of all entries
1197 void destroy_dwarf_entry_array()
1199 // Traverse the array and free the entry_ptr of all entries within array
1202 for (i = 0; i < dwarf_entry_array_size; i++)
1204 free(dwarf_entry_array[i].entry_ptr);
1207 // Free the array itself
1208 free(dwarf_entry_array);
1211 void print_dwarf_entry_array()
1214 printf("--- BEGIN DWARF ENTRY ARRAY - size: %ld\n", dwarf_entry_array_size);
1215 for (i = 0; i < dwarf_entry_array_size; i++)
1217 printf("array[%ld] (%p): ", i, dwarf_entry_array + i);
1218 print_dwarf_entry(&dwarf_entry_array[i]);
1220 printf("--- END DWARF ENTRY ARRAY\n");
1224 Requires: e is initialized and has a e->tag_name
1225 Modifies: e->entry_ptr (initializes and set to 0)
1227 Effects: Initialize the value of e->entry_ptr to the appropriate sub-type
1228 based on the value of tag_name
1229 If tag_name is 0, then don't do anything
1231 void initialize_dwarf_entry_ptr(dwarf_entry* e)
1235 if (tag_is_base_type(e->tag_name))
1237 e->entry_ptr = calloc(1, sizeof(base_type));
1239 else if (e->tag_name==DW_TAG_subrange_type) {
1240 e->entry_ptr=calloc(1,sizeof(array_bound));
1242 else if (e->tag_name==DW_TAG_typedef) {
1243 e->entry_ptr=calloc(1,sizeof(tdef));
1245 else if (e->tag_name==DW_TAG_inheritance) {
1246 e->entry_ptr=calloc(1,sizeof(inherit));
1248 else if (e->tag_name==DW_TAG_const_type) {
1249 e->entry_ptr=calloc(1,sizeof(consttype));
1251 else if (tag_is_modifier_type(e->tag_name))
1253 e->entry_ptr = calloc(1, sizeof(modifier_type));
1255 else if (tag_is_collection_type(e->tag_name))
1257 e->entry_ptr = calloc(1, sizeof(collection_type));
1259 else if (tag_is_member(e->tag_name))
1261 e->entry_ptr = calloc(1, sizeof(member));
1263 else if (tag_is_enumerator(e->tag_name))
1265 e->entry_ptr = calloc(1, sizeof(enumerator));
1267 else if (tag_is_function(e->tag_name))
1269 e->entry_ptr = calloc(1, sizeof(function));
1271 else if (tag_is_formal_parameter(e->tag_name))
1273 e->entry_ptr = calloc(1, sizeof(formal_parameter));
1275 else if (tag_is_compile_unit(e->tag_name))
1277 e->entry_ptr = calloc(1, sizeof(compile_unit));
1279 else if (tag_is_function_type(e->tag_name))
1281 e->entry_ptr = calloc(1, sizeof(function_type));
1286 // Now that dwarf_entry_array is initialized with values, we must link
1287 // the entries together in a coherent manner
1288 void finish_dwarf_entry_array_init(void)
1290 // These must be done in this order or else things will go screwy!!!
1291 link_array_entries_to_members();
1292 initialize_function_filenames();
1293 link_entries_to_type_entries();