dwarf_dump.c revision 179187
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: head/lib/libdwarf/dwarf_dump.c 179187 2008-05-22 02:14:23Z jb $ 27 */ 28 29#include <stdlib.h> 30#include <string.h> 31#include "_libdwarf.h" 32 33const char * 34get_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 84const char * 85get_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 219const char * 220get_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_indirect: 244 return "DW_FORM_indirect"; 245 case DW_FORM_ref1: 246 return "DW_FORM_ref1"; 247 case DW_FORM_ref2: 248 return "DW_FORM_ref2"; 249 case DW_FORM_ref4: 250 return "DW_FORM_ref4"; 251 case DW_FORM_ref8: 252 return "DW_FORM_ref8"; 253 case DW_FORM_ref_addr: 254 return "DW_FORM_ref_addr"; 255 case DW_FORM_ref_udata: 256 return "DW_FORM_ref_udata"; 257 case DW_FORM_sdata: 258 return "DW_FORM_sdata"; 259 case DW_FORM_string: 260 return "DW_FORM_string"; 261 case DW_FORM_strp: 262 return "DW_FORM_strp"; 263 case DW_FORM_udata: 264 return "DW_FORM_udata"; 265 default: 266 break; 267 } 268 269 return "Unknown attribute"; 270} 271 272const char * 273get_tag_desc(uint32_t tag) 274{ 275 switch (tag) { 276 case DW_TAG_access_declaration: 277 return "DW_TAG_access_declaration"; 278 case DW_TAG_array_type: 279 return "DW_TAG_array_type"; 280 case DW_TAG_base_type: 281 return "DW_TAG_base_type"; 282 case DW_TAG_catch_block: 283 return "DW_TAG_catch_block"; 284 case DW_TAG_class_type: 285 return "DW_TAG_class_type"; 286 case DW_TAG_common_block: 287 return "DW_TAG_common_block"; 288 case DW_TAG_common_inclusion: 289 return "DW_TAG_common_inclusion"; 290 case DW_TAG_compile_unit: 291 return "DW_TAG_compile_unit"; 292 case DW_TAG_condition: 293 return "DW_TAG_condition"; 294 case DW_TAG_const_type: 295 return "DW_TAG_const_type"; 296 case DW_TAG_constant: 297 return "DW_TAG_constant"; 298 case DW_TAG_dwarf_procedure: 299 return "DW_TAG_dwarf_procedure"; 300 case DW_TAG_entry_point: 301 return "DW_TAG_entry_point"; 302 case DW_TAG_enumeration_type: 303 return "DW_TAG_enumeration_type"; 304 case DW_TAG_enumerator: 305 return "DW_TAG_enumerator"; 306 case DW_TAG_formal_parameter: 307 return "DW_TAG_formal_parameter"; 308 case DW_TAG_friend: 309 return "DW_TAG_friend"; 310 case DW_TAG_imported_declaration: 311 return "DW_TAG_imported_declaration"; 312 case DW_TAG_imported_module: 313 return "DW_TAG_imported_module"; 314 case DW_TAG_imported_unit: 315 return "DW_TAG_imported_unit"; 316 case DW_TAG_inheritance: 317 return "DW_TAG_inheritance"; 318 case DW_TAG_inlined_subroutine: 319 return "DW_TAG_inlined_subroutine"; 320 case DW_TAG_interface_type: 321 return "DW_TAG_interface_type"; 322 case DW_TAG_label: 323 return "DW_TAG_label"; 324 case DW_TAG_lexical_block: 325 return "DW_TAG_lexical_block"; 326 case DW_TAG_member: 327 return "DW_TAG_member"; 328 case DW_TAG_module: 329 return "DW_TAG_module"; 330 case DW_TAG_namelist: 331 return "DW_TAG_namelist"; 332 case DW_TAG_namelist_item: 333 return "DW_TAG_namelist_item"; 334 case DW_TAG_namespace: 335 return "DW_TAG_namespace"; 336 case DW_TAG_packed_type: 337 return "DW_TAG_packed_type"; 338 case DW_TAG_partial_unit: 339 return "DW_TAG_partial_unit"; 340 case DW_TAG_pointer_type: 341 return "DW_TAG_pointer_type"; 342 case DW_TAG_ptr_to_member_type: 343 return "DW_TAG_ptr_to_member_type"; 344 case DW_TAG_reference_type: 345 return "DW_TAG_reference_type"; 346 case DW_TAG_restrict_type: 347 return "DW_TAG_restrict_type"; 348 case DW_TAG_set_type: 349 return "DW_TAG_set_type"; 350 case DW_TAG_shared_type: 351 return "DW_TAG_shared_type"; 352 case DW_TAG_string_type: 353 return "DW_TAG_string_type"; 354 case DW_TAG_structure_type: 355 return "DW_TAG_structure_type"; 356 case DW_TAG_subprogram: 357 return "DW_TAG_subprogram"; 358 case DW_TAG_subrange_type: 359 return "DW_TAG_subrange_type"; 360 case DW_TAG_subroutine_type: 361 return "DW_TAG_subroutine_type"; 362 case DW_TAG_template_type_parameter: 363 return "DW_TAG_template_type_parameter"; 364 case DW_TAG_template_value_parameter: 365 return "DW_TAG_template_value_parameter"; 366 case DW_TAG_thrown_type: 367 return "DW_TAG_thrown_type"; 368 case DW_TAG_try_block: 369 return "DW_TAG_try_block"; 370 case DW_TAG_typedef: 371 return "DW_TAG_typedef"; 372 case DW_TAG_union_type: 373 return "DW_TAG_union_type"; 374 case DW_TAG_unspecified_parameters: 375 return "DW_TAG_unspecified_parameters"; 376 case DW_TAG_unspecified_type: 377 return "DW_TAG_unspecified_type"; 378 case DW_TAG_variable: 379 return "DW_TAG_variable"; 380 case DW_TAG_variant: 381 return "DW_TAG_variant"; 382 case DW_TAG_variant_part: 383 return "DW_TAG_variant_part"; 384 case DW_TAG_volatile_type: 385 return "DW_TAG_volatile_type"; 386 case DW_TAG_with_stmt: 387 return "DW_TAG_with_stmt"; 388 default: 389 break; 390 } 391 392 return "Unknown tag"; 393} 394 395void 396dwarf_dump_abbrev(Dwarf_Debug dbg) 397{ 398 Dwarf_Abbrev a; 399 Dwarf_Attribute at; 400 Dwarf_CU cu; 401 402 printf("Contents of the .debug_abbrev section:\n\nEntry Tag\n"); 403 404 STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { 405 STAILQ_FOREACH(a, &cu->cu_abbrev, a_next) { 406 printf("%5lu %-30s [%s children]\n", 407 (u_long) a->a_entry, get_tag_desc(a->a_tag), 408 (a->a_children == DW_CHILDREN_yes) ? "has" : "no"); 409 410 STAILQ_FOREACH(at, &a->a_attrib, at_next) 411 printf(" %-30s %s\n", get_attr_desc(at->at_attrib), 412 get_form_desc(at->at_form)); 413 } 414 } 415} 416#ifdef DOODAD 417 case DW_AT_inline: 418 switch (uvalue) 419 { 420 case DW_INL_not_inlined: 421 printf (_("(not inlined)")); 422 break; 423 case DW_INL_inlined: 424 printf (_("(inlined)")); 425 break; 426 case DW_INL_declared_not_inlined: 427 printf (_("(declared as inline but ignored)")); 428 break; 429 case DW_INL_declared_inlined: 430 printf (_("(declared as inline and inlined)")); 431 break; 432 default: 433 printf (_(" (Unknown inline attribute value: %lx)"), uvalue); 434 break; 435 } 436 break; 437 438 case DW_AT_language: 439 switch (uvalue) 440 { 441 case DW_LANG_C: printf ("(non-ANSI C)"); break; 442 case DW_LANG_C89: printf ("(ANSI C)"); break; 443 case DW_LANG_C_plus_plus: printf ("(C++)"); break; 444 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break; 445 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break; 446 case DW_LANG_Modula2: printf ("(Modula 2)"); break; 447 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break; 448 case DW_LANG_Ada83: printf ("(Ada)"); break; 449 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break; 450 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break; 451 /* DWARF 2.1 values. */ 452 case DW_LANG_C99: printf ("(ANSI C99)"); break; 453 case DW_LANG_Ada95: printf ("(ADA 95)"); break; 454 case DW_LANG_Fortran95: printf ("(Fortran 95)"); break; 455 /* MIPS extension. */ 456 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break; 457 /* UPC extension. */ 458 case DW_LANG_Upc: printf ("(Unified Parallel C)"); break; 459 default: 460 printf ("(Unknown: %lx)", uvalue); 461 break; 462 } 463 break; 464 465 case DW_AT_encoding: 466 switch (uvalue) 467 { 468 case DW_ATE_void: printf ("(void)"); break; 469 case DW_ATE_address: printf ("(machine address)"); break; 470 case DW_ATE_boolean: printf ("(boolean)"); break; 471 case DW_ATE_complex_float: printf ("(complex float)"); break; 472 case DW_ATE_float: printf ("(float)"); break; 473 case DW_ATE_signed: printf ("(signed)"); break; 474 case DW_ATE_signed_char: printf ("(signed char)"); break; 475 case DW_ATE_unsigned: printf ("(unsigned)"); break; 476 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break; 477 /* DWARF 2.1 value. */ 478 case DW_ATE_imaginary_float: printf ("(imaginary float)"); break; 479 default: 480 if (uvalue >= DW_ATE_lo_user 481 && uvalue <= DW_ATE_hi_user) 482 printf ("(user defined type)"); 483 else 484 printf ("(unknown type)"); 485 break; 486 } 487 break; 488 489 case DW_AT_accessibility: 490 switch (uvalue) 491 { 492 case DW_ACCESS_public: printf ("(public)"); break; 493 case DW_ACCESS_protected: printf ("(protected)"); break; 494 case DW_ACCESS_private: printf ("(private)"); break; 495 default: 496 printf ("(unknown accessibility)"); 497 break; 498 } 499 break; 500 501 case DW_AT_visibility: 502 switch (uvalue) 503 { 504 case DW_VIS_local: printf ("(local)"); break; 505 case DW_VIS_exported: printf ("(exported)"); break; 506 case DW_VIS_qualified: printf ("(qualified)"); break; 507 default: printf ("(unknown visibility)"); break; 508 } 509 break; 510 511 case DW_AT_virtuality: 512 switch (uvalue) 513 { 514 case DW_VIRTUALITY_none: printf ("(none)"); break; 515 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break; 516 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break; 517 default: printf ("(unknown virtuality)"); break; 518 } 519 break; 520 521 case DW_AT_identifier_case: 522 switch (uvalue) 523 { 524 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break; 525 case DW_ID_up_case: printf ("(up_case)"); break; 526 case DW_ID_down_case: printf ("(down_case)"); break; 527 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break; 528 default: printf ("(unknown case)"); break; 529 } 530 break; 531 532 case DW_AT_calling_convention: 533 switch (uvalue) 534 { 535 case DW_CC_normal: printf ("(normal)"); break; 536 case DW_CC_program: printf ("(program)"); break; 537 case DW_CC_nocall: printf ("(nocall)"); break; 538 default: 539 if (uvalue >= DW_CC_lo_user 540 && uvalue <= DW_CC_hi_user) 541 printf ("(user defined)"); 542 else 543 printf ("(unknown convention)"); 544 } 545 break; 546 547 case DW_AT_ordering: 548 switch (uvalue) 549 { 550 case -1: printf ("(undefined)"); break; 551 case 0: printf ("(row major)"); break; 552 case 1: printf ("(column major)"); break; 553 } 554 break; 555 556 case DW_AT_frame_base: 557 case DW_AT_location: 558 case DW_AT_data_member_location: 559 case DW_AT_vtable_elem_location: 560 case DW_AT_allocated: 561 case DW_AT_associated: 562 case DW_AT_data_location: 563 case DW_AT_stride: 564 case DW_AT_upper_bound: 565 case DW_AT_lower_bound: 566 if (block_start) 567 { 568 printf ("("); 569 decode_location_expression (block_start, pointer_size, uvalue); 570 printf (")"); 571 } 572 else if (form == DW_FORM_data4 || form == DW_FORM_data8) 573 { 574 printf ("("); 575 printf ("location list"); 576 printf (")"); 577 } 578 break; 579#endif 580 581static void 582dwarf_dump_av_attr(Dwarf_Die die __unused, Dwarf_AttrValue av) 583{ 584 switch (av->av_attrib) { 585 case DW_AT_accessibility: 586 break; 587 588 case DW_AT_calling_convention: 589 break; 590 591 case DW_AT_encoding: 592 break; 593 594 case DW_AT_identifier_case: 595 break; 596 597 case DW_AT_inline: 598 break; 599 600 case DW_AT_language: 601 break; 602 603 case DW_AT_ordering: 604 break; 605 606 case DW_AT_virtuality: 607 break; 608 609 case DW_AT_visibility: 610 break; 611 612 case DW_AT_frame_base: 613 case DW_AT_location: 614 case DW_AT_data_member_location: 615 case DW_AT_vtable_elem_location: 616 case DW_AT_upper_bound: 617 case DW_AT_lower_bound: 618 break; 619 620 default: 621 break; 622 } 623} 624 625void 626dwarf_dump_av(Dwarf_Die die, Dwarf_AttrValue av) 627{ 628 uint64_t i; 629 630 printf(" %-30s : %-16s ", 631 get_attr_desc(av->av_attrib), 632 get_form_desc(av->av_form)); 633 634 switch (av->av_form) { 635 case DW_FORM_addr: 636 printf("0x%llx", (unsigned long long) av->u[0].u64); 637 break; 638 case DW_FORM_block: 639 case DW_FORM_block1: 640 case DW_FORM_block2: 641 case DW_FORM_block4: 642 printf("%lu byte block:", (u_long) av->u[0].u64); 643 for (i = 0; i < av->u[0].u64; i++) 644 printf(" %02x", av->u[1].u8p[i]); 645 break; 646 case DW_FORM_data1: 647 case DW_FORM_data2: 648 case DW_FORM_data4: 649 case DW_FORM_data8: 650 case DW_FORM_flag: 651 printf("%llu", (unsigned long long) av->u[0].u64); 652 break; 653 case DW_FORM_ref1: 654 case DW_FORM_ref2: 655 case DW_FORM_ref4: 656 case DW_FORM_ref8: 657 case DW_FORM_ref_udata: 658 printf("<%llx>", (unsigned long long) (av->u[0].u64 + 659 die->die_cu->cu_offset)); 660 break; 661 case DW_FORM_string: 662 printf("%s", av->u[0].s); 663 break; 664 case DW_FORM_strp: 665 printf("(indirect string, offset 0x%llx): %s", 666 (unsigned long long) av->u[0].u64, av->u[1].s); 667 break; 668 default: 669 printf("unknown form"); 670 break; 671 } 672 673 /* Dump any extra attribute-specific information. */ 674 dwarf_dump_av_attr(die, av); 675 676 printf("\n"); 677} 678 679void 680dwarf_dump_die_at_offset(Dwarf_Debug dbg, Dwarf_Off off) 681{ 682 Dwarf_CU cu; 683 Dwarf_Die die; 684 685 if (dbg == NULL) 686 return; 687 688 STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { 689 STAILQ_FOREACH(die, &cu->cu_die, die_next) { 690 if ((off_t) die->die_offset == off) { 691 dwarf_dump_die(die); 692 return; 693 } 694 } 695 } 696} 697 698void 699dwarf_dump_die(Dwarf_Die die) 700{ 701 Dwarf_AttrValue av; 702 703 printf("<%d><%llx>: Abbrev number: %llu (%s)\n", 704 die->die_level, (unsigned long long) die->die_offset, 705 (unsigned long long) die->die_abnum, 706 get_tag_desc(die->die_a->a_tag)); 707 708 STAILQ_FOREACH(av, &die->die_attrval, av_next) 709 dwarf_dump_av(die, av); 710} 711 712void 713dwarf_dump_raw(Dwarf_Debug dbg) 714{ 715 Dwarf_CU cu; 716 char *p = (char *) dbg; 717 int i; 718 719 printf("dbg %p\n",dbg); 720 721 if (dbg == NULL) 722 return; 723 724 for (i = 0; i < (int) sizeof(*dbg); i++) { 725 if (*p >= 0x20 && *p < 0x7f) { 726 printf(" %c",*p++ & 0xff); 727 } else { 728 printf(" %02x",*p++ & 0xff); 729 } 730 } 731 printf("\n"); 732 733 STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { 734 p = (char *) cu; 735 printf("cu %p\n",cu); 736 for (i = 0; i < (int) sizeof(*cu); i++) { 737 if (*p >= 0x20 && *p < 0x7f) { 738 printf(" %c",*p++ & 0xff); 739 } else { 740 printf(" %02x",*p++ & 0xff); 741 } 742 } 743 printf("\n"); 744 } 745} 746 747static void 748dwarf_dump_tree_dies(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Error *error) 749{ 750 Dwarf_Die child; 751 int ret; 752 753 do { 754 dwarf_dump_die(die); 755 756 if ((ret = dwarf_child(die, &child, error) == DWARF_E_NO_ENTRY)) { 757 /* No children. */ 758 } else if (ret != DWARF_E_NONE) { 759 printf("Error %s\n", dwarf_errmsg(error)); 760 return; 761 } else 762 dwarf_dump_tree_dies(dbg, child, error); 763 764 if (dwarf_siblingof(dbg, die, &die, error) != DWARF_E_NONE) 765 die = NULL; 766 767 } while (die != NULL); 768} 769 770void 771dwarf_dump_tree(Dwarf_Debug dbg) 772{ 773 Dwarf_CU cu; 774 Dwarf_Die die; 775 Dwarf_Error error; 776 Dwarf_Half cu_pointer_size; 777 Dwarf_Half cu_version; 778 Dwarf_Unsigned cu_abbrev_offset; 779 Dwarf_Unsigned cu_header_length; 780 Dwarf_Unsigned cu_next_offset; 781 782 STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { 783 printf ("\nCompilation Unit @ offset %llx:\n", 784 (unsigned long long) cu->cu_offset); 785 printf (" Length: %lu\n", (u_long) cu->cu_length); 786 printf (" Version: %hu\n", cu->cu_version); 787 printf (" Abbrev Offset: %lu\n", (u_long) cu->cu_abbrev_offset); 788 printf (" Pointer Size: %u\n", (u_int) cu->cu_pointer_size); 789 790 if (dwarf_next_cu_header(dbg, &cu_header_length, 791 &cu_version, &cu_abbrev_offset, &cu_pointer_size, 792 &cu_next_offset, &error) != DWARF_E_NONE) { 793 printf("Error %s\n", dwarf_errmsg(&error)); 794 return; 795 } 796 797 if (dwarf_siblingof(dbg, NULL, &die, &error) != DWARF_E_NONE) { 798 printf("Error %s\n", dwarf_errmsg(&error)); 799 return; 800 } 801 802 dwarf_dump_tree_dies(dbg, die, &error); 803 804 } 805} 806 807void 808dwarf_dump_info(Dwarf_Debug dbg) 809{ 810 Dwarf_CU cu; 811 Dwarf_Die die; 812 813 printf("Contents of the .debug_info section:\n"); 814 815 STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { 816 printf ("\nCompilation Unit @ offset %llx:\n", 817 (unsigned long long) cu->cu_offset); 818 printf (" Length: %lu\n", (u_long) cu->cu_length); 819 printf (" Version: %hu\n", cu->cu_version); 820 printf (" Abbrev Offset: %lu\n", (u_long) cu->cu_abbrev_offset); 821 printf (" Pointer Size: %u\n", (u_int) cu->cu_pointer_size); 822 823 STAILQ_FOREACH(die, &cu->cu_die, die_next) 824 dwarf_dump_die(die); 825 } 826} 827 828 829void 830dwarf_dump_shstrtab(Dwarf_Debug dbg) 831{ 832 char *name; 833 int indx = 0; 834 835 printf("---------------------\nSection header string table contents:\n"); 836 while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_stnum, indx)) != NULL) { 837 printf("%5d '%s'\n",indx,name); 838 indx += strlen(name) + 1; 839 } 840} 841 842void 843dwarf_dump_strtab(Dwarf_Debug dbg) 844{ 845 char *name; 846 int indx = 0; 847 848 printf("---------------------\nString table contents:\n"); 849 while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_strtab].s_shnum, indx)) != NULL) { 850 printf("%5d '%s'\n",indx,name); 851 indx += strlen(name) + 1; 852 } 853} 854 855void 856dwarf_dump_dbgstr(Dwarf_Debug dbg) 857{ 858 char *name; 859 int indx = 0; 860 861 printf("---------------------\nDebug string table contents:\n"); 862 while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_debug_str].s_shnum, indx)) != NULL) { 863 printf("%5d '%s'\n",indx,name); 864 indx += strlen(name) + 1; 865 } 866} 867 868void 869dwarf_dump_symtab(Dwarf_Debug dbg) 870{ 871 GElf_Sym sym; 872 char *name; 873 int indx = 0; 874 875 printf("---------------------\nSymbol table contents:\n"); 876 while (gelf_getsym(dbg->dbg_s[DWARF_symtab].s_data, indx++, &sym) != NULL) { 877 if ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_strtab].s_shnum, sym.st_name)) == NULL) 878 printf("sym.st_name %u indx %d sym.st_size %lu\n",sym.st_name,indx,(u_long) sym.st_size); 879 else 880 printf("'%s' sym.st_name %u indx %d sym.st_size %lu\n",name,sym.st_name,indx,(u_long) sym.st_size); 881 } 882} 883 884void 885dwarf_dump(Dwarf_Debug dbg) 886{ 887 dwarf_dump_strtab(dbg); 888 dwarf_dump_shstrtab(dbg); 889 dwarf_dump_dbgstr(dbg); 890 dwarf_dump_symtab(dbg); 891 dwarf_dump_info(dbg); 892} 893