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 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_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 274const char * 275get_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 397void 398dwarf_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 583static void 584dwarf_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 627void 628dwarf_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 682void 683dwarf_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 701void 702dwarf_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 715void 716dwarf_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 750static void 751dwarf_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 773void 774dwarf_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 810void 811dwarf_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 832void 833dwarf_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 845void 846dwarf_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 858void 859dwarf_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 871void 872dwarf_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 887void 888dwarf_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