/* Copyright (C) 2007-2010 The Android Open Source Project ** ** This software is licensed under the terms of the GNU General Public ** License version 2, as published by the Free Software Foundation, and ** may be copied, distributed, and modified under those terms. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. */ /* * Contains implementation of misc. DWARF utility routines. */ #include #define __STDC_FORMAT_MACROS 1 #include #include "dwarf_utils.h" /* "Stringifies" the parameter. */ #define DWARF_NAMEFY(val) case val: return "" #val "" /* "Stringifies" two parameters. */ #define DWARF_NAMEFY2(val1, val2) case val1: return "" #val1 " | " #val2 "" const char* dwarf_at_name(Dwarf_At at) { switch (at) { DWARF_NAMEFY(DW_AT_sibling); DWARF_NAMEFY(DW_AT_location); DWARF_NAMEFY(DW_AT_name); DWARF_NAMEFY(DW_AT_ordering); DWARF_NAMEFY(DW_AT_subscr_data); DWARF_NAMEFY(DW_AT_byte_size); DWARF_NAMEFY(DW_AT_bit_offset); DWARF_NAMEFY(DW_AT_bit_size); DWARF_NAMEFY(DW_AT_element_list); DWARF_NAMEFY(DW_AT_stmt_list); DWARF_NAMEFY(DW_AT_low_pc); DWARF_NAMEFY(DW_AT_high_pc); DWARF_NAMEFY(DW_AT_language); DWARF_NAMEFY(DW_AT_member); DWARF_NAMEFY(DW_AT_discr); DWARF_NAMEFY(DW_AT_discr_value); DWARF_NAMEFY(DW_AT_visibility); DWARF_NAMEFY(DW_AT_import); DWARF_NAMEFY(DW_AT_string_length); DWARF_NAMEFY(DW_AT_common_reference); DWARF_NAMEFY(DW_AT_comp_dir); DWARF_NAMEFY(DW_AT_const_value); DWARF_NAMEFY(DW_AT_containing_type); DWARF_NAMEFY(DW_AT_default_value); DWARF_NAMEFY(DW_AT_inline); DWARF_NAMEFY(DW_AT_is_optional); DWARF_NAMEFY(DW_AT_lower_bound); DWARF_NAMEFY(DW_AT_producer); DWARF_NAMEFY(DW_AT_prototyped); DWARF_NAMEFY(DW_AT_return_addr); DWARF_NAMEFY(DW_AT_start_scope); DWARF_NAMEFY2(DW_AT_bit_stride, DW_AT_stride_size); DWARF_NAMEFY(DW_AT_upper_bound); DWARF_NAMEFY(DW_AT_abstract_origin); DWARF_NAMEFY(DW_AT_accessibility); DWARF_NAMEFY(DW_AT_address_class); DWARF_NAMEFY(DW_AT_artificial); DWARF_NAMEFY(DW_AT_base_types); DWARF_NAMEFY(DW_AT_calling_convention); DWARF_NAMEFY(DW_AT_count); DWARF_NAMEFY(DW_AT_data_member_location); DWARF_NAMEFY(DW_AT_decl_column); DWARF_NAMEFY(DW_AT_decl_file); DWARF_NAMEFY(DW_AT_decl_line); DWARF_NAMEFY(DW_AT_declaration); DWARF_NAMEFY(DW_AT_discr_list); DWARF_NAMEFY(DW_AT_encoding); DWARF_NAMEFY(DW_AT_external); DWARF_NAMEFY(DW_AT_frame_base); DWARF_NAMEFY(DW_AT_friend); DWARF_NAMEFY(DW_AT_identifier_case); DWARF_NAMEFY(DW_AT_macro_info); DWARF_NAMEFY(DW_AT_namelist_item); DWARF_NAMEFY(DW_AT_priority); DWARF_NAMEFY(DW_AT_segment); DWARF_NAMEFY(DW_AT_specification); DWARF_NAMEFY(DW_AT_static_link); DWARF_NAMEFY(DW_AT_type); DWARF_NAMEFY(DW_AT_use_location); DWARF_NAMEFY(DW_AT_variable_parameter); DWARF_NAMEFY(DW_AT_virtuality); DWARF_NAMEFY(DW_AT_vtable_elem_location); DWARF_NAMEFY(DW_AT_allocated); DWARF_NAMEFY(DW_AT_associated); DWARF_NAMEFY(DW_AT_data_location); DWARF_NAMEFY2(DW_AT_byte_stride, DW_AT_stride); DWARF_NAMEFY(DW_AT_entry_pc); DWARF_NAMEFY(DW_AT_use_UTF8); DWARF_NAMEFY(DW_AT_extension); DWARF_NAMEFY(DW_AT_ranges); DWARF_NAMEFY(DW_AT_trampoline); DWARF_NAMEFY(DW_AT_call_column); DWARF_NAMEFY(DW_AT_call_file); DWARF_NAMEFY(DW_AT_call_line); DWARF_NAMEFY(DW_AT_description); DWARF_NAMEFY(DW_AT_binary_scale); DWARF_NAMEFY(DW_AT_decimal_scale); DWARF_NAMEFY(DW_AT_small); DWARF_NAMEFY(DW_AT_decimal_sign); DWARF_NAMEFY(DW_AT_digit_count); DWARF_NAMEFY(DW_AT_picture_string); DWARF_NAMEFY(DW_AT_mutable); DWARF_NAMEFY(DW_AT_threads_scaled); DWARF_NAMEFY(DW_AT_explicit); DWARF_NAMEFY(DW_AT_object_pointer); DWARF_NAMEFY(DW_AT_endianity); DWARF_NAMEFY(DW_AT_elemental); DWARF_NAMEFY(DW_AT_pure); DWARF_NAMEFY(DW_AT_recursive); DWARF_NAMEFY(DW_AT_signature); DWARF_NAMEFY(DW_AT_main_subprogram); DWARF_NAMEFY(DW_AT_data_bit_offset); DWARF_NAMEFY(DW_AT_const_expr); DWARF_NAMEFY(DW_AT_enum_class); DWARF_NAMEFY(DW_AT_linkage_name); default: return "DW_AT_Unknown"; } } const char* dwarf_form_name(Dwarf_Form form) { switch (form) { DWARF_NAMEFY(DW_FORM_addr); DWARF_NAMEFY(DW_FORM_block2); DWARF_NAMEFY(DW_FORM_block4); DWARF_NAMEFY(DW_FORM_data2); DWARF_NAMEFY(DW_FORM_data4); DWARF_NAMEFY(DW_FORM_data8); DWARF_NAMEFY(DW_FORM_string); DWARF_NAMEFY(DW_FORM_block); DWARF_NAMEFY(DW_FORM_block1); DWARF_NAMEFY(DW_FORM_data1); DWARF_NAMEFY(DW_FORM_flag); DWARF_NAMEFY(DW_FORM_sdata); DWARF_NAMEFY(DW_FORM_strp); DWARF_NAMEFY(DW_FORM_udata); DWARF_NAMEFY(DW_FORM_ref_addr); DWARF_NAMEFY(DW_FORM_ref1); DWARF_NAMEFY(DW_FORM_ref2); DWARF_NAMEFY(DW_FORM_ref4); DWARF_NAMEFY(DW_FORM_ref8); DWARF_NAMEFY(DW_FORM_ref_udata); DWARF_NAMEFY(DW_FORM_indirect); DWARF_NAMEFY(DW_FORM_sec_offset); DWARF_NAMEFY(DW_FORM_exprloc); DWARF_NAMEFY(DW_FORM_flag_present); DWARF_NAMEFY(DW_FORM_ref_sig8); default: return "DW_FORM_Unknown"; } } const char* dwarf_tag_name(Dwarf_Tag tag) { switch (tag) { DWARF_NAMEFY(DW_TAG_array_type); DWARF_NAMEFY(DW_TAG_class_type); DWARF_NAMEFY(DW_TAG_entry_point); DWARF_NAMEFY(DW_TAG_enumeration_type); DWARF_NAMEFY(DW_TAG_formal_parameter); DWARF_NAMEFY(DW_TAG_imported_declaration); DWARF_NAMEFY(DW_TAG_label); DWARF_NAMEFY(DW_TAG_lexical_block); DWARF_NAMEFY(DW_TAG_member); DWARF_NAMEFY(DW_TAG_pointer_type); DWARF_NAMEFY(DW_TAG_reference_type); DWARF_NAMEFY(DW_TAG_compile_unit); DWARF_NAMEFY(DW_TAG_string_type); DWARF_NAMEFY(DW_TAG_structure_type); DWARF_NAMEFY(DW_TAG_subroutine_type); DWARF_NAMEFY(DW_TAG_typedef); DWARF_NAMEFY(DW_TAG_union_type); DWARF_NAMEFY(DW_TAG_unspecified_parameters); DWARF_NAMEFY(DW_TAG_variant); DWARF_NAMEFY(DW_TAG_common_block); DWARF_NAMEFY(DW_TAG_common_inclusion); DWARF_NAMEFY(DW_TAG_inheritance); DWARF_NAMEFY(DW_TAG_inlined_subroutine); DWARF_NAMEFY(DW_TAG_module); DWARF_NAMEFY(DW_TAG_ptr_to_member_type); DWARF_NAMEFY(DW_TAG_set_type); DWARF_NAMEFY(DW_TAG_subrange_type); DWARF_NAMEFY(DW_TAG_with_stmt); DWARF_NAMEFY(DW_TAG_access_declaration); DWARF_NAMEFY(DW_TAG_base_type); DWARF_NAMEFY(DW_TAG_catch_block); DWARF_NAMEFY(DW_TAG_const_type); DWARF_NAMEFY(DW_TAG_constant); DWARF_NAMEFY(DW_TAG_enumerator); DWARF_NAMEFY(DW_TAG_file_type); DWARF_NAMEFY(DW_TAG_friend); DWARF_NAMEFY(DW_TAG_namelist); DWARF_NAMEFY2(DW_TAG_namelist_item, DW_TAG_namelist_items); DWARF_NAMEFY(DW_TAG_packed_type); DWARF_NAMEFY(DW_TAG_subprogram); DWARF_NAMEFY2(DW_TAG_template_type_parameter, DW_TAG_template_type_param); DWARF_NAMEFY2(DW_TAG_template_value_parameter, DW_TAG_template_value_param); DWARF_NAMEFY(DW_TAG_thrown_type); DWARF_NAMEFY(DW_TAG_try_block); DWARF_NAMEFY(DW_TAG_variant_part); DWARF_NAMEFY(DW_TAG_variable); DWARF_NAMEFY(DW_TAG_volatile_type); DWARF_NAMEFY(DW_TAG_dwarf_procedure); DWARF_NAMEFY(DW_TAG_restrict_type); DWARF_NAMEFY(DW_TAG_interface_type); DWARF_NAMEFY(DW_TAG_namespace); DWARF_NAMEFY(DW_TAG_imported_module); DWARF_NAMEFY(DW_TAG_unspecified_type); DWARF_NAMEFY(DW_TAG_partial_unit); DWARF_NAMEFY(DW_TAG_imported_unit); DWARF_NAMEFY(DW_TAG_mutable_type); DWARF_NAMEFY(DW_TAG_condition); DWARF_NAMEFY(DW_TAG_shared_type); DWARF_NAMEFY(DW_TAG_type_unit); DWARF_NAMEFY(DW_TAG_rvalue_reference_type); DWARF_NAMEFY(DW_TAG_template_alias); default: return "DW_TAG_Unknown"; } } void dump_attrib(Dwarf_At at, Dwarf_Form form, const Dwarf_Value* val) { if (form != 0) { printf(" +++ Attribute: %s [%s]\n", dwarf_at_name(at), dwarf_form_name(form)); } else { printf(" +++ Attribute: %s\n", dwarf_at_name(at)); } dump_value(val); } void dump_value(const Dwarf_Value* attr_value) { printf(" Data[%03u]: (", attr_value->encoded_size); switch (attr_value->type) { case DWARF_VALUE_U8: printf("BYTE) = %u (x%02X)\n", (Elf_Word)attr_value->u8, (Elf_Word)attr_value->u8); break; case DWARF_VALUE_S8: printf("SBYTE) = %d (x%02X)\n", (Elf_Sword)attr_value->s8, (Elf_Sword)attr_value->s8); break; case DWARF_VALUE_U16: printf("WORD) = %u (x%04X)\n", (Elf_Word)attr_value->u16, (Elf_Word)attr_value->u16); break; case DWARF_VALUE_S16: printf("SWORD) = %d (x%04X)\n", (Elf_Sword)attr_value->s16, (Elf_Sword)attr_value->s16); break; case DWARF_VALUE_U32: printf("DWORD) = %u (x%08X)\n", attr_value->u32, attr_value->u32); break; case DWARF_VALUE_S32: printf("SDWORD) = %d (x%08X)\n", attr_value->s32, attr_value->s32); break; case DWARF_VALUE_U64: printf("XWORD) = %" PRIu64 " (x%" PRIX64 ")\n", attr_value->u64, attr_value->u64); break; case DWARF_VALUE_S64: printf("SXWORD) = %" PRId64 " (x%" PRIX64 ")\n", attr_value->s64, attr_value->s64); break; case DWARF_VALUE_STR: printf("STRING) = %s\n", attr_value->str); break; case DWARF_VALUE_PTR32: printf("PTR32) = x%08X\n", attr_value->ptr32); break; case DWARF_VALUE_PTR64: printf("PTR64) = x%08" PRIX64 "\n", attr_value->ptr64); break; case DWARF_VALUE_BLOCK: printf("BLOCK) = [%u]:", attr_value->block.block_size); for (Elf_Xword i = 0; i < attr_value->block.block_size; i++) { Elf_Byte prnt = *((const Elf_Byte*)attr_value->block.block_ptr + i); printf(" x%02X", prnt); } printf("\n"); break; case DWARF_VALUE_UNKNOWN: default: printf("UNKNOWN)"); break; } }