1179187Sjb/*- 2179187Sjb * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3179187Sjb * All rights reserved. 4179187Sjb * 5179187Sjb * Redistribution and use in source and binary forms, with or without 6179187Sjb * modification, are permitted provided that the following conditions 7179187Sjb * are met: 8179187Sjb * 1. Redistributions of source code must retain the above copyright 9179187Sjb * notice, this list of conditions and the following disclaimer. 10179187Sjb * 2. Redistributions in binary form must reproduce the above copyright 11179187Sjb * notice, this list of conditions and the following disclaimer in the 12179187Sjb * documentation and/or other materials provided with the distribution. 13179187Sjb * 14179187Sjb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15179187Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16179187Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17179187Sjb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18179187Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19179187Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20179187Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21179187Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22179187Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23179187Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24179187Sjb * SUCH DAMAGE. 25179187Sjb * 26179187Sjb * $FreeBSD$ 27179187Sjb */ 28179187Sjb 29179187Sjb#include <stdlib.h> 30179187Sjb#include <string.h> 31179187Sjb#include "_libdwarf.h" 32179187Sjb 33179187Sjbconst char * 34179187Sjbget_sht_desc(uint32_t sh_type) 35179187Sjb{ 36179187Sjb switch (sh_type) { 37179187Sjb case SHT_NULL: 38179187Sjb return "inactive"; 39179187Sjb case SHT_PROGBITS: 40179187Sjb return "program defined information"; 41179187Sjb case SHT_SYMTAB: 42179187Sjb return "symbol table section"; 43179187Sjb case SHT_STRTAB: 44179187Sjb return "string table section"; 45179187Sjb case SHT_RELA: 46179187Sjb return "relocation section with addends"; 47179187Sjb case SHT_HASH: 48179187Sjb return "symbol hash table section"; 49179187Sjb case SHT_DYNAMIC: 50179187Sjb return "dynamic section"; 51179187Sjb case SHT_NOTE: 52179187Sjb return "note section"; 53179187Sjb case SHT_NOBITS: 54179187Sjb return "no space section"; 55179187Sjb case SHT_REL: 56179187Sjb return "relocation section - no addends"; 57179187Sjb case SHT_SHLIB: 58179187Sjb return "reserved - purpose unknown"; 59179187Sjb case SHT_DYNSYM: 60179187Sjb return "dynamic symbol table section"; 61179187Sjb case SHT_INIT_ARRAY: 62179187Sjb return "Initialization function pointers."; 63179187Sjb case SHT_FINI_ARRAY: 64179187Sjb return "Termination function pointers."; 65179187Sjb case SHT_PREINIT_ARRAY: 66179187Sjb return "Pre-initialization function ptrs."; 67179187Sjb case SHT_GROUP: 68179187Sjb return "Section group."; 69179187Sjb case SHT_SYMTAB_SHNDX: 70179187Sjb return "Section indexes (see SHN_XINDEX)."; 71179187Sjb case SHT_GNU_verdef: 72179187Sjb return "Symbol versions provided"; 73179187Sjb case SHT_GNU_verneed: 74179187Sjb return "Symbol versions required"; 75179187Sjb case SHT_GNU_versym: 76179187Sjb return "Symbol version table"; 77179187Sjb case SHT_AMD64_UNWIND: 78179187Sjb return "AMD64 unwind"; 79179187Sjb default: 80179187Sjb return "Unknown"; 81179187Sjb } 82179187Sjb} 83179187Sjb 84179187Sjbconst char * 85179187Sjbget_attr_desc(uint32_t attr) 86179187Sjb{ 87179187Sjb switch (attr) { 88179187Sjb case DW_AT_abstract_origin: 89179187Sjb return "DW_AT_abstract_origin"; 90179187Sjb case DW_AT_accessibility: 91179187Sjb return "DW_AT_accessibility"; 92179187Sjb case DW_AT_address_class: 93179187Sjb return "DW_AT_address_class"; 94179187Sjb case DW_AT_artificial: 95179187Sjb return "DW_AT_artificial"; 96179187Sjb case DW_AT_base_types: 97179187Sjb return "DW_AT_base_types"; 98179187Sjb case DW_AT_bit_offset: 99179187Sjb return "DW_AT_bit_offset"; 100179187Sjb case DW_AT_bit_size: 101179187Sjb return "DW_AT_bit_size"; 102179187Sjb case DW_AT_byte_size: 103179187Sjb return "DW_AT_byte_size"; 104179187Sjb case DW_AT_calling_convention: 105179187Sjb return "DW_AT_calling_convention"; 106179187Sjb case DW_AT_common_reference: 107179187Sjb return "DW_AT_common_reference"; 108179187Sjb case DW_AT_comp_dir: 109179187Sjb return "DW_AT_comp_dir"; 110179187Sjb case DW_AT_const_value: 111179187Sjb return "DW_AT_const_value"; 112179187Sjb case DW_AT_containing_type: 113179187Sjb return "DW_AT_containing_type"; 114179187Sjb case DW_AT_count: 115179187Sjb return "DW_AT_count"; 116179187Sjb case DW_AT_data_member_location: 117179187Sjb return "DW_AT_data_member_location"; 118179187Sjb case DW_AT_decl_column: 119179187Sjb return "DW_AT_decl_column"; 120179187Sjb case DW_AT_decl_file: 121179187Sjb return "DW_AT_decl_file"; 122179187Sjb case DW_AT_decl_line: 123179187Sjb return "DW_AT_decl_line"; 124179187Sjb case DW_AT_declaration: 125179187Sjb return "DW_AT_declaration"; 126179187Sjb case DW_AT_default_value: 127179187Sjb return "DW_AT_default_value"; 128179187Sjb case DW_AT_discr: 129179187Sjb return "DW_AT_discr"; 130179187Sjb case DW_AT_discr_list: 131179187Sjb return "DW_AT_discr_list"; 132179187Sjb case DW_AT_discr_value: 133179187Sjb return "DW_AT_discr_value"; 134179187Sjb case DW_AT_element_list: 135179187Sjb return "DW_AT_element_list"; 136179187Sjb case DW_AT_encoding: 137179187Sjb return "DW_AT_encoding"; 138179187Sjb case DW_AT_external: 139179187Sjb return "DW_AT_external"; 140179187Sjb case DW_AT_frame_base: 141179187Sjb return "DW_AT_frame_base"; 142179187Sjb case DW_AT_friend: 143179187Sjb return "DW_AT_friend"; 144179187Sjb case DW_AT_high_pc: 145179187Sjb return "DW_AT_high_pc"; 146179187Sjb case DW_AT_identifier_case: 147179187Sjb return "DW_AT_identifier_case"; 148179187Sjb case DW_AT_import: 149179187Sjb return "DW_AT_import"; 150179187Sjb case DW_AT_inline: 151179187Sjb return "DW_AT_inline"; 152179187Sjb case DW_AT_is_optional: 153179187Sjb return "DW_AT_is_optional"; 154179187Sjb case DW_AT_language: 155179187Sjb return "DW_AT_language"; 156179187Sjb case DW_AT_location: 157179187Sjb return "DW_AT_location"; 158179187Sjb case DW_AT_low_pc: 159179187Sjb return "DW_AT_low_pc"; 160179187Sjb case DW_AT_lower_bound: 161179187Sjb return "DW_AT_lower_bound"; 162179187Sjb case DW_AT_macro_info: 163179187Sjb return "DW_AT_macro_info"; 164179187Sjb case DW_AT_member: 165179187Sjb return "DW_AT_member"; 166179187Sjb case DW_AT_name: 167179187Sjb return "DW_AT_name"; 168179187Sjb case DW_AT_namelist_item: 169179187Sjb return "DW_AT_namelist_item"; 170179187Sjb case DW_AT_ordering: 171179187Sjb return "DW_AT_ordering"; 172179187Sjb case DW_AT_priority: 173179187Sjb return "DW_AT_priority"; 174179187Sjb case DW_AT_producer: 175179187Sjb return "DW_AT_producer"; 176179187Sjb case DW_AT_prototyped: 177179187Sjb return "DW_AT_prototyped"; 178179187Sjb case DW_AT_return_addr: 179179187Sjb return "DW_AT_return_addr"; 180179187Sjb case DW_AT_segment: 181179187Sjb return "DW_AT_segment"; 182179187Sjb case DW_AT_sibling: 183179187Sjb return "DW_AT_sibling"; 184179187Sjb case DW_AT_specification: 185179187Sjb return "DW_AT_specification"; 186179187Sjb case DW_AT_start_scope: 187179187Sjb return "DW_AT_start_scope"; 188179187Sjb case DW_AT_static_link: 189179187Sjb return "DW_AT_static_link"; 190179187Sjb case DW_AT_stmt_list: 191179187Sjb return "DW_AT_stmt_list"; 192179187Sjb case DW_AT_stride_size: 193179187Sjb return "DW_AT_stride_size"; 194179187Sjb case DW_AT_string_length: 195179187Sjb return "DW_AT_string_length"; 196179187Sjb case DW_AT_subscr_data: 197179187Sjb return "DW_AT_subscr_data"; 198179187Sjb case DW_AT_type: 199179187Sjb return "DW_AT_type"; 200179187Sjb case DW_AT_upper_bound: 201179187Sjb return "DW_AT_upper_bound"; 202179187Sjb case DW_AT_use_location: 203179187Sjb return "DW_AT_use_location"; 204179187Sjb case DW_AT_variable_parameter: 205179187Sjb return "DW_AT_variable_parameter"; 206179187Sjb case DW_AT_virtuality: 207179187Sjb return "DW_AT_virtuality"; 208179187Sjb case DW_AT_visibility: 209179187Sjb return "DW_AT_visibility"; 210179187Sjb case DW_AT_vtable_elem_location: 211179187Sjb return "DW_AT_vtable_elem_location"; 212179187Sjb default: 213179187Sjb break; 214179187Sjb } 215179187Sjb 216179187Sjb return "Unknown attribute"; 217179187Sjb} 218179187Sjb 219179187Sjbconst char * 220179187Sjbget_form_desc(uint32_t form) 221179187Sjb{ 222179187Sjb switch (form) { 223179187Sjb case DW_FORM_addr: 224179187Sjb return "DW_FORM_addr"; 225179187Sjb case DW_FORM_block: 226179187Sjb return "DW_FORM_block"; 227179187Sjb case DW_FORM_block1: 228179187Sjb return "DW_FORM_block1"; 229179187Sjb case DW_FORM_block2: 230179187Sjb return "DW_FORM_block2"; 231179187Sjb case DW_FORM_block4: 232179187Sjb return "DW_FORM_block4"; 233179187Sjb case DW_FORM_data1: 234179187Sjb return "DW_FORM_data1"; 235179187Sjb case DW_FORM_data2: 236179187Sjb return "DW_FORM_data2"; 237179187Sjb case DW_FORM_data4: 238179187Sjb return "DW_FORM_data4"; 239179187Sjb case DW_FORM_data8: 240179187Sjb return "DW_FORM_data8"; 241179187Sjb case DW_FORM_flag: 242179187Sjb return "DW_FORM_flag"; 243239872Sdim case DW_FORM_flag_present: 244239872Sdim return "DW_FORM_flag_present"; 245179187Sjb case DW_FORM_indirect: 246179187Sjb return "DW_FORM_indirect"; 247179187Sjb case DW_FORM_ref1: 248179187Sjb return "DW_FORM_ref1"; 249179187Sjb case DW_FORM_ref2: 250179187Sjb return "DW_FORM_ref2"; 251179187Sjb case DW_FORM_ref4: 252179187Sjb return "DW_FORM_ref4"; 253179187Sjb case DW_FORM_ref8: 254179187Sjb return "DW_FORM_ref8"; 255179187Sjb case DW_FORM_ref_addr: 256179187Sjb return "DW_FORM_ref_addr"; 257179187Sjb case DW_FORM_ref_udata: 258179187Sjb return "DW_FORM_ref_udata"; 259179187Sjb case DW_FORM_sdata: 260179187Sjb return "DW_FORM_sdata"; 261179187Sjb case DW_FORM_string: 262179187Sjb return "DW_FORM_string"; 263179187Sjb case DW_FORM_strp: 264179187Sjb return "DW_FORM_strp"; 265179187Sjb case DW_FORM_udata: 266179187Sjb return "DW_FORM_udata"; 267179187Sjb default: 268179187Sjb break; 269179187Sjb } 270179187Sjb 271179187Sjb return "Unknown attribute"; 272179187Sjb} 273179187Sjb 274179187Sjbconst char * 275179187Sjbget_tag_desc(uint32_t tag) 276179187Sjb{ 277179187Sjb switch (tag) { 278179187Sjb case DW_TAG_access_declaration: 279179187Sjb return "DW_TAG_access_declaration"; 280179187Sjb case DW_TAG_array_type: 281179187Sjb return "DW_TAG_array_type"; 282179187Sjb case DW_TAG_base_type: 283179187Sjb return "DW_TAG_base_type"; 284179187Sjb case DW_TAG_catch_block: 285179187Sjb return "DW_TAG_catch_block"; 286179187Sjb case DW_TAG_class_type: 287179187Sjb return "DW_TAG_class_type"; 288179187Sjb case DW_TAG_common_block: 289179187Sjb return "DW_TAG_common_block"; 290179187Sjb case DW_TAG_common_inclusion: 291179187Sjb return "DW_TAG_common_inclusion"; 292179187Sjb case DW_TAG_compile_unit: 293179187Sjb return "DW_TAG_compile_unit"; 294179187Sjb case DW_TAG_condition: 295179187Sjb return "DW_TAG_condition"; 296179187Sjb case DW_TAG_const_type: 297179187Sjb return "DW_TAG_const_type"; 298179187Sjb case DW_TAG_constant: 299179187Sjb return "DW_TAG_constant"; 300179187Sjb case DW_TAG_dwarf_procedure: 301179187Sjb return "DW_TAG_dwarf_procedure"; 302179187Sjb case DW_TAG_entry_point: 303179187Sjb return "DW_TAG_entry_point"; 304179187Sjb case DW_TAG_enumeration_type: 305179187Sjb return "DW_TAG_enumeration_type"; 306179187Sjb case DW_TAG_enumerator: 307179187Sjb return "DW_TAG_enumerator"; 308179187Sjb case DW_TAG_formal_parameter: 309179187Sjb return "DW_TAG_formal_parameter"; 310179187Sjb case DW_TAG_friend: 311179187Sjb return "DW_TAG_friend"; 312179187Sjb case DW_TAG_imported_declaration: 313179187Sjb return "DW_TAG_imported_declaration"; 314179187Sjb case DW_TAG_imported_module: 315179187Sjb return "DW_TAG_imported_module"; 316179187Sjb case DW_TAG_imported_unit: 317179187Sjb return "DW_TAG_imported_unit"; 318179187Sjb case DW_TAG_inheritance: 319179187Sjb return "DW_TAG_inheritance"; 320179187Sjb case DW_TAG_inlined_subroutine: 321179187Sjb return "DW_TAG_inlined_subroutine"; 322179187Sjb case DW_TAG_interface_type: 323179187Sjb return "DW_TAG_interface_type"; 324179187Sjb case DW_TAG_label: 325179187Sjb return "DW_TAG_label"; 326179187Sjb case DW_TAG_lexical_block: 327179187Sjb return "DW_TAG_lexical_block"; 328179187Sjb case DW_TAG_member: 329179187Sjb return "DW_TAG_member"; 330179187Sjb case DW_TAG_module: 331179187Sjb return "DW_TAG_module"; 332179187Sjb case DW_TAG_namelist: 333179187Sjb return "DW_TAG_namelist"; 334179187Sjb case DW_TAG_namelist_item: 335179187Sjb return "DW_TAG_namelist_item"; 336179187Sjb case DW_TAG_namespace: 337179187Sjb return "DW_TAG_namespace"; 338179187Sjb case DW_TAG_packed_type: 339179187Sjb return "DW_TAG_packed_type"; 340179187Sjb case DW_TAG_partial_unit: 341179187Sjb return "DW_TAG_partial_unit"; 342179187Sjb case DW_TAG_pointer_type: 343179187Sjb return "DW_TAG_pointer_type"; 344179187Sjb case DW_TAG_ptr_to_member_type: 345179187Sjb return "DW_TAG_ptr_to_member_type"; 346179187Sjb case DW_TAG_reference_type: 347179187Sjb return "DW_TAG_reference_type"; 348179187Sjb case DW_TAG_restrict_type: 349179187Sjb return "DW_TAG_restrict_type"; 350179187Sjb case DW_TAG_set_type: 351179187Sjb return "DW_TAG_set_type"; 352179187Sjb case DW_TAG_shared_type: 353179187Sjb return "DW_TAG_shared_type"; 354179187Sjb case DW_TAG_string_type: 355179187Sjb return "DW_TAG_string_type"; 356179187Sjb case DW_TAG_structure_type: 357179187Sjb return "DW_TAG_structure_type"; 358179187Sjb case DW_TAG_subprogram: 359179187Sjb return "DW_TAG_subprogram"; 360179187Sjb case DW_TAG_subrange_type: 361179187Sjb return "DW_TAG_subrange_type"; 362179187Sjb case DW_TAG_subroutine_type: 363179187Sjb return "DW_TAG_subroutine_type"; 364179187Sjb case DW_TAG_template_type_parameter: 365179187Sjb return "DW_TAG_template_type_parameter"; 366179187Sjb case DW_TAG_template_value_parameter: 367179187Sjb return "DW_TAG_template_value_parameter"; 368179187Sjb case DW_TAG_thrown_type: 369179187Sjb return "DW_TAG_thrown_type"; 370179187Sjb case DW_TAG_try_block: 371179187Sjb return "DW_TAG_try_block"; 372179187Sjb case DW_TAG_typedef: 373179187Sjb return "DW_TAG_typedef"; 374179187Sjb case DW_TAG_union_type: 375179187Sjb return "DW_TAG_union_type"; 376179187Sjb case DW_TAG_unspecified_parameters: 377179187Sjb return "DW_TAG_unspecified_parameters"; 378179187Sjb case DW_TAG_unspecified_type: 379179187Sjb return "DW_TAG_unspecified_type"; 380179187Sjb case DW_TAG_variable: 381179187Sjb return "DW_TAG_variable"; 382179187Sjb case DW_TAG_variant: 383179187Sjb return "DW_TAG_variant"; 384179187Sjb case DW_TAG_variant_part: 385179187Sjb return "DW_TAG_variant_part"; 386179187Sjb case DW_TAG_volatile_type: 387179187Sjb return "DW_TAG_volatile_type"; 388179187Sjb case DW_TAG_with_stmt: 389179187Sjb return "DW_TAG_with_stmt"; 390179187Sjb default: 391179187Sjb break; 392179187Sjb } 393179187Sjb 394179187Sjb return "Unknown tag"; 395179187Sjb} 396179187Sjb 397179187Sjbvoid 398179187Sjbdwarf_dump_abbrev(Dwarf_Debug dbg) 399179187Sjb{ 400179187Sjb Dwarf_Abbrev a; 401179187Sjb Dwarf_Attribute at; 402179187Sjb Dwarf_CU cu; 403179187Sjb 404179187Sjb printf("Contents of the .debug_abbrev section:\n\nEntry Tag\n"); 405179187Sjb 406179187Sjb STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { 407179187Sjb STAILQ_FOREACH(a, &cu->cu_abbrev, a_next) { 408179187Sjb printf("%5lu %-30s [%s children]\n", 409179187Sjb (u_long) a->a_entry, get_tag_desc(a->a_tag), 410179187Sjb (a->a_children == DW_CHILDREN_yes) ? "has" : "no"); 411179187Sjb 412179187Sjb STAILQ_FOREACH(at, &a->a_attrib, at_next) 413179187Sjb printf(" %-30s %s\n", get_attr_desc(at->at_attrib), 414179187Sjb get_form_desc(at->at_form)); 415179187Sjb } 416179187Sjb } 417179187Sjb} 418179187Sjb#ifdef DOODAD 419179187Sjb case DW_AT_inline: 420179187Sjb switch (uvalue) 421179187Sjb { 422179187Sjb case DW_INL_not_inlined: 423179187Sjb printf (_("(not inlined)")); 424179187Sjb break; 425179187Sjb case DW_INL_inlined: 426179187Sjb printf (_("(inlined)")); 427179187Sjb break; 428179187Sjb case DW_INL_declared_not_inlined: 429179187Sjb printf (_("(declared as inline but ignored)")); 430179187Sjb break; 431179187Sjb case DW_INL_declared_inlined: 432179187Sjb printf (_("(declared as inline and inlined)")); 433179187Sjb break; 434179187Sjb default: 435179187Sjb printf (_(" (Unknown inline attribute value: %lx)"), uvalue); 436179187Sjb break; 437179187Sjb } 438179187Sjb break; 439179187Sjb 440179187Sjb case DW_AT_language: 441179187Sjb switch (uvalue) 442179187Sjb { 443179187Sjb case DW_LANG_C: printf ("(non-ANSI C)"); break; 444179187Sjb case DW_LANG_C89: printf ("(ANSI C)"); break; 445179187Sjb case DW_LANG_C_plus_plus: printf ("(C++)"); break; 446179187Sjb case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break; 447179187Sjb case DW_LANG_Fortran90: printf ("(Fortran 90)"); break; 448179187Sjb case DW_LANG_Modula2: printf ("(Modula 2)"); break; 449179187Sjb case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break; 450179187Sjb case DW_LANG_Ada83: printf ("(Ada)"); break; 451179187Sjb case DW_LANG_Cobol74: printf ("(Cobol 74)"); break; 452179187Sjb case DW_LANG_Cobol85: printf ("(Cobol 85)"); break; 453179187Sjb /* DWARF 2.1 values. */ 454179187Sjb case DW_LANG_C99: printf ("(ANSI C99)"); break; 455179187Sjb case DW_LANG_Ada95: printf ("(ADA 95)"); break; 456179187Sjb case DW_LANG_Fortran95: printf ("(Fortran 95)"); break; 457179187Sjb /* MIPS extension. */ 458179187Sjb case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break; 459179187Sjb /* UPC extension. */ 460179187Sjb case DW_LANG_Upc: printf ("(Unified Parallel C)"); break; 461179187Sjb default: 462179187Sjb printf ("(Unknown: %lx)", uvalue); 463179187Sjb break; 464179187Sjb } 465179187Sjb break; 466179187Sjb 467179187Sjb case DW_AT_encoding: 468179187Sjb switch (uvalue) 469179187Sjb { 470179187Sjb case DW_ATE_void: printf ("(void)"); break; 471179187Sjb case DW_ATE_address: printf ("(machine address)"); break; 472179187Sjb case DW_ATE_boolean: printf ("(boolean)"); break; 473179187Sjb case DW_ATE_complex_float: printf ("(complex float)"); break; 474179187Sjb case DW_ATE_float: printf ("(float)"); break; 475179187Sjb case DW_ATE_signed: printf ("(signed)"); break; 476179187Sjb case DW_ATE_signed_char: printf ("(signed char)"); break; 477179187Sjb case DW_ATE_unsigned: printf ("(unsigned)"); break; 478179187Sjb case DW_ATE_unsigned_char: printf ("(unsigned char)"); break; 479179187Sjb /* DWARF 2.1 value. */ 480179187Sjb case DW_ATE_imaginary_float: printf ("(imaginary float)"); break; 481179187Sjb default: 482179187Sjb if (uvalue >= DW_ATE_lo_user 483179187Sjb && uvalue <= DW_ATE_hi_user) 484179187Sjb printf ("(user defined type)"); 485179187Sjb else 486179187Sjb printf ("(unknown type)"); 487179187Sjb break; 488179187Sjb } 489179187Sjb break; 490179187Sjb 491179187Sjb case DW_AT_accessibility: 492179187Sjb switch (uvalue) 493179187Sjb { 494179187Sjb case DW_ACCESS_public: printf ("(public)"); break; 495179187Sjb case DW_ACCESS_protected: printf ("(protected)"); break; 496179187Sjb case DW_ACCESS_private: printf ("(private)"); break; 497179187Sjb default: 498179187Sjb printf ("(unknown accessibility)"); 499179187Sjb break; 500179187Sjb } 501179187Sjb break; 502179187Sjb 503179187Sjb case DW_AT_visibility: 504179187Sjb switch (uvalue) 505179187Sjb { 506179187Sjb case DW_VIS_local: printf ("(local)"); break; 507179187Sjb case DW_VIS_exported: printf ("(exported)"); break; 508179187Sjb case DW_VIS_qualified: printf ("(qualified)"); break; 509179187Sjb default: printf ("(unknown visibility)"); break; 510179187Sjb } 511179187Sjb break; 512179187Sjb 513179187Sjb case DW_AT_virtuality: 514179187Sjb switch (uvalue) 515179187Sjb { 516179187Sjb case DW_VIRTUALITY_none: printf ("(none)"); break; 517179187Sjb case DW_VIRTUALITY_virtual: printf ("(virtual)"); break; 518179187Sjb case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break; 519179187Sjb default: printf ("(unknown virtuality)"); break; 520179187Sjb } 521179187Sjb break; 522179187Sjb 523179187Sjb case DW_AT_identifier_case: 524179187Sjb switch (uvalue) 525179187Sjb { 526179187Sjb case DW_ID_case_sensitive: printf ("(case_sensitive)"); break; 527179187Sjb case DW_ID_up_case: printf ("(up_case)"); break; 528179187Sjb case DW_ID_down_case: printf ("(down_case)"); break; 529179187Sjb case DW_ID_case_insensitive: printf ("(case_insensitive)"); break; 530179187Sjb default: printf ("(unknown case)"); break; 531179187Sjb } 532179187Sjb break; 533179187Sjb 534179187Sjb case DW_AT_calling_convention: 535179187Sjb switch (uvalue) 536179187Sjb { 537179187Sjb case DW_CC_normal: printf ("(normal)"); break; 538179187Sjb case DW_CC_program: printf ("(program)"); break; 539179187Sjb case DW_CC_nocall: printf ("(nocall)"); break; 540179187Sjb default: 541179187Sjb if (uvalue >= DW_CC_lo_user 542179187Sjb && uvalue <= DW_CC_hi_user) 543179187Sjb printf ("(user defined)"); 544179187Sjb else 545179187Sjb printf ("(unknown convention)"); 546179187Sjb } 547179187Sjb break; 548179187Sjb 549179187Sjb case DW_AT_ordering: 550179187Sjb switch (uvalue) 551179187Sjb { 552179187Sjb case -1: printf ("(undefined)"); break; 553179187Sjb case 0: printf ("(row major)"); break; 554179187Sjb case 1: printf ("(column major)"); break; 555179187Sjb } 556179187Sjb break; 557179187Sjb 558179187Sjb case DW_AT_frame_base: 559179187Sjb case DW_AT_location: 560179187Sjb case DW_AT_data_member_location: 561179187Sjb case DW_AT_vtable_elem_location: 562179187Sjb case DW_AT_allocated: 563179187Sjb case DW_AT_associated: 564179187Sjb case DW_AT_data_location: 565179187Sjb case DW_AT_stride: 566179187Sjb case DW_AT_upper_bound: 567179187Sjb case DW_AT_lower_bound: 568179187Sjb if (block_start) 569179187Sjb { 570179187Sjb printf ("("); 571179187Sjb decode_location_expression (block_start, pointer_size, uvalue); 572179187Sjb printf (")"); 573179187Sjb } 574179187Sjb else if (form == DW_FORM_data4 || form == DW_FORM_data8) 575179187Sjb { 576179187Sjb printf ("("); 577179187Sjb printf ("location list"); 578179187Sjb printf (")"); 579179187Sjb } 580179187Sjb break; 581179187Sjb#endif 582179187Sjb 583179187Sjbstatic void 584179187Sjbdwarf_dump_av_attr(Dwarf_Die die __unused, Dwarf_AttrValue av) 585179187Sjb{ 586179187Sjb switch (av->av_attrib) { 587179187Sjb case DW_AT_accessibility: 588179187Sjb break; 589179187Sjb 590179187Sjb case DW_AT_calling_convention: 591179187Sjb break; 592179187Sjb 593179187Sjb case DW_AT_encoding: 594179187Sjb break; 595179187Sjb 596179187Sjb case DW_AT_identifier_case: 597179187Sjb break; 598179187Sjb 599179187Sjb case DW_AT_inline: 600179187Sjb break; 601179187Sjb 602179187Sjb case DW_AT_language: 603179187Sjb break; 604179187Sjb 605179187Sjb case DW_AT_ordering: 606179187Sjb break; 607179187Sjb 608179187Sjb case DW_AT_virtuality: 609179187Sjb break; 610179187Sjb 611179187Sjb case DW_AT_visibility: 612179187Sjb break; 613179187Sjb 614179187Sjb case DW_AT_frame_base: 615179187Sjb case DW_AT_location: 616179187Sjb case DW_AT_data_member_location: 617179187Sjb case DW_AT_vtable_elem_location: 618179187Sjb case DW_AT_upper_bound: 619179187Sjb case DW_AT_lower_bound: 620179187Sjb break; 621179187Sjb 622179187Sjb default: 623179187Sjb break; 624179187Sjb } 625179187Sjb} 626179187Sjb 627179187Sjbvoid 628179187Sjbdwarf_dump_av(Dwarf_Die die, Dwarf_AttrValue av) 629179187Sjb{ 630179187Sjb uint64_t i; 631179187Sjb 632179187Sjb printf(" %-30s : %-16s ", 633179187Sjb get_attr_desc(av->av_attrib), 634179187Sjb get_form_desc(av->av_form)); 635179187Sjb 636179187Sjb switch (av->av_form) { 637179187Sjb case DW_FORM_addr: 638179187Sjb printf("0x%llx", (unsigned long long) av->u[0].u64); 639179187Sjb break; 640179187Sjb case DW_FORM_block: 641179187Sjb case DW_FORM_block1: 642179187Sjb case DW_FORM_block2: 643179187Sjb case DW_FORM_block4: 644179187Sjb printf("%lu byte block:", (u_long) av->u[0].u64); 645179187Sjb for (i = 0; i < av->u[0].u64; i++) 646179187Sjb printf(" %02x", av->u[1].u8p[i]); 647179187Sjb break; 648179187Sjb case DW_FORM_data1: 649179187Sjb case DW_FORM_data2: 650179187Sjb case DW_FORM_data4: 651179187Sjb case DW_FORM_data8: 652179187Sjb case DW_FORM_flag: 653239872Sdim case DW_FORM_flag_present: 654179187Sjb printf("%llu", (unsigned long long) av->u[0].u64); 655179187Sjb break; 656179187Sjb case DW_FORM_ref1: 657179187Sjb case DW_FORM_ref2: 658179187Sjb case DW_FORM_ref4: 659179187Sjb case DW_FORM_ref8: 660179187Sjb case DW_FORM_ref_udata: 661179187Sjb printf("<%llx>", (unsigned long long) (av->u[0].u64 + 662179187Sjb die->die_cu->cu_offset)); 663179187Sjb break; 664179187Sjb case DW_FORM_string: 665179187Sjb printf("%s", av->u[0].s); 666179187Sjb break; 667179187Sjb case DW_FORM_strp: 668179187Sjb printf("(indirect string, offset 0x%llx): %s", 669179187Sjb (unsigned long long) av->u[0].u64, av->u[1].s); 670179187Sjb break; 671179187Sjb default: 672179187Sjb printf("unknown form"); 673179187Sjb break; 674179187Sjb } 675179187Sjb 676179187Sjb /* Dump any extra attribute-specific information. */ 677179187Sjb dwarf_dump_av_attr(die, av); 678179187Sjb 679179187Sjb printf("\n"); 680179187Sjb} 681179187Sjb 682179187Sjbvoid 683179187Sjbdwarf_dump_die_at_offset(Dwarf_Debug dbg, Dwarf_Off off) 684179187Sjb{ 685179187Sjb Dwarf_CU cu; 686179187Sjb Dwarf_Die die; 687179187Sjb 688179187Sjb if (dbg == NULL) 689179187Sjb return; 690179187Sjb 691179187Sjb STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { 692179187Sjb STAILQ_FOREACH(die, &cu->cu_die, die_next) { 693179187Sjb if ((off_t) die->die_offset == off) { 694179187Sjb dwarf_dump_die(die); 695179187Sjb return; 696179187Sjb } 697179187Sjb } 698179187Sjb } 699179187Sjb} 700179187Sjb 701179187Sjbvoid 702179187Sjbdwarf_dump_die(Dwarf_Die die) 703179187Sjb{ 704179187Sjb Dwarf_AttrValue av; 705179187Sjb 706179187Sjb printf("<%d><%llx>: Abbrev number: %llu (%s)\n", 707179187Sjb die->die_level, (unsigned long long) die->die_offset, 708179187Sjb (unsigned long long) die->die_abnum, 709179187Sjb get_tag_desc(die->die_a->a_tag)); 710179187Sjb 711179187Sjb STAILQ_FOREACH(av, &die->die_attrval, av_next) 712179187Sjb dwarf_dump_av(die, av); 713179187Sjb} 714179187Sjb 715179187Sjbvoid 716179187Sjbdwarf_dump_raw(Dwarf_Debug dbg) 717179187Sjb{ 718179187Sjb Dwarf_CU cu; 719179187Sjb char *p = (char *) dbg; 720179187Sjb int i; 721179187Sjb 722179187Sjb printf("dbg %p\n",dbg); 723179187Sjb 724179187Sjb if (dbg == NULL) 725179187Sjb return; 726179187Sjb 727179187Sjb for (i = 0; i < (int) sizeof(*dbg); i++) { 728179187Sjb if (*p >= 0x20 && *p < 0x7f) { 729179187Sjb printf(" %c",*p++ & 0xff); 730179187Sjb } else { 731179187Sjb printf(" %02x",*p++ & 0xff); 732179187Sjb } 733179187Sjb } 734179187Sjb printf("\n"); 735179187Sjb 736179187Sjb STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { 737179187Sjb p = (char *) cu; 738179187Sjb printf("cu %p\n",cu); 739179187Sjb for (i = 0; i < (int) sizeof(*cu); i++) { 740179187Sjb if (*p >= 0x20 && *p < 0x7f) { 741179187Sjb printf(" %c",*p++ & 0xff); 742179187Sjb } else { 743179187Sjb printf(" %02x",*p++ & 0xff); 744179187Sjb } 745179187Sjb } 746179187Sjb printf("\n"); 747179187Sjb } 748179187Sjb} 749179187Sjb 750179187Sjbstatic void 751179187Sjbdwarf_dump_tree_dies(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Error *error) 752179187Sjb{ 753179187Sjb Dwarf_Die child; 754179187Sjb int ret; 755179187Sjb 756179187Sjb do { 757179187Sjb dwarf_dump_die(die); 758179187Sjb 759179187Sjb if ((ret = dwarf_child(die, &child, error) == DWARF_E_NO_ENTRY)) { 760179187Sjb /* No children. */ 761179187Sjb } else if (ret != DWARF_E_NONE) { 762179187Sjb printf("Error %s\n", dwarf_errmsg(error)); 763179187Sjb return; 764179187Sjb } else 765179187Sjb dwarf_dump_tree_dies(dbg, child, error); 766179187Sjb 767179187Sjb if (dwarf_siblingof(dbg, die, &die, error) != DWARF_E_NONE) 768179187Sjb die = NULL; 769179187Sjb 770179187Sjb } while (die != NULL); 771179187Sjb} 772179187Sjb 773179187Sjbvoid 774179187Sjbdwarf_dump_tree(Dwarf_Debug dbg) 775179187Sjb{ 776179187Sjb Dwarf_CU cu; 777179187Sjb Dwarf_Die die; 778179187Sjb Dwarf_Error error; 779179187Sjb Dwarf_Half cu_pointer_size; 780179187Sjb Dwarf_Half cu_version; 781179187Sjb Dwarf_Unsigned cu_abbrev_offset; 782179187Sjb Dwarf_Unsigned cu_header_length; 783179187Sjb Dwarf_Unsigned cu_next_offset; 784179187Sjb 785179187Sjb STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { 786179187Sjb printf ("\nCompilation Unit @ offset %llx:\n", 787179187Sjb (unsigned long long) cu->cu_offset); 788179187Sjb printf (" Length: %lu\n", (u_long) cu->cu_length); 789179187Sjb printf (" Version: %hu\n", cu->cu_version); 790179187Sjb printf (" Abbrev Offset: %lu\n", (u_long) cu->cu_abbrev_offset); 791179187Sjb printf (" Pointer Size: %u\n", (u_int) cu->cu_pointer_size); 792179187Sjb 793179187Sjb if (dwarf_next_cu_header(dbg, &cu_header_length, 794179187Sjb &cu_version, &cu_abbrev_offset, &cu_pointer_size, 795179187Sjb &cu_next_offset, &error) != DWARF_E_NONE) { 796179187Sjb printf("Error %s\n", dwarf_errmsg(&error)); 797179187Sjb return; 798179187Sjb } 799179187Sjb 800179187Sjb if (dwarf_siblingof(dbg, NULL, &die, &error) != DWARF_E_NONE) { 801179187Sjb printf("Error %s\n", dwarf_errmsg(&error)); 802179187Sjb return; 803179187Sjb } 804179187Sjb 805179187Sjb dwarf_dump_tree_dies(dbg, die, &error); 806179187Sjb 807179187Sjb } 808179187Sjb} 809179187Sjb 810179187Sjbvoid 811179187Sjbdwarf_dump_info(Dwarf_Debug dbg) 812179187Sjb{ 813179187Sjb Dwarf_CU cu; 814179187Sjb Dwarf_Die die; 815179187Sjb 816179187Sjb printf("Contents of the .debug_info section:\n"); 817179187Sjb 818179187Sjb STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { 819179187Sjb printf ("\nCompilation Unit @ offset %llx:\n", 820179187Sjb (unsigned long long) cu->cu_offset); 821179187Sjb printf (" Length: %lu\n", (u_long) cu->cu_length); 822179187Sjb printf (" Version: %hu\n", cu->cu_version); 823179187Sjb printf (" Abbrev Offset: %lu\n", (u_long) cu->cu_abbrev_offset); 824179187Sjb printf (" Pointer Size: %u\n", (u_int) cu->cu_pointer_size); 825179187Sjb 826179187Sjb STAILQ_FOREACH(die, &cu->cu_die, die_next) 827179187Sjb dwarf_dump_die(die); 828179187Sjb } 829179187Sjb} 830179187Sjb 831179187Sjb 832179187Sjbvoid 833179187Sjbdwarf_dump_shstrtab(Dwarf_Debug dbg) 834179187Sjb{ 835179187Sjb char *name; 836179187Sjb int indx = 0; 837179187Sjb 838179187Sjb printf("---------------------\nSection header string table contents:\n"); 839179187Sjb while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_stnum, indx)) != NULL) { 840179187Sjb printf("%5d '%s'\n",indx,name); 841179187Sjb indx += strlen(name) + 1; 842179187Sjb } 843179187Sjb} 844179187Sjb 845179187Sjbvoid 846179187Sjbdwarf_dump_strtab(Dwarf_Debug dbg) 847179187Sjb{ 848179187Sjb char *name; 849179187Sjb int indx = 0; 850179187Sjb 851179187Sjb printf("---------------------\nString table contents:\n"); 852179187Sjb while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_strtab].s_shnum, indx)) != NULL) { 853179187Sjb printf("%5d '%s'\n",indx,name); 854179187Sjb indx += strlen(name) + 1; 855179187Sjb } 856179187Sjb} 857179187Sjb 858179187Sjbvoid 859179187Sjbdwarf_dump_dbgstr(Dwarf_Debug dbg) 860179187Sjb{ 861179187Sjb char *name; 862179187Sjb int indx = 0; 863179187Sjb 864179187Sjb printf("---------------------\nDebug string table contents:\n"); 865179187Sjb while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_debug_str].s_shnum, indx)) != NULL) { 866179187Sjb printf("%5d '%s'\n",indx,name); 867179187Sjb indx += strlen(name) + 1; 868179187Sjb } 869179187Sjb} 870179187Sjb 871179187Sjbvoid 872179187Sjbdwarf_dump_symtab(Dwarf_Debug dbg) 873179187Sjb{ 874179187Sjb GElf_Sym sym; 875179187Sjb char *name; 876179187Sjb int indx = 0; 877179187Sjb 878179187Sjb printf("---------------------\nSymbol table contents:\n"); 879179187Sjb while (gelf_getsym(dbg->dbg_s[DWARF_symtab].s_data, indx++, &sym) != NULL) { 880179187Sjb if ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_strtab].s_shnum, sym.st_name)) == NULL) 881179187Sjb printf("sym.st_name %u indx %d sym.st_size %lu\n",sym.st_name,indx,(u_long) sym.st_size); 882179187Sjb else 883179187Sjb printf("'%s' sym.st_name %u indx %d sym.st_size %lu\n",name,sym.st_name,indx,(u_long) sym.st_size); 884179187Sjb } 885179187Sjb} 886179187Sjb 887179187Sjbvoid 888179187Sjbdwarf_dump(Dwarf_Debug dbg) 889179187Sjb{ 890179187Sjb dwarf_dump_strtab(dbg); 891179187Sjb dwarf_dump_shstrtab(dbg); 892179187Sjb dwarf_dump_dbgstr(dbg); 893179187Sjb dwarf_dump_symtab(dbg); 894179187Sjb dwarf_dump_info(dbg); 895179187Sjb} 896