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==DW_TAG_typedef||
206 tag_is_enumerator(tag) ||
207 tag_is_function(tag) ||
208 tag_is_formal_parameter(tag) ||
209 tag_is_compile_unit(tag));
210 case DW_AT_byte_size:
211 return (tag_is_base_type(tag) ||
212 tag_is_collection_type(tag) ||
214 case DW_AT_bit_offset:
215 return (tag_is_base_type(tag) ||
218 return (tag_is_base_type(tag) ||
220 case DW_AT_const_value:
221 return tag_is_enumerator(tag);
222 case DW_AT_data_member_location:
223 return tag_is_member(tag)||tag==DW_TAG_inheritance;
225 return (tag_is_modifier_type(tag) ||
226 tag_is_member(tag) ||
227 tag_is_function(tag) ||
228 tag_is_formal_parameter(tag) ||
229 tag_is_function_type(tag)||
230 tag==DW_TAG_typedef||
231 tag==DW_TAG_const_type||
232 tag==DW_TAG_inheritance);
233 case DW_AT_upper_bound:
234 return (tag==DW_TAG_subrange_type);
236 return tag_is_base_type(tag);
238 return tag_is_compile_unit(tag);
240 return tag_is_function(tag);
242 return tag_is_function(tag);
251 // Harvest attribute values into the appropriate entry
252 // Returns a boolean to signal success or failure
253 // Remember to only harvest attribute value if the type is listening for it
255 char harvest_type_value(dwarf_entry* e, unsigned long value)
258 if ((e == 0) || (e->entry_ptr == 0))
263 if (tag ==DW_TAG_subrange_type) {
264 ((array_bound*)e->entry_ptr)->target_ID = value;
266 } else if (tag==DW_TAG_typedef) {
267 ((tdef*)e->entry_ptr)->target_ID = value;
269 } else if (tag==DW_TAG_inheritance) {
270 ((inherit*)e->entry_ptr)->target_ID = value;
272 } else if (tag==DW_TAG_const_type) {
273 ((consttype*)e->entry_ptr)->target_ID = value;
275 } else if (tag_is_modifier_type(tag))
277 ((modifier_type*)e->entry_ptr)->target_ID = value;
280 else if (tag_is_member(tag))
282 ((member*)e->entry_ptr)->type_ID = value;
285 else if (tag_is_function(tag))
287 ((function*)e->entry_ptr)->return_type_ID = value;
290 else if (tag_is_formal_parameter(tag))
292 ((formal_parameter*)e->entry_ptr)->type_ID = value;
295 else if (tag_is_function_type(tag))
297 ((function_type *)e->entry_ptr)->return_type_ID = value;
304 char harvest_byte_size_value(dwarf_entry* e, unsigned long value)
307 if ((e == 0) || (e->entry_ptr == 0))
312 if (tag_is_base_type(tag))
314 ((base_type*)e->entry_ptr)->byte_size = value;
317 else if (tag_is_collection_type(tag))
319 ((collection_type*)e->entry_ptr)->byte_size = value;
322 else if (tag_is_member(tag))
324 ((member*)e->entry_ptr)->byte_size = value;
331 char harvest_encoding_value(dwarf_entry* e, unsigned long value)
334 if ((e == 0) || (e->entry_ptr == 0))
339 if (tag_is_base_type(tag))
341 ((base_type*)e->entry_ptr)->encoding = value;
348 char harvest_bit_size_value(dwarf_entry* e, unsigned long value)
351 if ((e == 0) || (e->entry_ptr == 0))
356 if (tag_is_base_type(tag))
358 ((base_type*)e->entry_ptr)->bit_size = value;
361 else if (tag_is_member(tag))
363 ((member*)e->entry_ptr)->bit_size = value;
371 char harvest_bit_offset_value(dwarf_entry* e, unsigned long value)
374 if ((e == 0) || (e->entry_ptr == 0))
379 if (tag_is_base_type(tag))
381 ((base_type*)e->entry_ptr)->bit_offset = value;
384 else if (tag_is_member(tag))
386 ((member*)e->entry_ptr)->bit_offset = value;
393 char harvest_const_value(dwarf_entry* e, unsigned long value)
396 if ((e == 0) || (e->entry_ptr == 0))
401 if (tag_is_enumerator(tag))
403 ((enumerator*)e->entry_ptr)->const_value = value;
410 char harvest_upper_bound(dwarf_entry* e, unsigned long value)
413 if ((e == 0) || (e->entry_ptr == 0))
418 if (tag==DW_TAG_subrange_type)
420 ((array_bound*)e->entry_ptr)->upperbound = value;
427 // REMEMBER to use strdup to make a COPY of the string
428 // or else you will run into SERIOUS memory corruption
429 // problems when readelf.c frees those strings from memory!!!
430 char harvest_name(dwarf_entry* e, const char* str)
433 if ((e == 0) || (e->entry_ptr == 0))
438 if (tag_is_enumerator(tag))
440 ((enumerator*)e->entry_ptr)->name = strdup(str);
443 else if (tag==DW_TAG_typedef)
445 ((tdef*)e->entry_ptr)->name = strdup(str);
448 else if (tag_is_collection_type(tag))
450 ((collection_type*)e->entry_ptr)->name = strdup(str);
453 else if (tag_is_member(tag))
455 ((member*)e->entry_ptr)->name = strdup(str);
458 else if (tag_is_function(tag))
460 ((function*)e->entry_ptr)->name = strdup(str);
463 else if (tag_is_formal_parameter(tag))
465 ((formal_parameter*)e->entry_ptr)->name = strdup(str);
468 else if (tag_is_compile_unit(tag))
470 ((compile_unit*)e->entry_ptr)->filename = strdup(str);
477 char harvest_comp_dir(dwarf_entry* e, const char* str)
480 if ((e == 0) || (e->entry_ptr == 0))
485 if (tag_is_compile_unit(tag))
487 ((compile_unit*)e->entry_ptr)->comp_dir = strdup(str);
494 char harvest_location(dwarf_entry* e, long value)
497 if ((e == 0) || (e->entry_ptr == 0))
502 if (tag_is_formal_parameter(tag))
504 ((formal_parameter*)e->entry_ptr)->location = value;
511 char harvest_data_member_location(dwarf_entry* e, long value)
514 if ((e == 0) || (e->entry_ptr == 0))
519 if (tag_is_member(tag))
521 ((member*)e->entry_ptr)->data_member_location = value;
524 else if (tag==DW_TAG_inheritance) {
525 ((inherit*)e->entry_ptr)->data_member_location = value;
532 char harvest_string(dwarf_entry* e, unsigned long attr, const char* str)
534 if ((e == 0) || (e->entry_ptr == 0))
537 if (attr == DW_AT_name)
538 return harvest_name(e, str);
539 else if (attr == DW_AT_comp_dir)
540 return harvest_comp_dir(e, str);
545 char harvest_external_flag_value(dwarf_entry *e, unsigned long value) {
547 if ((e == 0) || (e->entry_ptr == 0))
552 if (tag_is_function(tag))
554 ((function*)e->entry_ptr)->is_external = value;
561 char harvest_address_value(dwarf_entry* e, unsigned long attr,
562 unsigned long value) {
564 if ((e == 0) || (e->entry_ptr == 0))
569 if (tag_is_function(tag) && attr == DW_AT_low_pc)
571 ((function*)e->entry_ptr)->start_pc = value;
579 char harvest_ordinary_unsigned_value(dwarf_entry* e, unsigned long attr, unsigned long value)
581 if ((e == 0) || (e->entry_ptr == 0))
585 // DW_AT_byte_size, DW_AT_encoding, DW_AT_const_value,
586 // DW_AT_bit_size, DW_AT_bit_offset and DW_AT_external
587 // return ordinary unsigned data
590 case DW_AT_byte_size:
591 return harvest_byte_size_value(e, value);
593 return harvest_encoding_value(e, value);
594 case DW_AT_const_value:
595 return harvest_const_value(e, value);
596 case DW_AT_upper_bound:
597 return harvest_upper_bound(e, value);
599 return harvest_bit_size_value(e, value);
600 case DW_AT_bit_offset:
601 return harvest_bit_offset_value(e, value);
603 return harvest_external_flag_value(e, value);
610 Requires: dwarf_entry_array initialized
613 Effects: Performs a binary search through dwarf_entry_array, looking for
614 the entry with the matching ID field (target_ID).
615 Stores the index of the matching entry in index_ptr
617 char binary_search_dwarf_entry_array(unsigned long target_ID, unsigned long* index_ptr)
619 unsigned long upper = dwarf_entry_array_size - 1;
620 unsigned long lower = 0;
622 // printf("--target_ID: 0x%x, index_ptr: 0x%x, upper.ID: 0x%x, lower.ID: 0x%x\n",
625 // dwarf_entry_array[upper].ID,
626 // dwarf_entry_array[lower].ID);
628 // First do boundary sanity check to save ourselves lots of useless work:
629 if ((target_ID > dwarf_entry_array[upper].ID) ||
630 (target_ID < dwarf_entry_array[lower].ID))
633 while (upper > lower)
635 unsigned long mid = (upper + lower) / 2;
636 unsigned long cur_ID = dwarf_entry_array[mid].ID;
638 // printf("**lower: %d, mid: %d, upper: %d, target_ID: 0x%x, cur_ID: 0x%x\n",
645 // Special case - (upper == (lower + 1)) - that means only 2 entries left to check:
646 if (upper == (lower + 1))
648 if (target_ID == dwarf_entry_array[lower].ID)
653 else if (target_ID == dwarf_entry_array[upper].ID)
660 // YOU LOSE! The target_ID is BETWEEN the lower and upper entries
664 else if (target_ID == cur_ID) // Right on!
669 else if (target_ID < cur_ID)
673 else if (target_ID > cur_ID)
679 // Return 0 if no answer found
684 Requires: dwarf_entry_array initialized
685 Modifies: certain fields within certain entries within dwarf_entry_array
686 (modifier_type::target_ptr, function::return_type,
687 member::type_ptr, formal_parameter::type_ptr)
689 Effects: Links every entry with a type_ID to the actual entry of that type
690 within dwarf_entry_array. Sets the appropriate type_ptr pointers to point
691 to entries within dwarf_entry_array where that type resides
692 (relevant for modifier_type, member, function, and formal_parameter entries)
694 void link_entries_to_type_entries()
697 dwarf_entry* cur_entry = 0;
699 for (idx = 0; idx < dwarf_entry_array_size; idx++)
702 cur_entry = &dwarf_entry_array[idx];
703 tag = cur_entry->tag_name;
705 if (tag_is_modifier_type(tag))
708 unsigned long target_index = 0;
709 modifier_type* modifier_ptr = (modifier_type*)(cur_entry->entry_ptr);
710 unsigned long target_ID = modifier_ptr->target_ID;
712 // Use a binary search to try to find the index of the entry in the
713 // array with the corresponding target_ID
714 success = binary_search_dwarf_entry_array(target_ID, &target_index);
717 modifier_ptr->target_ptr=&dwarf_entry_array[target_index];
719 if (tag==DW_TAG_array_type) {
720 int currentlevel=cur_entry->level;
721 dwarf_entry* tmp_entry = cur_entry+1;
722 int dist_to_end=dwarf_entry_array_size-idx;
724 while ((member_count < dist_to_end) // put this first! short-circuit eval.
725 && tmp_entry->level> currentlevel)
727 if (tmp_entry->tag_name==DW_TAG_subrange_type&&(tmp_entry->level==(currentlevel+1)))
731 modifier_ptr->array_ptr=(dwarf_entry**)calloc(1,member_count*sizeof(dwarf_entry*));
732 modifier_ptr->num_array=member_count;
734 tmp_entry=cur_entry+1;
735 while ((member_count < dist_to_end) // put this first! short-circuit eval.
736 && tmp_entry->level> currentlevel)
738 if (tmp_entry->tag_name==DW_TAG_subrange_type&&(tmp_entry->level==(currentlevel+1)))
739 modifier_ptr->array_ptr[member_count++]=tmp_entry;
744 else if (tag==DW_TAG_subrange_type) {
746 unsigned long target_index = 0;
747 array_bound* bound_ptr = (array_bound*)(cur_entry->entry_ptr);
748 unsigned long target_ID = bound_ptr->target_ID;
750 // Use a binary search to try to find the index of the entry in the
751 // array with the corresponding target_ID
752 success = binary_search_dwarf_entry_array(target_ID, &target_index);
755 bound_ptr->target_ptr=&dwarf_entry_array[target_index];
758 else if (tag==DW_TAG_typedef) {
760 unsigned long target_index = 0;
761 tdef* bound_ptr = (tdef*)(cur_entry->entry_ptr);
762 unsigned long target_ID = bound_ptr->target_ID;
764 // Use a binary search to try to find the index of the entry in the
765 // array with the corresponding target_ID
766 success = binary_search_dwarf_entry_array(target_ID, &target_index);
769 bound_ptr->target_ptr=&dwarf_entry_array[target_index];
772 else if (tag==DW_TAG_const_type) {
774 unsigned long target_index = 0;
775 consttype* bound_ptr = (consttype*)(cur_entry->entry_ptr);
776 unsigned long target_ID = bound_ptr->target_ID;
778 // Use a binary search to try to find the index of the entry in the
779 // array with the corresponding target_ID
780 success = binary_search_dwarf_entry_array(target_ID, &target_index);
783 bound_ptr->target_ptr=&dwarf_entry_array[target_index];
786 else if (tag==DW_TAG_inheritance) {
788 unsigned long target_index = 0;
789 inherit* bound_ptr = (inherit*)(cur_entry->entry_ptr);
790 unsigned long target_ID = bound_ptr->target_ID;
792 // Use a binary search to try to find the index of the entry in the
793 // array with the corresponding target_ID
794 success = binary_search_dwarf_entry_array(target_ID, &target_index);
797 bound_ptr->target_ptr=&dwarf_entry_array[target_index];
800 else if (tag_is_function(tag))
803 unsigned long target_index = 0;
804 function* function_ptr = (function*)(cur_entry->entry_ptr);
805 unsigned long target_ID = function_ptr->return_type_ID;
807 // Use a binary search to try to find the index of the entry in the
808 // array with the corresponding target_ID
809 success = binary_search_dwarf_entry_array(target_ID, &target_index);
812 function_ptr->return_type=&dwarf_entry_array[target_index];
815 else if (tag_is_function_type(tag))
818 unsigned long target_index = 0;
819 function_type *function_ptr
820 = (function_type *)(cur_entry->entry_ptr);
821 unsigned long target_ID = function_ptr->return_type_ID;
823 // Use a binary search to try to find the index of the entry in the
824 // array with the corresponding target_ID
825 success = binary_search_dwarf_entry_array(target_ID, &target_index);
828 function_ptr->return_type=&dwarf_entry_array[target_index];
831 else if (tag_is_member(tag))
834 unsigned long target_index = 0;
835 member* member_ptr = (member*)(cur_entry->entry_ptr);
836 unsigned long target_ID = member_ptr->type_ID;
838 // Use a binary search to try to find the index of the entry in the
839 // array with the corresponding target_ID
840 success = binary_search_dwarf_entry_array(target_ID, &target_index);
843 member_ptr->type_ptr=&dwarf_entry_array[target_index];
846 else if (tag_is_formal_parameter(tag))
849 unsigned long target_index = 0;
850 formal_parameter* formal_param_ptr = (formal_parameter*)(cur_entry->entry_ptr);
851 unsigned long target_ID = formal_param_ptr->type_ID;
853 // Use a binary search to try to find the index of the entry in the
854 // array with the corresponding target_ID
855 success = binary_search_dwarf_entry_array(target_ID, &target_index);
858 formal_param_ptr->type_ptr=&dwarf_entry_array[target_index];
865 Requires: dist_to_end indicates distance from e until end of dwarf_entry_array,
866 e points to an element of dwarf_entry_array
867 Modifies: e->num_members, e->members
869 Effects: Links the collection entry to its members, which are located
870 adjacent to it in the dwarf_entry array, making sure not to
871 accidentally segfault by indexing out of bounds
872 (indicated by dist_to_end param
873 which indicates distance until the end of the array)
875 void link_collection_to_members(dwarf_entry* e, unsigned long dist_to_end)
877 // 1. Figure out what kind of collection it is (struct, union, enumeration)
878 // 2. Traverse through subsequent entries, checking if the type_ID
879 // is the appropriate member type for that collection
880 // 3. Stop either when you hit a type_ID that is not a member OR
881 // when you are about to run out of array bounds
882 // 4. Store the subsequent array entry (e + 1) as pointer to first member
883 // (as long as its not out of bounds) and store the number of entries
884 // you traversed as the number of members
886 unsigned long member_count = 0;
887 unsigned int currentlevel=e->level;
888 dwarf_entry* cur_entry = e;
889 collection_type* collection_ptr = (collection_type*)(e->entry_ptr);
891 // If you are at the end of the array, you're screwed anyways
897 // enumerations expect DW_TAG_enumerator as members
898 case DW_TAG_enumeration_type:
899 cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
900 while ((member_count < dist_to_end) // put this first! short-circuit eval.
901 && cur_entry->level> currentlevel)
903 if (cur_entry->tag_name==DW_TAG_enumerator&&(cur_entry->level==(currentlevel+1)))
908 // structs and unions expect DW_TAG_member as members
909 case DW_TAG_structure_type:
910 case DW_TAG_union_type:
911 cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
912 while ((member_count < dist_to_end) // put this first! short-circuit eval.
913 && cur_entry->level>currentlevel)
915 if ((cur_entry->tag_name==DW_TAG_member||
916 cur_entry->tag_name==DW_TAG_inheritance)&&
917 cur_entry->level==(currentlevel+1))
926 collection_ptr->num_members = member_count;
927 collection_ptr->members = (dwarf_entry **)calloc(1,member_count*sizeof(dwarf_entry *));
933 // enumerations expect DW_TAG_enumerator as members
934 case DW_TAG_enumeration_type:
935 cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
936 while ((member_count < dist_to_end) // put this first! short-circuit eval.
937 && cur_entry->level> currentlevel)
939 if (cur_entry->tag_name==DW_TAG_enumerator&&(cur_entry->level==(currentlevel+1)))
940 collection_ptr->members[member_count++]=cur_entry;
944 // structs and unions expect DW_TAG_member as members
945 case DW_TAG_structure_type:
946 case DW_TAG_union_type:
947 cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
948 while ((member_count < dist_to_end) // put this first! short-circuit eval.
949 && cur_entry->level>currentlevel)
951 if ((cur_entry->tag_name==DW_TAG_member||
952 cur_entry->tag_name==DW_TAG_inheritance)
953 &&cur_entry->level==(currentlevel+1))
954 collection_ptr->members[member_count++]=cur_entry;
963 // Same as above except linking functions with formal parameters
964 void link_function_to_params(dwarf_entry* e, unsigned long dist_to_end)
966 unsigned long param_count = 0;
967 dwarf_entry* cur_entry = e;
968 function* function_ptr = (function*)(e->entry_ptr);
970 // If you are at the end of the array, you're screwed anyways
974 cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
975 // functions expect DW_TAG_formal_parameter as parameters
976 while ((param_count < dist_to_end) // important that this is first! short-circuit eval.
977 && cur_entry->tag_name == DW_TAG_formal_parameter)
983 function_ptr->num_formal_params = param_count;
984 function_ptr->params = (e + 1);
988 Requires: dwarf_entry_array is initialized
989 Modifies: ((function*)cur_entry->entry_ptr)->filename for function entries
991 Effects: Initialize the filename field of each function entry
992 by linearly traversing dwarf_entry_array and noting that every compile_unit
993 entry describes a file and all functions to the right of that entry
994 (but to the left of the next entry) belong to that file
995 e.g. [compile_unit foo.c][...][func1][...][func2][...][compile_unit bar.c][func3]
996 func1 and func2 belong to foo.c and func3 belongs to bar.c
998 void initialize_function_filenames()
1002 dwarf_entry* cur_entry = 0;
1004 for (idx = 0; idx < dwarf_entry_array_size; idx++)
1006 cur_entry = &dwarf_entry_array[idx];
1008 if (tag_is_compile_unit(cur_entry->tag_name))
1009 cur_file = ((compile_unit*)cur_entry->entry_ptr)->filename;
1010 else if (tag_is_function(cur_entry->tag_name))
1011 ((function*)cur_entry->entry_ptr)->filename = cur_file;
1016 Requires: dwarf_entry_array is initialized
1017 Modifies: function and collection entries within dwarf_entry_array
1019 Effects: Links function and collections entries to their respective members
1020 e.g. functions need to have a list of their formal parameters
1021 while structs, unions, and enumeration types need to have lists of members
1022 THIS ALGORITHM EXPLOITS THE FACT THAT MEMBERS/PARAMETERS ARE LISTED
1023 RIGHT AFTER THE RESPECTIVE FUNCTION OR STRUCT
1024 e.g. [function][param1][param2][param3][something_else]
1026 void link_array_entries_to_members()
1029 dwarf_entry* cur_entry = 0;
1031 // Linearly traverse the array and pick off function or collections
1032 // (struct, union, enumeration) entries to link to members:
1033 for (idx = 0; idx < dwarf_entry_array_size; idx++)
1035 cur_entry = &dwarf_entry_array[idx];
1036 if (tag_is_collection_type(cur_entry->tag_name))
1037 link_collection_to_members(cur_entry, dwarf_entry_array_size - idx - 1);
1038 else if (tag_is_function(cur_entry->tag_name))
1039 link_function_to_params(cur_entry, dwarf_entry_array_size - idx - 1);
1043 // Prints the contents of the entry depending on its type
1044 void print_dwarf_entry(dwarf_entry* e)
1048 printf("ERROR! Pointer e is null in print_dwarf_entry\n");
1052 printf("ID:0x%lx, TAG:%s\n", e->ID, get_TAG_name(e->tag_name));
1056 case DW_TAG_subprogram:
1058 function* function_ptr = (function*)(e->entry_ptr);
1059 printf(" Name: %s, Filename: %s, Return Type ID (addr): 0x%lx (%p), Num. params: %ld, 1st param addr: %p\n",
1061 function_ptr->filename,
1062 function_ptr->return_type_ID,
1063 function_ptr->return_type,
1064 function_ptr->num_formal_params,
1065 function_ptr->params);
1068 case DW_TAG_formal_parameter:
1070 formal_parameter* formal_param_ptr = (formal_parameter*)(e->entry_ptr);
1071 printf(" Name: %s, Type ID (addr): 0x%lx (%p), Location: %ld\n",
1072 formal_param_ptr->name,
1073 formal_param_ptr->type_ID,
1074 formal_param_ptr->type_ptr,
1075 formal_param_ptr->location);
1080 member* member_ptr = (member*)(e->entry_ptr);
1081 printf(" Name: %s, Type ID (addr): 0x%lx (%p), Data member location: %ld, Byte size: %ld, Bit offset: %ld, Bit size: %ld\n",
1083 member_ptr->type_ID,
1084 member_ptr->type_ptr,
1085 member_ptr->data_member_location,
1086 member_ptr->byte_size,
1087 member_ptr->bit_offset,
1088 member_ptr->bit_size);
1091 case DW_TAG_enumerator:
1093 enumerator* enumerator_ptr = (enumerator*)(e->entry_ptr);
1094 printf(" Name: %s, Const value: %ld\n",
1095 enumerator_ptr->name,
1096 enumerator_ptr->const_value);
1100 case DW_TAG_structure_type:
1101 case DW_TAG_union_type:
1102 case DW_TAG_enumeration_type:
1104 collection_type* collection_ptr = (collection_type*)(e->entry_ptr);
1105 printf(" Name: %s, Byte size: %ld, Num. members: %ld, 1st member addr: %p\n",
1106 collection_ptr->name,
1107 collection_ptr->byte_size,
1108 collection_ptr->num_members,
1109 collection_ptr->members);
1113 case DW_TAG_base_type:
1115 base_type* base_ptr = (base_type*)(e->entry_ptr);
1116 printf(" Byte size: %ld, Encoding: %ld ",
1117 base_ptr->byte_size,
1118 base_ptr->encoding);
1120 // More detailed encoding information
1121 switch (base_ptr->encoding)
1123 case DW_ATE_void: printf ("(void)"); break;
1124 case DW_ATE_address: printf ("(machine address)"); break;
1125 case DW_ATE_boolean: printf ("(boolean)"); break;
1126 case DW_ATE_complex_float: printf ("(complex float)"); break;
1127 case DW_ATE_float: printf ("(float)"); break;
1128 case DW_ATE_signed: printf ("(signed)"); break;
1129 case DW_ATE_signed_char: printf ("(signed char)"); break;
1130 case DW_ATE_unsigned: printf ("(unsigned)"); break;
1131 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
1132 /* DWARF 2.1 value. */
1133 case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
1135 if (base_ptr->encoding >= DW_ATE_lo_user
1136 && base_ptr->encoding <= DW_ATE_hi_user)
1138 printf ("(user defined type)");
1142 printf ("(unknown type)");
1147 printf(", Bit size: %ld, Bit offset: %ld\n",
1149 base_ptr->bit_offset);
1153 case DW_TAG_const_type:
1154 case DW_TAG_pointer_type:
1155 case DW_TAG_array_type:
1156 case DW_TAG_volatile_type:
1158 modifier_type* modifier_ptr = (modifier_type*)(e->entry_ptr);
1159 printf(" Target ID (addr): 0x%lx (%p)\n",
1160 modifier_ptr->target_ID,
1161 modifier_ptr->target_ptr);
1165 case DW_TAG_compile_unit:
1167 compile_unit* compile_ptr = (compile_unit*)(e->entry_ptr);
1168 printf(" Filename: %s, Compile dir: %s\n",
1169 compile_ptr->filename,
1170 compile_ptr->comp_dir);
1173 case DW_TAG_subroutine_type:
1175 function_type * func_type = (function_type *)(e->entry_ptr);
1176 printf(" Return type ID (addr): 0x%lx (%p)\n",
1177 func_type->return_type_ID, func_type->return_type);
1187 Modifies: dwarf_entry_array (initializes and blanks all entries to zero)
1189 Effects: Initializes sets up dwarf_entry_array to hold num_entries components
1191 void initialize_dwarf_entry_array(unsigned long num_entries)
1193 // use calloc to blank everything upon initialization
1194 dwarf_entry_array = calloc(num_entries, sizeof *dwarf_entry_array);
1198 Requires: dwarf_entry_array is initialized
1199 Modifies: dwarf_entry_array (free and set to 0)
1201 Effects: Destroys dwarf_entry_array and all entry_ptr fields of all entries
1203 void destroy_dwarf_entry_array()
1205 // Traverse the array and free the entry_ptr of all entries within array
1208 for (i = 0; i < dwarf_entry_array_size; i++)
1210 free(dwarf_entry_array[i].entry_ptr);
1213 // Free the array itself
1214 free(dwarf_entry_array);
1217 void print_dwarf_entry_array()
1220 printf("--- BEGIN DWARF ENTRY ARRAY - size: %ld\n", dwarf_entry_array_size);
1221 for (i = 0; i < dwarf_entry_array_size; i++)
1223 printf("array[%ld] (%p): ", i, dwarf_entry_array + i);
1224 print_dwarf_entry(&dwarf_entry_array[i]);
1226 printf("--- END DWARF ENTRY ARRAY\n");
1230 Requires: e is initialized and has a e->tag_name
1231 Modifies: e->entry_ptr (initializes and set to 0)
1233 Effects: Initialize the value of e->entry_ptr to the appropriate sub-type
1234 based on the value of tag_name
1235 If tag_name is 0, then don't do anything
1237 void initialize_dwarf_entry_ptr(dwarf_entry* e)
1241 if (tag_is_base_type(e->tag_name))
1243 e->entry_ptr = calloc(1, sizeof(base_type));
1245 else if (e->tag_name==DW_TAG_subrange_type) {
1246 e->entry_ptr=calloc(1,sizeof(array_bound));
1248 else if (e->tag_name==DW_TAG_typedef) {
1249 e->entry_ptr=calloc(1,sizeof(tdef));
1251 else if (e->tag_name==DW_TAG_inheritance) {
1252 e->entry_ptr=calloc(1,sizeof(inherit));
1254 else if (e->tag_name==DW_TAG_const_type) {
1255 e->entry_ptr=calloc(1,sizeof(consttype));
1257 else if (tag_is_modifier_type(e->tag_name))
1259 e->entry_ptr = calloc(1, sizeof(modifier_type));
1261 else if (tag_is_collection_type(e->tag_name))
1263 e->entry_ptr = calloc(1, sizeof(collection_type));
1265 else if (tag_is_member(e->tag_name))
1267 e->entry_ptr = calloc(1, sizeof(member));
1269 else if (tag_is_enumerator(e->tag_name))
1271 e->entry_ptr = calloc(1, sizeof(enumerator));
1273 else if (tag_is_function(e->tag_name))
1275 e->entry_ptr = calloc(1, sizeof(function));
1277 else if (tag_is_formal_parameter(e->tag_name))
1279 e->entry_ptr = calloc(1, sizeof(formal_parameter));
1281 else if (tag_is_compile_unit(e->tag_name))
1283 e->entry_ptr = calloc(1, sizeof(compile_unit));
1285 else if (tag_is_function_type(e->tag_name))
1287 e->entry_ptr = calloc(1, sizeof(function_type));
1292 // Now that dwarf_entry_array is initialized with values, we must link
1293 // the entries together in a coherent manner
1294 void finish_dwarf_entry_array_init(void)
1296 // These must be done in this order or else things will go screwy!!!
1297 link_array_entries_to_members();
1298 initialize_function_filenames();
1299 link_entries_to_type_entries();