aboutsummaryrefslogtreecommitdiffstats
path: root/elff/dwarf_utils.cc
diff options
context:
space:
mode:
Diffstat (limited to 'elff/dwarf_utils.cc')
-rw-r--r--elff/dwarf_utils.cc313
1 files changed, 313 insertions, 0 deletions
diff --git a/elff/dwarf_utils.cc b/elff/dwarf_utils.cc
new file mode 100644
index 0000000..56c05a3
--- /dev/null
+++ b/elff/dwarf_utils.cc
@@ -0,0 +1,313 @@
+/* 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 "stdio.h"
+#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) = %I64u (x%I64X)\n", attr_value->u64,
+ attr_value->u64);
+ break;
+
+ case DWARF_VALUE_S64:
+ printf("SXWORD) = %I64d (x%I64X)\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%08I64X\n", attr_value->ptr64);
+ break;
+
+ case DWARF_VALUE_BLOCK:
+ printf("BLOCK) = [%I64u]:", 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;
+ }
+}