1 /* Copyright (C) 2007-2010 The Android Open Source Project
2 **
3 ** This software is licensed under the terms of the GNU General Public
4 ** License version 2, as published by the Free Software Foundation, and
5 ** may be copied, distributed, and modified under those terms.
6 **
7 ** This program is distributed in the hope that it will be useful,
8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 ** GNU General Public License for more details.
11 */
12 
13 /*
14  * Contains implementation of misc. DWARF utility routines.
15  */
16 
17 #include <stdio.h>
18 #define __STDC_FORMAT_MACROS 1
19 #include <inttypes.h>
20 #include "dwarf_utils.h"
21 
22 /* "Stringifies" the parameter. */
23 #define DWARF_NAMEFY(val) case val: return "" #val ""
24 
25 /* "Stringifies" two parameters. */
26 #define DWARF_NAMEFY2(val1, val2) case val1: return "" #val1 " | " #val2 ""
27 
28 const char*
dwarf_at_name(Dwarf_At at)29 dwarf_at_name(Dwarf_At at) {
30   switch (at) {
31     DWARF_NAMEFY(DW_AT_sibling);
32     DWARF_NAMEFY(DW_AT_location);
33     DWARF_NAMEFY(DW_AT_name);
34     DWARF_NAMEFY(DW_AT_ordering);
35     DWARF_NAMEFY(DW_AT_subscr_data);
36     DWARF_NAMEFY(DW_AT_byte_size);
37     DWARF_NAMEFY(DW_AT_bit_offset);
38     DWARF_NAMEFY(DW_AT_bit_size);
39     DWARF_NAMEFY(DW_AT_element_list);
40     DWARF_NAMEFY(DW_AT_stmt_list);
41     DWARF_NAMEFY(DW_AT_low_pc);
42     DWARF_NAMEFY(DW_AT_high_pc);
43     DWARF_NAMEFY(DW_AT_language);
44     DWARF_NAMEFY(DW_AT_member);
45     DWARF_NAMEFY(DW_AT_discr);
46     DWARF_NAMEFY(DW_AT_discr_value);
47     DWARF_NAMEFY(DW_AT_visibility);
48     DWARF_NAMEFY(DW_AT_import);
49     DWARF_NAMEFY(DW_AT_string_length);
50     DWARF_NAMEFY(DW_AT_common_reference);
51     DWARF_NAMEFY(DW_AT_comp_dir);
52     DWARF_NAMEFY(DW_AT_const_value);
53     DWARF_NAMEFY(DW_AT_containing_type);
54     DWARF_NAMEFY(DW_AT_default_value);
55     DWARF_NAMEFY(DW_AT_inline);
56     DWARF_NAMEFY(DW_AT_is_optional);
57     DWARF_NAMEFY(DW_AT_lower_bound);
58     DWARF_NAMEFY(DW_AT_producer);
59     DWARF_NAMEFY(DW_AT_prototyped);
60     DWARF_NAMEFY(DW_AT_return_addr);
61     DWARF_NAMEFY(DW_AT_start_scope);
62     DWARF_NAMEFY2(DW_AT_bit_stride, DW_AT_stride_size);
63     DWARF_NAMEFY(DW_AT_upper_bound);
64     DWARF_NAMEFY(DW_AT_abstract_origin);
65     DWARF_NAMEFY(DW_AT_accessibility);
66     DWARF_NAMEFY(DW_AT_address_class);
67     DWARF_NAMEFY(DW_AT_artificial);
68     DWARF_NAMEFY(DW_AT_base_types);
69     DWARF_NAMEFY(DW_AT_calling_convention);
70     DWARF_NAMEFY(DW_AT_count);
71     DWARF_NAMEFY(DW_AT_data_member_location);
72     DWARF_NAMEFY(DW_AT_decl_column);
73     DWARF_NAMEFY(DW_AT_decl_file);
74     DWARF_NAMEFY(DW_AT_decl_line);
75     DWARF_NAMEFY(DW_AT_declaration);
76     DWARF_NAMEFY(DW_AT_discr_list);
77     DWARF_NAMEFY(DW_AT_encoding);
78     DWARF_NAMEFY(DW_AT_external);
79     DWARF_NAMEFY(DW_AT_frame_base);
80     DWARF_NAMEFY(DW_AT_friend);
81     DWARF_NAMEFY(DW_AT_identifier_case);
82     DWARF_NAMEFY(DW_AT_macro_info);
83     DWARF_NAMEFY(DW_AT_namelist_item);
84     DWARF_NAMEFY(DW_AT_priority);
85     DWARF_NAMEFY(DW_AT_segment);
86     DWARF_NAMEFY(DW_AT_specification);
87     DWARF_NAMEFY(DW_AT_static_link);
88     DWARF_NAMEFY(DW_AT_type);
89     DWARF_NAMEFY(DW_AT_use_location);
90     DWARF_NAMEFY(DW_AT_variable_parameter);
91     DWARF_NAMEFY(DW_AT_virtuality);
92     DWARF_NAMEFY(DW_AT_vtable_elem_location);
93     DWARF_NAMEFY(DW_AT_allocated);
94     DWARF_NAMEFY(DW_AT_associated);
95     DWARF_NAMEFY(DW_AT_data_location);
96     DWARF_NAMEFY2(DW_AT_byte_stride, DW_AT_stride);
97     DWARF_NAMEFY(DW_AT_entry_pc);
98     DWARF_NAMEFY(DW_AT_use_UTF8);
99     DWARF_NAMEFY(DW_AT_extension);
100     DWARF_NAMEFY(DW_AT_ranges);
101     DWARF_NAMEFY(DW_AT_trampoline);
102     DWARF_NAMEFY(DW_AT_call_column);
103     DWARF_NAMEFY(DW_AT_call_file);
104     DWARF_NAMEFY(DW_AT_call_line);
105     DWARF_NAMEFY(DW_AT_description);
106     DWARF_NAMEFY(DW_AT_binary_scale);
107     DWARF_NAMEFY(DW_AT_decimal_scale);
108     DWARF_NAMEFY(DW_AT_small);
109     DWARF_NAMEFY(DW_AT_decimal_sign);
110     DWARF_NAMEFY(DW_AT_digit_count);
111     DWARF_NAMEFY(DW_AT_picture_string);
112     DWARF_NAMEFY(DW_AT_mutable);
113     DWARF_NAMEFY(DW_AT_threads_scaled);
114     DWARF_NAMEFY(DW_AT_explicit);
115     DWARF_NAMEFY(DW_AT_object_pointer);
116     DWARF_NAMEFY(DW_AT_endianity);
117     DWARF_NAMEFY(DW_AT_elemental);
118     DWARF_NAMEFY(DW_AT_pure);
119     DWARF_NAMEFY(DW_AT_recursive);
120     DWARF_NAMEFY(DW_AT_signature);
121     DWARF_NAMEFY(DW_AT_main_subprogram);
122     DWARF_NAMEFY(DW_AT_data_bit_offset);
123     DWARF_NAMEFY(DW_AT_const_expr);
124     DWARF_NAMEFY(DW_AT_enum_class);
125     DWARF_NAMEFY(DW_AT_linkage_name);
126     default:
127       return "DW_AT_Unknown";
128   }
129 }
130 
131 const char*
dwarf_form_name(Dwarf_Form form)132 dwarf_form_name(Dwarf_Form form) {
133   switch (form) {
134     DWARF_NAMEFY(DW_FORM_addr);
135     DWARF_NAMEFY(DW_FORM_block2);
136     DWARF_NAMEFY(DW_FORM_block4);
137     DWARF_NAMEFY(DW_FORM_data2);
138     DWARF_NAMEFY(DW_FORM_data4);
139     DWARF_NAMEFY(DW_FORM_data8);
140     DWARF_NAMEFY(DW_FORM_string);
141     DWARF_NAMEFY(DW_FORM_block);
142     DWARF_NAMEFY(DW_FORM_block1);
143     DWARF_NAMEFY(DW_FORM_data1);
144     DWARF_NAMEFY(DW_FORM_flag);
145     DWARF_NAMEFY(DW_FORM_sdata);
146     DWARF_NAMEFY(DW_FORM_strp);
147     DWARF_NAMEFY(DW_FORM_udata);
148     DWARF_NAMEFY(DW_FORM_ref_addr);
149     DWARF_NAMEFY(DW_FORM_ref1);
150     DWARF_NAMEFY(DW_FORM_ref2);
151     DWARF_NAMEFY(DW_FORM_ref4);
152     DWARF_NAMEFY(DW_FORM_ref8);
153     DWARF_NAMEFY(DW_FORM_ref_udata);
154     DWARF_NAMEFY(DW_FORM_indirect);
155     DWARF_NAMEFY(DW_FORM_sec_offset);
156     DWARF_NAMEFY(DW_FORM_exprloc);
157     DWARF_NAMEFY(DW_FORM_flag_present);
158     DWARF_NAMEFY(DW_FORM_ref_sig8);
159     default:
160       return "DW_FORM_Unknown";
161   }
162 }
163 
164 const char*
dwarf_tag_name(Dwarf_Tag tag)165 dwarf_tag_name(Dwarf_Tag tag) {
166   switch (tag) {
167     DWARF_NAMEFY(DW_TAG_array_type);
168     DWARF_NAMEFY(DW_TAG_class_type);
169     DWARF_NAMEFY(DW_TAG_entry_point);
170     DWARF_NAMEFY(DW_TAG_enumeration_type);
171     DWARF_NAMEFY(DW_TAG_formal_parameter);
172     DWARF_NAMEFY(DW_TAG_imported_declaration);
173     DWARF_NAMEFY(DW_TAG_label);
174     DWARF_NAMEFY(DW_TAG_lexical_block);
175     DWARF_NAMEFY(DW_TAG_member);
176     DWARF_NAMEFY(DW_TAG_pointer_type);
177     DWARF_NAMEFY(DW_TAG_reference_type);
178     DWARF_NAMEFY(DW_TAG_compile_unit);
179     DWARF_NAMEFY(DW_TAG_string_type);
180     DWARF_NAMEFY(DW_TAG_structure_type);
181     DWARF_NAMEFY(DW_TAG_subroutine_type);
182     DWARF_NAMEFY(DW_TAG_typedef);
183     DWARF_NAMEFY(DW_TAG_union_type);
184     DWARF_NAMEFY(DW_TAG_unspecified_parameters);
185     DWARF_NAMEFY(DW_TAG_variant);
186     DWARF_NAMEFY(DW_TAG_common_block);
187     DWARF_NAMEFY(DW_TAG_common_inclusion);
188     DWARF_NAMEFY(DW_TAG_inheritance);
189     DWARF_NAMEFY(DW_TAG_inlined_subroutine);
190     DWARF_NAMEFY(DW_TAG_module);
191     DWARF_NAMEFY(DW_TAG_ptr_to_member_type);
192     DWARF_NAMEFY(DW_TAG_set_type);
193     DWARF_NAMEFY(DW_TAG_subrange_type);
194     DWARF_NAMEFY(DW_TAG_with_stmt);
195     DWARF_NAMEFY(DW_TAG_access_declaration);
196     DWARF_NAMEFY(DW_TAG_base_type);
197     DWARF_NAMEFY(DW_TAG_catch_block);
198     DWARF_NAMEFY(DW_TAG_const_type);
199     DWARF_NAMEFY(DW_TAG_constant);
200     DWARF_NAMEFY(DW_TAG_enumerator);
201     DWARF_NAMEFY(DW_TAG_file_type);
202     DWARF_NAMEFY(DW_TAG_friend);
203     DWARF_NAMEFY(DW_TAG_namelist);
204     DWARF_NAMEFY2(DW_TAG_namelist_item, DW_TAG_namelist_items);
205     DWARF_NAMEFY(DW_TAG_packed_type);
206     DWARF_NAMEFY(DW_TAG_subprogram);
207     DWARF_NAMEFY2(DW_TAG_template_type_parameter, DW_TAG_template_type_param);
208     DWARF_NAMEFY2(DW_TAG_template_value_parameter,
209                   DW_TAG_template_value_param);
210     DWARF_NAMEFY(DW_TAG_thrown_type);
211     DWARF_NAMEFY(DW_TAG_try_block);
212     DWARF_NAMEFY(DW_TAG_variant_part);
213     DWARF_NAMEFY(DW_TAG_variable);
214     DWARF_NAMEFY(DW_TAG_volatile_type);
215     DWARF_NAMEFY(DW_TAG_dwarf_procedure);
216     DWARF_NAMEFY(DW_TAG_restrict_type);
217     DWARF_NAMEFY(DW_TAG_interface_type);
218     DWARF_NAMEFY(DW_TAG_namespace);
219     DWARF_NAMEFY(DW_TAG_imported_module);
220     DWARF_NAMEFY(DW_TAG_unspecified_type);
221     DWARF_NAMEFY(DW_TAG_partial_unit);
222     DWARF_NAMEFY(DW_TAG_imported_unit);
223     DWARF_NAMEFY(DW_TAG_mutable_type);
224     DWARF_NAMEFY(DW_TAG_condition);
225     DWARF_NAMEFY(DW_TAG_shared_type);
226     DWARF_NAMEFY(DW_TAG_type_unit);
227     DWARF_NAMEFY(DW_TAG_rvalue_reference_type);
228     DWARF_NAMEFY(DW_TAG_template_alias);
229     default:
230       return "DW_TAG_Unknown";
231   }
232 }
233 
234 void
dump_attrib(Dwarf_At at,Dwarf_Form form,const Dwarf_Value * val)235 dump_attrib(Dwarf_At at, Dwarf_Form form, const Dwarf_Value* val) {
236   if (form != 0) {
237     printf("   +++ Attribute: %s [%s]\n",
238            dwarf_at_name(at), dwarf_form_name(form));
239   } else {
240     printf("   +++ Attribute: %s\n", dwarf_at_name(at));
241   }
242   dump_value(val);
243 }
244 
245 void
dump_value(const Dwarf_Value * attr_value)246 dump_value(const Dwarf_Value* attr_value) {
247   printf("       Data[%03u]: (", attr_value->encoded_size);
248   switch (attr_value->type) {
249     case DWARF_VALUE_U8:
250       printf("BYTE)   = %u (x%02X)\n", (Elf_Word)attr_value->u8,
251                                        (Elf_Word)attr_value->u8);
252       break;
253 
254     case DWARF_VALUE_S8:
255       printf("SBYTE)  = %d (x%02X)\n", (Elf_Sword)attr_value->s8,
256                                        (Elf_Sword)attr_value->s8);
257       break;
258 
259     case DWARF_VALUE_U16:
260       printf("WORD)   = %u (x%04X)\n", (Elf_Word)attr_value->u16,
261                                        (Elf_Word)attr_value->u16);
262       break;
263 
264     case DWARF_VALUE_S16:
265       printf("SWORD)  = %d (x%04X)\n", (Elf_Sword)attr_value->s16,
266                                        (Elf_Sword)attr_value->s16);
267       break;
268 
269     case DWARF_VALUE_U32:
270       printf("DWORD)  = %u (x%08X)\n", attr_value->u32,
271                                        attr_value->u32);
272       break;
273 
274     case DWARF_VALUE_S32:
275       printf("SDWORD) = %d (x%08X)\n", attr_value->s32,
276                                        attr_value->s32);
277       break;
278 
279     case DWARF_VALUE_U64:
280       printf("XWORD)  = %" PRIu64 " (x%" PRIX64 ")\n", attr_value->u64,
281                                                        attr_value->u64);
282       break;
283 
284     case DWARF_VALUE_S64:
285       printf("SXWORD) = %" PRId64 " (x%" PRIX64 ")\n", attr_value->s64,
286                                                        attr_value->s64);
287       break;
288 
289     case DWARF_VALUE_STR:
290       printf("STRING) = %s\n", attr_value->str);
291       break;
292 
293     case DWARF_VALUE_PTR32:
294       printf("PTR32)  = x%08X\n", attr_value->ptr32);
295       break;
296 
297     case DWARF_VALUE_PTR64:
298       printf("PTR64)  = x%08" PRIX64 "\n", attr_value->ptr64);
299       break;
300 
301     case DWARF_VALUE_BLOCK:
302       printf("BLOCK)  = [%u]:", attr_value->block.block_size);
303       for (Elf_Xword i = 0; i < attr_value->block.block_size; i++) {
304         Elf_Byte prnt = *((const Elf_Byte*)attr_value->block.block_ptr + i);
305         printf(" x%02X", prnt);
306       }
307       printf("\n");
308       break;
309 
310     case DWARF_VALUE_UNKNOWN:
311     default:
312       printf("UNKNOWN)");
313       break;
314   }
315 }
316