1 /*-
2 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD$
27 */
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include "_libdwarf.h"
32
33 const char *
get_sht_desc(uint32_t sh_type)34 get_sht_desc(uint32_t sh_type)
35 {
36 switch (sh_type) {
37 case SHT_NULL:
38 return "inactive";
39 case SHT_PROGBITS:
40 return "program defined information";
41 case SHT_SYMTAB:
42 return "symbol table section";
43 case SHT_STRTAB:
44 return "string table section";
45 case SHT_RELA:
46 return "relocation section with addends";
47 case SHT_HASH:
48 return "symbol hash table section";
49 case SHT_DYNAMIC:
50 return "dynamic section";
51 case SHT_NOTE:
52 return "note section";
53 case SHT_NOBITS:
54 return "no space section";
55 case SHT_REL:
56 return "relocation section - no addends";
57 case SHT_SHLIB:
58 return "reserved - purpose unknown";
59 case SHT_DYNSYM:
60 return "dynamic symbol table section";
61 case SHT_INIT_ARRAY:
62 return "Initialization function pointers.";
63 case SHT_FINI_ARRAY:
64 return "Termination function pointers.";
65 case SHT_PREINIT_ARRAY:
66 return "Pre-initialization function ptrs.";
67 case SHT_GROUP:
68 return "Section group.";
69 case SHT_SYMTAB_SHNDX:
70 return "Section indexes (see SHN_XINDEX).";
71 case SHT_GNU_verdef:
72 return "Symbol versions provided";
73 case SHT_GNU_verneed:
74 return "Symbol versions required";
75 case SHT_GNU_versym:
76 return "Symbol version table";
77 case SHT_AMD64_UNWIND:
78 return "AMD64 unwind";
79 default:
80 return "Unknown";
81 }
82 }
83
84 const char *
get_attr_desc(uint32_t attr)85 get_attr_desc(uint32_t attr)
86 {
87 switch (attr) {
88 case DW_AT_abstract_origin:
89 return "DW_AT_abstract_origin";
90 case DW_AT_accessibility:
91 return "DW_AT_accessibility";
92 case DW_AT_address_class:
93 return "DW_AT_address_class";
94 case DW_AT_artificial:
95 return "DW_AT_artificial";
96 case DW_AT_base_types:
97 return "DW_AT_base_types";
98 case DW_AT_bit_offset:
99 return "DW_AT_bit_offset";
100 case DW_AT_bit_size:
101 return "DW_AT_bit_size";
102 case DW_AT_byte_size:
103 return "DW_AT_byte_size";
104 case DW_AT_calling_convention:
105 return "DW_AT_calling_convention";
106 case DW_AT_common_reference:
107 return "DW_AT_common_reference";
108 case DW_AT_comp_dir:
109 return "DW_AT_comp_dir";
110 case DW_AT_const_value:
111 return "DW_AT_const_value";
112 case DW_AT_containing_type:
113 return "DW_AT_containing_type";
114 case DW_AT_count:
115 return "DW_AT_count";
116 case DW_AT_data_member_location:
117 return "DW_AT_data_member_location";
118 case DW_AT_decl_column:
119 return "DW_AT_decl_column";
120 case DW_AT_decl_file:
121 return "DW_AT_decl_file";
122 case DW_AT_decl_line:
123 return "DW_AT_decl_line";
124 case DW_AT_declaration:
125 return "DW_AT_declaration";
126 case DW_AT_default_value:
127 return "DW_AT_default_value";
128 case DW_AT_discr:
129 return "DW_AT_discr";
130 case DW_AT_discr_list:
131 return "DW_AT_discr_list";
132 case DW_AT_discr_value:
133 return "DW_AT_discr_value";
134 case DW_AT_element_list:
135 return "DW_AT_element_list";
136 case DW_AT_encoding:
137 return "DW_AT_encoding";
138 case DW_AT_external:
139 return "DW_AT_external";
140 case DW_AT_frame_base:
141 return "DW_AT_frame_base";
142 case DW_AT_friend:
143 return "DW_AT_friend";
144 case DW_AT_high_pc:
145 return "DW_AT_high_pc";
146 case DW_AT_identifier_case:
147 return "DW_AT_identifier_case";
148 case DW_AT_import:
149 return "DW_AT_import";
150 case DW_AT_inline:
151 return "DW_AT_inline";
152 case DW_AT_is_optional:
153 return "DW_AT_is_optional";
154 case DW_AT_language:
155 return "DW_AT_language";
156 case DW_AT_location:
157 return "DW_AT_location";
158 case DW_AT_low_pc:
159 return "DW_AT_low_pc";
160 case DW_AT_lower_bound:
161 return "DW_AT_lower_bound";
162 case DW_AT_macro_info:
163 return "DW_AT_macro_info";
164 case DW_AT_member:
165 return "DW_AT_member";
166 case DW_AT_name:
167 return "DW_AT_name";
168 case DW_AT_namelist_item:
169 return "DW_AT_namelist_item";
170 case DW_AT_ordering:
171 return "DW_AT_ordering";
172 case DW_AT_priority:
173 return "DW_AT_priority";
174 case DW_AT_producer:
175 return "DW_AT_producer";
176 case DW_AT_prototyped:
177 return "DW_AT_prototyped";
178 case DW_AT_return_addr:
179 return "DW_AT_return_addr";
180 case DW_AT_segment:
181 return "DW_AT_segment";
182 case DW_AT_sibling:
183 return "DW_AT_sibling";
184 case DW_AT_specification:
185 return "DW_AT_specification";
186 case DW_AT_start_scope:
187 return "DW_AT_start_scope";
188 case DW_AT_static_link:
189 return "DW_AT_static_link";
190 case DW_AT_stmt_list:
191 return "DW_AT_stmt_list";
192 case DW_AT_stride_size:
193 return "DW_AT_stride_size";
194 case DW_AT_string_length:
195 return "DW_AT_string_length";
196 case DW_AT_subscr_data:
197 return "DW_AT_subscr_data";
198 case DW_AT_type:
199 return "DW_AT_type";
200 case DW_AT_upper_bound:
201 return "DW_AT_upper_bound";
202 case DW_AT_use_location:
203 return "DW_AT_use_location";
204 case DW_AT_variable_parameter:
205 return "DW_AT_variable_parameter";
206 case DW_AT_virtuality:
207 return "DW_AT_virtuality";
208 case DW_AT_visibility:
209 return "DW_AT_visibility";
210 case DW_AT_vtable_elem_location:
211 return "DW_AT_vtable_elem_location";
212 default:
213 break;
214 }
215
216 return "Unknown attribute";
217 }
218
219 const char *
get_form_desc(uint32_t form)220 get_form_desc(uint32_t form)
221 {
222 switch (form) {
223 case DW_FORM_addr:
224 return "DW_FORM_addr";
225 case DW_FORM_block:
226 return "DW_FORM_block";
227 case DW_FORM_block1:
228 return "DW_FORM_block1";
229 case DW_FORM_block2:
230 return "DW_FORM_block2";
231 case DW_FORM_block4:
232 return "DW_FORM_block4";
233 case DW_FORM_data1:
234 return "DW_FORM_data1";
235 case DW_FORM_data2:
236 return "DW_FORM_data2";
237 case DW_FORM_data4:
238 return "DW_FORM_data4";
239 case DW_FORM_data8:
240 return "DW_FORM_data8";
241 case DW_FORM_flag:
242 return "DW_FORM_flag";
243 case DW_FORM_flag_present:
244 return "DW_FORM_flag_present";
245 case DW_FORM_indirect:
246 return "DW_FORM_indirect";
247 case DW_FORM_ref1:
248 return "DW_FORM_ref1";
249 case DW_FORM_ref2:
250 return "DW_FORM_ref2";
251 case DW_FORM_ref4:
252 return "DW_FORM_ref4";
253 case DW_FORM_ref8:
254 return "DW_FORM_ref8";
255 case DW_FORM_ref_addr:
256 return "DW_FORM_ref_addr";
257 case DW_FORM_ref_udata:
258 return "DW_FORM_ref_udata";
259 case DW_FORM_sdata:
260 return "DW_FORM_sdata";
261 case DW_FORM_string:
262 return "DW_FORM_string";
263 case DW_FORM_strp:
264 return "DW_FORM_strp";
265 case DW_FORM_udata:
266 return "DW_FORM_udata";
267 default:
268 break;
269 }
270
271 return "Unknown attribute";
272 }
273
274 const char *
get_tag_desc(uint32_t tag)275 get_tag_desc(uint32_t tag)
276 {
277 switch (tag) {
278 case DW_TAG_access_declaration:
279 return "DW_TAG_access_declaration";
280 case DW_TAG_array_type:
281 return "DW_TAG_array_type";
282 case DW_TAG_base_type:
283 return "DW_TAG_base_type";
284 case DW_TAG_catch_block:
285 return "DW_TAG_catch_block";
286 case DW_TAG_class_type:
287 return "DW_TAG_class_type";
288 case DW_TAG_common_block:
289 return "DW_TAG_common_block";
290 case DW_TAG_common_inclusion:
291 return "DW_TAG_common_inclusion";
292 case DW_TAG_compile_unit:
293 return "DW_TAG_compile_unit";
294 case DW_TAG_condition:
295 return "DW_TAG_condition";
296 case DW_TAG_const_type:
297 return "DW_TAG_const_type";
298 case DW_TAG_constant:
299 return "DW_TAG_constant";
300 case DW_TAG_dwarf_procedure:
301 return "DW_TAG_dwarf_procedure";
302 case DW_TAG_entry_point:
303 return "DW_TAG_entry_point";
304 case DW_TAG_enumeration_type:
305 return "DW_TAG_enumeration_type";
306 case DW_TAG_enumerator:
307 return "DW_TAG_enumerator";
308 case DW_TAG_formal_parameter:
309 return "DW_TAG_formal_parameter";
310 case DW_TAG_friend:
311 return "DW_TAG_friend";
312 case DW_TAG_imported_declaration:
313 return "DW_TAG_imported_declaration";
314 case DW_TAG_imported_module:
315 return "DW_TAG_imported_module";
316 case DW_TAG_imported_unit:
317 return "DW_TAG_imported_unit";
318 case DW_TAG_inheritance:
319 return "DW_TAG_inheritance";
320 case DW_TAG_inlined_subroutine:
321 return "DW_TAG_inlined_subroutine";
322 case DW_TAG_interface_type:
323 return "DW_TAG_interface_type";
324 case DW_TAG_label:
325 return "DW_TAG_label";
326 case DW_TAG_lexical_block:
327 return "DW_TAG_lexical_block";
328 case DW_TAG_member:
329 return "DW_TAG_member";
330 case DW_TAG_module:
331 return "DW_TAG_module";
332 case DW_TAG_namelist:
333 return "DW_TAG_namelist";
334 case DW_TAG_namelist_item:
335 return "DW_TAG_namelist_item";
336 case DW_TAG_namespace:
337 return "DW_TAG_namespace";
338 case DW_TAG_packed_type:
339 return "DW_TAG_packed_type";
340 case DW_TAG_partial_unit:
341 return "DW_TAG_partial_unit";
342 case DW_TAG_pointer_type:
343 return "DW_TAG_pointer_type";
344 case DW_TAG_ptr_to_member_type:
345 return "DW_TAG_ptr_to_member_type";
346 case DW_TAG_reference_type:
347 return "DW_TAG_reference_type";
348 case DW_TAG_restrict_type:
349 return "DW_TAG_restrict_type";
350 case DW_TAG_set_type:
351 return "DW_TAG_set_type";
352 case DW_TAG_shared_type:
353 return "DW_TAG_shared_type";
354 case DW_TAG_string_type:
355 return "DW_TAG_string_type";
356 case DW_TAG_structure_type:
357 return "DW_TAG_structure_type";
358 case DW_TAG_subprogram:
359 return "DW_TAG_subprogram";
360 case DW_TAG_subrange_type:
361 return "DW_TAG_subrange_type";
362 case DW_TAG_subroutine_type:
363 return "DW_TAG_subroutine_type";
364 case DW_TAG_template_type_parameter:
365 return "DW_TAG_template_type_parameter";
366 case DW_TAG_template_value_parameter:
367 return "DW_TAG_template_value_parameter";
368 case DW_TAG_thrown_type:
369 return "DW_TAG_thrown_type";
370 case DW_TAG_try_block:
371 return "DW_TAG_try_block";
372 case DW_TAG_typedef:
373 return "DW_TAG_typedef";
374 case DW_TAG_union_type:
375 return "DW_TAG_union_type";
376 case DW_TAG_unspecified_parameters:
377 return "DW_TAG_unspecified_parameters";
378 case DW_TAG_unspecified_type:
379 return "DW_TAG_unspecified_type";
380 case DW_TAG_variable:
381 return "DW_TAG_variable";
382 case DW_TAG_variant:
383 return "DW_TAG_variant";
384 case DW_TAG_variant_part:
385 return "DW_TAG_variant_part";
386 case DW_TAG_volatile_type:
387 return "DW_TAG_volatile_type";
388 case DW_TAG_with_stmt:
389 return "DW_TAG_with_stmt";
390 default:
391 break;
392 }
393
394 return "Unknown tag";
395 }
396
397 void
dwarf_dump_abbrev(Dwarf_Debug dbg)398 dwarf_dump_abbrev(Dwarf_Debug dbg)
399 {
400 Dwarf_Abbrev a;
401 Dwarf_Attribute at;
402 Dwarf_CU cu;
403
404 printf("Contents of the .debug_abbrev section:\n\nEntry Tag\n");
405
406 STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
407 STAILQ_FOREACH(a, &cu->cu_abbrev, a_next) {
408 printf("%5lu %-30s [%s children]\n",
409 (u_long) a->a_entry, get_tag_desc(a->a_tag),
410 (a->a_children == DW_CHILDREN_yes) ? "has" : "no");
411
412 STAILQ_FOREACH(at, &a->a_attrib, at_next)
413 printf(" %-30s %s\n", get_attr_desc(at->at_attrib),
414 get_form_desc(at->at_form));
415 }
416 }
417 }
418 #ifdef DOODAD
419 case DW_AT_inline:
420 switch (uvalue)
421 {
422 case DW_INL_not_inlined:
423 printf (_("(not inlined)"));
424 break;
425 case DW_INL_inlined:
426 printf (_("(inlined)"));
427 break;
428 case DW_INL_declared_not_inlined:
429 printf (_("(declared as inline but ignored)"));
430 break;
431 case DW_INL_declared_inlined:
432 printf (_("(declared as inline and inlined)"));
433 break;
434 default:
435 printf (_(" (Unknown inline attribute value: %lx)"), uvalue);
436 break;
437 }
438 break;
439
440 case DW_AT_language:
441 switch (uvalue)
442 {
443 case DW_LANG_C: printf ("(non-ANSI C)"); break;
444 case DW_LANG_C89: printf ("(ANSI C)"); break;
445 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
446 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
447 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
448 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
449 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
450 case DW_LANG_Ada83: printf ("(Ada)"); break;
451 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
452 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
453 /* DWARF 2.1 values. */
454 case DW_LANG_C99: printf ("(ANSI C99)"); break;
455 case DW_LANG_Ada95: printf ("(ADA 95)"); break;
456 case DW_LANG_Fortran95: printf ("(Fortran 95)"); break;
457 /* MIPS extension. */
458 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
459 /* UPC extension. */
460 case DW_LANG_Upc: printf ("(Unified Parallel C)"); break;
461 default:
462 printf ("(Unknown: %lx)", uvalue);
463 break;
464 }
465 break;
466
467 case DW_AT_encoding:
468 switch (uvalue)
469 {
470 case DW_ATE_void: printf ("(void)"); break;
471 case DW_ATE_address: printf ("(machine address)"); break;
472 case DW_ATE_boolean: printf ("(boolean)"); break;
473 case DW_ATE_complex_float: printf ("(complex float)"); break;
474 case DW_ATE_float: printf ("(float)"); break;
475 case DW_ATE_signed: printf ("(signed)"); break;
476 case DW_ATE_signed_char: printf ("(signed char)"); break;
477 case DW_ATE_unsigned: printf ("(unsigned)"); break;
478 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
479 /* DWARF 2.1 value. */
480 case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
481 default:
482 if (uvalue >= DW_ATE_lo_user
483 && uvalue <= DW_ATE_hi_user)
484 printf ("(user defined type)");
485 else
486 printf ("(unknown type)");
487 break;
488 }
489 break;
490
491 case DW_AT_accessibility:
492 switch (uvalue)
493 {
494 case DW_ACCESS_public: printf ("(public)"); break;
495 case DW_ACCESS_protected: printf ("(protected)"); break;
496 case DW_ACCESS_private: printf ("(private)"); break;
497 default:
498 printf ("(unknown accessibility)");
499 break;
500 }
501 break;
502
503 case DW_AT_visibility:
504 switch (uvalue)
505 {
506 case DW_VIS_local: printf ("(local)"); break;
507 case DW_VIS_exported: printf ("(exported)"); break;
508 case DW_VIS_qualified: printf ("(qualified)"); break;
509 default: printf ("(unknown visibility)"); break;
510 }
511 break;
512
513 case DW_AT_virtuality:
514 switch (uvalue)
515 {
516 case DW_VIRTUALITY_none: printf ("(none)"); break;
517 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
518 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
519 default: printf ("(unknown virtuality)"); break;
520 }
521 break;
522
523 case DW_AT_identifier_case:
524 switch (uvalue)
525 {
526 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
527 case DW_ID_up_case: printf ("(up_case)"); break;
528 case DW_ID_down_case: printf ("(down_case)"); break;
529 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
530 default: printf ("(unknown case)"); break;
531 }
532 break;
533
534 case DW_AT_calling_convention:
535 switch (uvalue)
536 {
537 case DW_CC_normal: printf ("(normal)"); break;
538 case DW_CC_program: printf ("(program)"); break;
539 case DW_CC_nocall: printf ("(nocall)"); break;
540 default:
541 if (uvalue >= DW_CC_lo_user
542 && uvalue <= DW_CC_hi_user)
543 printf ("(user defined)");
544 else
545 printf ("(unknown convention)");
546 }
547 break;
548
549 case DW_AT_ordering:
550 switch (uvalue)
551 {
552 case -1: printf ("(undefined)"); break;
553 case 0: printf ("(row major)"); break;
554 case 1: printf ("(column major)"); break;
555 }
556 break;
557
558 case DW_AT_frame_base:
559 case DW_AT_location:
560 case DW_AT_data_member_location:
561 case DW_AT_vtable_elem_location:
562 case DW_AT_allocated:
563 case DW_AT_associated:
564 case DW_AT_data_location:
565 case DW_AT_stride:
566 case DW_AT_upper_bound:
567 case DW_AT_lower_bound:
568 if (block_start)
569 {
570 printf ("(");
571 decode_location_expression (block_start, pointer_size, uvalue);
572 printf (")");
573 }
574 else if (form == DW_FORM_data4 || form == DW_FORM_data8)
575 {
576 printf ("(");
577 printf ("location list");
578 printf (")");
579 }
580 break;
581 #endif
582
583 static void
dwarf_dump_av_attr(Dwarf_Die die __unused,Dwarf_AttrValue av)584 dwarf_dump_av_attr(Dwarf_Die die __unused, Dwarf_AttrValue av)
585 {
586 switch (av->av_attrib) {
587 case DW_AT_accessibility:
588 break;
589
590 case DW_AT_calling_convention:
591 break;
592
593 case DW_AT_encoding:
594 break;
595
596 case DW_AT_identifier_case:
597 break;
598
599 case DW_AT_inline:
600 break;
601
602 case DW_AT_language:
603 break;
604
605 case DW_AT_ordering:
606 break;
607
608 case DW_AT_virtuality:
609 break;
610
611 case DW_AT_visibility:
612 break;
613
614 case DW_AT_frame_base:
615 case DW_AT_location:
616 case DW_AT_data_member_location:
617 case DW_AT_vtable_elem_location:
618 case DW_AT_upper_bound:
619 case DW_AT_lower_bound:
620 break;
621
622 default:
623 break;
624 }
625 }
626
627 void
dwarf_dump_av(Dwarf_Die die,Dwarf_AttrValue av)628 dwarf_dump_av(Dwarf_Die die, Dwarf_AttrValue av)
629 {
630 uint64_t i;
631
632 printf(" %-30s : %-16s ",
633 get_attr_desc(av->av_attrib),
634 get_form_desc(av->av_form));
635
636 switch (av->av_form) {
637 case DW_FORM_addr:
638 printf("0x%llx", (unsigned long long) av->u[0].u64);
639 break;
640 case DW_FORM_block:
641 case DW_FORM_block1:
642 case DW_FORM_block2:
643 case DW_FORM_block4:
644 printf("%lu byte block:", (u_long) av->u[0].u64);
645 for (i = 0; i < av->u[0].u64; i++)
646 printf(" %02x", av->u[1].u8p[i]);
647 break;
648 case DW_FORM_data1:
649 case DW_FORM_data2:
650 case DW_FORM_data4:
651 case DW_FORM_data8:
652 case DW_FORM_flag:
653 case DW_FORM_flag_present:
654 printf("%llu", (unsigned long long) av->u[0].u64);
655 break;
656 case DW_FORM_ref1:
657 case DW_FORM_ref2:
658 case DW_FORM_ref4:
659 case DW_FORM_ref8:
660 case DW_FORM_ref_udata:
661 printf("<%llx>", (unsigned long long) (av->u[0].u64 +
662 die->die_cu->cu_offset));
663 break;
664 case DW_FORM_string:
665 printf("%s", av->u[0].s);
666 break;
667 case DW_FORM_strp:
668 printf("(indirect string, offset 0x%llx): %s",
669 (unsigned long long) av->u[0].u64, av->u[1].s);
670 break;
671 default:
672 printf("unknown form");
673 break;
674 }
675
676 /* Dump any extra attribute-specific information. */
677 dwarf_dump_av_attr(die, av);
678
679 printf("\n");
680 }
681
682 void
dwarf_dump_die_at_offset(Dwarf_Debug dbg,Dwarf_Off off)683 dwarf_dump_die_at_offset(Dwarf_Debug dbg, Dwarf_Off off)
684 {
685 Dwarf_CU cu;
686 Dwarf_Die die;
687
688 if (dbg == NULL)
689 return;
690
691 STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
692 STAILQ_FOREACH(die, &cu->cu_die, die_next) {
693 if ((off_t) die->die_offset == off) {
694 dwarf_dump_die(die);
695 return;
696 }
697 }
698 }
699 }
700
701 void
dwarf_dump_die(Dwarf_Die die)702 dwarf_dump_die(Dwarf_Die die)
703 {
704 Dwarf_AttrValue av;
705
706 printf("<%d><%llx>: Abbrev number: %llu (%s)\n",
707 die->die_level, (unsigned long long) die->die_offset,
708 (unsigned long long) die->die_abnum,
709 get_tag_desc(die->die_a->a_tag));
710
711 STAILQ_FOREACH(av, &die->die_attrval, av_next)
712 dwarf_dump_av(die, av);
713 }
714
715 void
dwarf_dump_raw(Dwarf_Debug dbg)716 dwarf_dump_raw(Dwarf_Debug dbg)
717 {
718 Dwarf_CU cu;
719 char *p = (char *) dbg;
720 int i;
721
722 printf("dbg %p\n",dbg);
723
724 if (dbg == NULL)
725 return;
726
727 for (i = 0; i < (int) sizeof(*dbg); i++) {
728 if (*p >= 0x20 && *p < 0x7f) {
729 printf(" %c",*p++ & 0xff);
730 } else {
731 printf(" %02x",*p++ & 0xff);
732 }
733 }
734 printf("\n");
735
736 STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
737 p = (char *) cu;
738 printf("cu %p\n",cu);
739 for (i = 0; i < (int) sizeof(*cu); i++) {
740 if (*p >= 0x20 && *p < 0x7f) {
741 printf(" %c",*p++ & 0xff);
742 } else {
743 printf(" %02x",*p++ & 0xff);
744 }
745 }
746 printf("\n");
747 }
748 }
749
750 static void
dwarf_dump_tree_dies(Dwarf_Debug dbg,Dwarf_Die die,Dwarf_Error * error)751 dwarf_dump_tree_dies(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Error *error)
752 {
753 Dwarf_Die child;
754 int ret;
755
756 do {
757 dwarf_dump_die(die);
758
759 if ((ret = dwarf_child(die, &child, error) == DWARF_E_NO_ENTRY)) {
760 /* No children. */
761 } else if (ret != DWARF_E_NONE) {
762 printf("Error %s\n", dwarf_errmsg(error));
763 return;
764 } else
765 dwarf_dump_tree_dies(dbg, child, error);
766
767 if (dwarf_siblingof(dbg, die, &die, error) != DWARF_E_NONE)
768 die = NULL;
769
770 } while (die != NULL);
771 }
772
773 void
dwarf_dump_tree(Dwarf_Debug dbg)774 dwarf_dump_tree(Dwarf_Debug dbg)
775 {
776 Dwarf_CU cu;
777 Dwarf_Die die;
778 Dwarf_Error error;
779 Dwarf_Half cu_pointer_size;
780 Dwarf_Half cu_version;
781 Dwarf_Unsigned cu_abbrev_offset;
782 Dwarf_Unsigned cu_header_length;
783 Dwarf_Unsigned cu_next_offset;
784
785 STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
786 printf ("\nCompilation Unit @ offset %llx:\n",
787 (unsigned long long) cu->cu_offset);
788 printf (" Length: %lu\n", (u_long) cu->cu_length);
789 printf (" Version: %hu\n", cu->cu_version);
790 printf (" Abbrev Offset: %lu\n", (u_long) cu->cu_abbrev_offset);
791 printf (" Pointer Size: %u\n", (u_int) cu->cu_pointer_size);
792
793 if (dwarf_next_cu_header(dbg, &cu_header_length,
794 &cu_version, &cu_abbrev_offset, &cu_pointer_size,
795 &cu_next_offset, &error) != DWARF_E_NONE) {
796 printf("Error %s\n", dwarf_errmsg(&error));
797 return;
798 }
799
800 if (dwarf_siblingof(dbg, NULL, &die, &error) != DWARF_E_NONE) {
801 printf("Error %s\n", dwarf_errmsg(&error));
802 return;
803 }
804
805 dwarf_dump_tree_dies(dbg, die, &error);
806
807 }
808 }
809
810 void
dwarf_dump_info(Dwarf_Debug dbg)811 dwarf_dump_info(Dwarf_Debug dbg)
812 {
813 Dwarf_CU cu;
814 Dwarf_Die die;
815
816 printf("Contents of the .debug_info section:\n");
817
818 STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
819 printf ("\nCompilation Unit @ offset %llx:\n",
820 (unsigned long long) cu->cu_offset);
821 printf (" Length: %lu\n", (u_long) cu->cu_length);
822 printf (" Version: %hu\n", cu->cu_version);
823 printf (" Abbrev Offset: %lu\n", (u_long) cu->cu_abbrev_offset);
824 printf (" Pointer Size: %u\n", (u_int) cu->cu_pointer_size);
825
826 STAILQ_FOREACH(die, &cu->cu_die, die_next)
827 dwarf_dump_die(die);
828 }
829 }
830
831
832 void
dwarf_dump_shstrtab(Dwarf_Debug dbg)833 dwarf_dump_shstrtab(Dwarf_Debug dbg)
834 {
835 char *name;
836 int indx = 0;
837
838 printf("---------------------\nSection header string table contents:\n");
839 while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_stnum, indx)) != NULL) {
840 printf("%5d '%s'\n",indx,name);
841 indx += strlen(name) + 1;
842 }
843 }
844
845 void
dwarf_dump_strtab(Dwarf_Debug dbg)846 dwarf_dump_strtab(Dwarf_Debug dbg)
847 {
848 char *name;
849 int indx = 0;
850
851 printf("---------------------\nString table contents:\n");
852 while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_strtab].s_shnum, indx)) != NULL) {
853 printf("%5d '%s'\n",indx,name);
854 indx += strlen(name) + 1;
855 }
856 }
857
858 void
dwarf_dump_dbgstr(Dwarf_Debug dbg)859 dwarf_dump_dbgstr(Dwarf_Debug dbg)
860 {
861 char *name;
862 int indx = 0;
863
864 printf("---------------------\nDebug string table contents:\n");
865 while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_debug_str].s_shnum, indx)) != NULL) {
866 printf("%5d '%s'\n",indx,name);
867 indx += strlen(name) + 1;
868 }
869 }
870
871 void
dwarf_dump_symtab(Dwarf_Debug dbg)872 dwarf_dump_symtab(Dwarf_Debug dbg)
873 {
874 GElf_Sym sym;
875 char *name;
876 int indx = 0;
877
878 printf("---------------------\nSymbol table contents:\n");
879 while (gelf_getsym(dbg->dbg_s[DWARF_symtab].s_data, indx++, &sym) != NULL) {
880 if ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_strtab].s_shnum, sym.st_name)) == NULL)
881 printf("sym.st_name %u indx %d sym.st_size %lu\n",sym.st_name,indx,(u_long) sym.st_size);
882 else
883 printf("'%s' sym.st_name %u indx %d sym.st_size %lu\n",name,sym.st_name,indx,(u_long) sym.st_size);
884 }
885 }
886
887 void
dwarf_dump(Dwarf_Debug dbg)888 dwarf_dump(Dwarf_Debug dbg)
889 {
890 dwarf_dump_strtab(dbg);
891 dwarf_dump_shstrtab(dbg);
892 dwarf_dump_dbgstr(dbg);
893 dwarf_dump_symtab(dbg);
894 dwarf_dump_info(dbg);
895 }
896