commit 5ec36f31e5938778300d902cd5fd7f0c2eefca12 Author: Phireh Date: Sat Sep 23 20:17:03 2023 +0200 feat: initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..64d31cf --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Executable +pesticide diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..121e8db --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +pesticide: main.cpp enums.h enum_names.h + g++ -o pesticide main.cpp -Werror -Wextra -pedantic -O0 -g -gdwarf64 diff --git a/enum_names.h b/enum_names.h new file mode 100644 index 0000000..8564518 --- /dev/null +++ b/enum_names.h @@ -0,0 +1,1064 @@ +#include "enums.h" + +#define DW_DLV_OK 0 +#define DW_DLV_NO_ENTRY -1 + +const char * +dwarf_get_TAG_name(unsigned int val) +{ + switch (val) { + case DW_TAG_array_type: + return "DW_TAG_array_type"; + case DW_TAG_class_type: + return "DW_TAG_class_type"; + case DW_TAG_entry_point: + return "DW_TAG_entry_point"; + case DW_TAG_enumeration_type: + return "DW_TAG_enumeration_type"; + case DW_TAG_formal_parameter: + return "DW_TAG_formal_parameter"; + case DW_TAG_imported_declaration: + return "DW_TAG_imported_declaration"; + case DW_TAG_label: + return "DW_TAG_label"; + case DW_TAG_lexical_block: + return "DW_TAG_lexical_block"; + case DW_TAG_member: + return "DW_TAG_member"; + case DW_TAG_pointer_type: + return "DW_TAG_pointer_type"; + case DW_TAG_reference_type: + return "DW_TAG_reference_type"; + case DW_TAG_compile_unit: + return "DW_TAG_compile_unit"; + case DW_TAG_string_type: + return "DW_TAG_string_type"; + case DW_TAG_structure_type: + return "DW_TAG_structure_type"; + case DW_TAG_subroutine_type: + return "DW_TAG_subroutine_type"; + case DW_TAG_typedef: + return "DW_TAG_typedef"; + case DW_TAG_union_type: + return "DW_TAG_union_type"; + case DW_TAG_unspecified_parameters: + return "DW_TAG_unspecified_parameters"; + case DW_TAG_variant: + return "DW_TAG_variant"; + case DW_TAG_common_block: + return "DW_TAG_common_block"; + case DW_TAG_common_inclusion: + return "DW_TAG_common_inclusion"; + case DW_TAG_inheritance: + return "DW_TAG_inheritance"; + case DW_TAG_inlined_subroutine: + return "DW_TAG_inlined_subroutine"; + case DW_TAG_module: + return "DW_TAG_module"; + case DW_TAG_ptr_to_member_type: + return "DW_TAG_ptr_to_member_type"; + case DW_TAG_set_type: + return "DW_TAG_set_type"; + case DW_TAG_subrange_type: + return "DW_TAG_subrange_type"; + case DW_TAG_with_stmt: + return "DW_TAG_with_stmt"; + case DW_TAG_access_declaration: + return "DW_TAG_access_declaration"; + case DW_TAG_base_type: + return "DW_TAG_base_type"; + case DW_TAG_catch_block: + return "DW_TAG_catch_block"; + case DW_TAG_const_type: + return "DW_TAG_const_type"; + case DW_TAG_constant: + return "DW_TAG_constant"; + case DW_TAG_enumerator: + return "DW_TAG_enumerator"; + case DW_TAG_file_type: + return "DW_TAG_file_type"; + case DW_TAG_friend: + return "DW_TAG_friend"; + case DW_TAG_namelist: + return "DW_TAG_namelist"; + case DW_TAG_namelist_item: + return "DW_TAG_namelist_item"; + /* Skipping alternate spelling of value + 0x2c. DW_TAG_namelist_items */ + case DW_TAG_packed_type: + return "DW_TAG_packed_type"; + case DW_TAG_subprogram: + return "DW_TAG_subprogram"; + case DW_TAG_template_type_parameter: + return "DW_TAG_template_type_parameter"; + /* Skipping alternate spelling of value + 0x2f. DW_TAG_template_type_param */ + case DW_TAG_template_value_parameter: + return "DW_TAG_template_value_parameter"; + /* Skipping alternate spelling of value + 0x30. DW_TAG_template_value_param */ + case DW_TAG_thrown_type: + return "DW_TAG_thrown_type"; + case DW_TAG_try_block: + return "DW_TAG_try_block"; + case DW_TAG_variant_part: + return "DW_TAG_variant_part"; + case DW_TAG_variable: + return "DW_TAG_variable"; + case DW_TAG_volatile_type: + return "DW_TAG_volatile_type"; + case DW_TAG_dwarf_procedure: + return "DW_TAG_dwarf_procedure"; + case DW_TAG_restrict_type: + return "DW_TAG_restrict_type"; + case DW_TAG_interface_type: + return "DW_TAG_interface_type"; + case DW_TAG_namespace: + return "DW_TAG_namespace"; + case DW_TAG_imported_module: + return "DW_TAG_imported_module"; + case DW_TAG_unspecified_type: + return "DW_TAG_unspecified_type"; + case DW_TAG_partial_unit: + return "DW_TAG_partial_unit"; + case DW_TAG_imported_unit: + return "DW_TAG_imported_unit"; + /* case DW_TAG_mutable_type: */ + /* return "DW_TAG_mutable_type"; */ + case DW_TAG_condition: + return "DW_TAG_condition"; + case DW_TAG_shared_type: + return "DW_TAG_shared_type"; + case DW_TAG_type_unit: + return "DW_TAG_type_unit"; + case DW_TAG_rvalue_reference_type: + return "DW_TAG_rvalue_reference_type"; + case DW_TAG_template_alias: + return "DW_TAG_template_alias"; + case DW_TAG_coarray_type: + return "DW_TAG_coarray_type"; + case DW_TAG_generic_subrange: + return "DW_TAG_generic_subrange"; + case DW_TAG_dynamic_type: + return "DW_TAG_dynamic_type"; + case DW_TAG_atomic_type: + return "DW_TAG_atomic_type"; + case DW_TAG_call_site: + return "DW_TAG_call_site"; + case DW_TAG_call_site_parameter: + return "DW_TAG_call_site_parameter"; + case DW_TAG_skeleton_unit: + return "DW_TAG_skeleton_unit"; + case DW_TAG_immutable_type: + return "DW_TAG_immutable_type"; + case DW_TAG_lo_user: + return "DW_TAG_lo_user"; + /* case DW_TAG_MIPS_loop: */ + /* return "DW_TAG_MIPS_loop"; */ + /* case DW_TAG_HP_array_descriptor: */ + /* return "DW_TAG_HP_array_descriptor"; */ + /* case DW_TAG_format_label: */ + /* return "DW_TAG_format_label"; */ + /* case DW_TAG_function_template: */ + /* return "DW_TAG_function_template"; */ + /* case DW_TAG_class_template: */ + /* return "DW_TAG_class_template"; */ + /* case DW_TAG_GNU_BINCL: */ + /* return "DW_TAG_GNU_BINCL"; */ + /* case DW_TAG_GNU_EINCL: */ + /* return "DW_TAG_GNU_EINCL"; */ + /* case DW_TAG_GNU_template_template_parameter: */ + /* return "DW_TAG_GNU_template_template_parameter"; */ + /* Skipping alternate spelling of value + 0x4106. DW_TAG_GNU_template_template_param */ + /* case DW_TAG_GNU_template_parameter_pack: */ + /* return "DW_TAG_GNU_template_parameter_pack"; */ + /* case DW_TAG_GNU_formal_parameter_pack: */ + /* return "DW_TAG_GNU_formal_parameter_pack"; */ + /* case DW_TAG_GNU_call_site: */ + /* return "DW_TAG_GNU_call_site"; */ + /* case DW_TAG_GNU_call_site_parameter: */ + /* return "DW_TAG_GNU_call_site_parameter"; */ + /* case DW_TAG_SUN_function_template: */ + /* return "DW_TAG_SUN_function_template"; */ + /* case DW_TAG_SUN_class_template: */ + /* return "DW_TAG_SUN_class_template"; */ + /* case DW_TAG_SUN_struct_template: */ + /* return "DW_TAG_SUN_struct_template"; */ + /* case DW_TAG_SUN_union_template: */ + /* return "DW_TAG_SUN_union_template"; */ + /* case DW_TAG_SUN_indirect_inheritance: */ + /* return "DW_TAG_SUN_indirect_inheritance"; */ + /* case DW_TAG_SUN_codeflags: */ + /* return "DW_TAG_SUN_codeflags"; */ + /* case DW_TAG_SUN_memop_info: */ + /* return "DW_TAG_SUN_memop_info"; */ + /* case DW_TAG_SUN_omp_child_func: */ + /* return "DW_TAG_SUN_omp_child_func"; */ + /* case DW_TAG_SUN_rtti_descriptor: */ + /* return "DW_TAG_SUN_rtti_descriptor"; */ + /* case DW_TAG_SUN_dtor_info: */ + /* return "DW_TAG_SUN_dtor_info"; */ + /* case DW_TAG_SUN_dtor: */ + /* return "DW_TAG_SUN_dtor"; */ + /* case DW_TAG_SUN_f90_interface: */ + /* return "DW_TAG_SUN_f90_interface"; */ + /* case DW_TAG_SUN_fortran_vax_structure: */ + /* return "DW_TAG_SUN_fortran_vax_structure"; */ + /* case DW_TAG_SUN_hi: */ + /* return "DW_TAG_SUN_hi"; */ + /* case DW_TAG_ALTIUM_circ_type: */ + /* return "DW_TAG_ALTIUM_circ_type"; */ + /* case DW_TAG_ALTIUM_mwa_circ_type: */ + /* return "DW_TAG_ALTIUM_mwa_circ_type"; */ + /* case DW_TAG_ALTIUM_rev_carry_type: */ + /* return "DW_TAG_ALTIUM_rev_carry_type"; */ + /* case DW_TAG_ALTIUM_rom: */ + /* return "DW_TAG_ALTIUM_rom"; */ + /* case DW_TAG_LLVM_annotation: */ + /* return "DW_TAG_LLVM_annotation"; */ + /* case DW_TAG_ghs_namespace: */ + /* return "DW_TAG_ghs_namespace"; */ + /* case DW_TAG_ghs_using_namespace: */ + /* return "DW_TAG_ghs_using_namespace"; */ + /* case DW_TAG_ghs_using_declaration: */ + /* return "DW_TAG_ghs_using_declaration"; */ + /* case DW_TAG_ghs_template_templ_param: */ + /* return "DW_TAG_ghs_template_templ_param"; */ + /* case DW_TAG_upc_shared_type: */ + /* return "DW_TAG_upc_shared_type"; */ + /* case DW_TAG_upc_strict_type: */ + /* return "DW_TAG_upc_strict_type"; */ + /* case DW_TAG_upc_relaxed_type: */ + /* return "DW_TAG_upc_relaxed_type"; */ + /* case DW_TAG_PGI_kanji_type: */ + /* return "DW_TAG_PGI_kanji_type"; */ + /* case DW_TAG_PGI_interface_block: */ + /* return "DW_TAG_PGI_interface_block"; */ + /* case DW_TAG_BORLAND_property: */ + /* return "DW_TAG_BORLAND_property"; */ + /* case DW_TAG_BORLAND_Delphi_string: */ + /* return "DW_TAG_BORLAND_Delphi_string"; */ + /* case DW_TAG_BORLAND_Delphi_dynamic_array: */ + /* return "DW_TAG_BORLAND_Delphi_dynamic_array"; */ + /* case DW_TAG_BORLAND_Delphi_set: */ + /* return "DW_TAG_BORLAND_Delphi_set"; */ + /* case DW_TAG_BORLAND_Delphi_variant: */ + /* return "DW_TAG_BORLAND_Delphi_variant"; */ + case DW_TAG_hi_user: + return "DW_TAG_hi_user"; + default: break; + } + return ""; +} + +const char * +dwarf_get_AT_name (unsigned int val) +{ + switch (val) { + case DW_AT_sibling: + return "DW_AT_sibling"; + case DW_AT_location: + return "DW_AT_location"; + case DW_AT_name: + return "DW_AT_name"; + case DW_AT_ordering: + return "DW_AT_ordering"; + // case DW_AT_subscr_data: CAN'T FIND IN PDF + // return "DW_AT_subscr_data"; + case DW_AT_byte_size: + return "DW_AT_byte_size"; + // case DW_AT_bit_offset: DEPRECATED + // return "DW_AT_bit_offset"; + case DW_AT_bit_size: + return "DW_AT_bit_size"; + //case DW_AT_element_list: CAN'T FIND IN PDF + //return "DW_AT_element_list"; + case DW_AT_stmt_list: + return "DW_AT_stmt_list"; + case DW_AT_low_pc: + return "DW_AT_low_pc"; + case DW_AT_high_pc: + return "DW_AT_high_pc"; + case DW_AT_language: + return "DW_AT_language"; + // case DW_AT_member: CAN'T FIND IN PDF + // return "DW_AT_member"; + case DW_AT_discr: + return "DW_AT_discr"; + case DW_AT_discr_value: + return "DW_AT_discr_value"; + case DW_AT_visibility: + return "DW_AT_visibility"; + case DW_AT_import: + return "DW_AT_import"; + case DW_AT_string_length: + return "DW_AT_string_length"; + case DW_AT_common_reference: + return "DW_AT_common_reference"; + case DW_AT_comp_dir: + return "DW_AT_comp_dir"; + case DW_AT_const_value: + return "DW_AT_const_value"; + case DW_AT_containing_type: + return "DW_AT_containing_type"; + case DW_AT_default_value: + return "DW_AT_default_value"; + case DW_AT_inline: + return "DW_AT_inline"; + case DW_AT_is_optional: + return "DW_AT_is_optional"; + case DW_AT_lower_bound: + return "DW_AT_lower_bound"; + case DW_AT_producer: + return "DW_AT_producer"; + case DW_AT_prototyped: + return "DW_AT_prototyped"; + case DW_AT_return_addr: + return "DW_AT_return_addr"; + case DW_AT_start_scope: + return "DW_AT_start_scope"; + case DW_AT_bit_stride: + return "DW_AT_bit_stride"; + /* Skipping alternate spelling of value + 0x2e. DW_AT_stride_size */ + case DW_AT_upper_bound: + return "DW_AT_upper_bound"; + case DW_AT_abstract_origin: + return "DW_AT_abstract_origin"; + case DW_AT_accessibility: + return "DW_AT_accessibility"; + case DW_AT_address_class: + return "DW_AT_address_class"; + case DW_AT_artificial: + return "DW_AT_artificial"; + case DW_AT_base_types: + return "DW_AT_base_types"; + case DW_AT_calling_convention: + return "DW_AT_calling_convention"; + case DW_AT_count: + return "DW_AT_count"; + case DW_AT_data_member_location: + return "DW_AT_data_member_location"; + case DW_AT_decl_column: + return "DW_AT_decl_column"; + case DW_AT_decl_file: + return "DW_AT_decl_file"; + case DW_AT_decl_line: + return "DW_AT_decl_line"; + case DW_AT_declaration: + return "DW_AT_declaration"; + case DW_AT_discr_list: + return "DW_AT_discr_list"; + case DW_AT_encoding: + return "DW_AT_encoding"; + case DW_AT_external: + return "DW_AT_external"; + case DW_AT_frame_base: + return "DW_AT_frame_base"; + case DW_AT_friend: + return "DW_AT_friend"; + case DW_AT_identifier_case: + return "DW_AT_identifier_case"; + // case DW_AT_macro_info: DEPRECATED + // return "DW_AT_macro_info"; + case DW_AT_namelist_item: + return "DW_AT_namelist_item"; + case DW_AT_priority: + return "DW_AT_priority"; + case DW_AT_segment: + return "DW_AT_segment"; + case DW_AT_specification: + return "DW_AT_specification"; + case DW_AT_static_link: + return "DW_AT_static_link"; + case DW_AT_type: + return "DW_AT_type"; + case DW_AT_use_location: + return "DW_AT_use_location"; + case DW_AT_variable_parameter: + return "DW_AT_variable_parameter"; + case DW_AT_virtuality: + return "DW_AT_virtuality"; + case DW_AT_vtable_elem_location: + return "DW_AT_vtable_elem_location"; + case DW_AT_allocated: + return "DW_AT_allocated"; + case DW_AT_associated: + return "DW_AT_associated"; + case DW_AT_data_location: + return "DW_AT_data_location"; + case DW_AT_byte_stride: + return "DW_AT_byte_stride"; + /* Skipping alternate spelling of value + 0x51. DW_AT_stride */ + case DW_AT_entry_pc: + return "DW_AT_entry_pc"; + case DW_AT_use_UTF8: + return "DW_AT_use_UTF8"; + case DW_AT_extension: + return "DW_AT_extension"; + case DW_AT_ranges: + return "DW_AT_ranges"; + case DW_AT_trampoline: + return "DW_AT_trampoline"; + case DW_AT_call_column: + return "DW_AT_call_column"; + case DW_AT_call_file: + return "DW_AT_call_file"; + case DW_AT_call_line: + return "DW_AT_call_line"; + case DW_AT_description: + return "DW_AT_description"; + case DW_AT_binary_scale: + return "DW_AT_binary_scale"; + case DW_AT_decimal_scale: + return "DW_AT_decimal_scale"; + case DW_AT_small: + return "DW_AT_small"; + case DW_AT_decimal_sign: + return "DW_AT_decimal_sign"; + case DW_AT_digit_count: + return "DW_AT_digit_count"; + case DW_AT_picture_string: + return "DW_AT_picture_string"; + case DW_AT_mutable: + return "DW_AT_mutable"; + case DW_AT_threads_scaled: + return "DW_AT_threads_scaled"; + case DW_AT_explicit: + return "DW_AT_explicit"; + case DW_AT_object_pointer: + return "DW_AT_object_pointer"; + case DW_AT_endianity: + return "DW_AT_endianity"; + case DW_AT_elemental: + return "DW_AT_elemental"; + case DW_AT_pure: + return "DW_AT_pure"; + case DW_AT_recursive: + return "DW_AT_recursive"; + case DW_AT_signature: + return "DW_AT_signature"; + case DW_AT_main_subprogram: + return "DW_AT_main_subprogram"; + case DW_AT_data_bit_offset: + return "DW_AT_data_bit_offset"; + case DW_AT_const_expr: + return "DW_AT_const_expr"; + case DW_AT_enum_class: + return "DW_AT_enum_class"; + case DW_AT_linkage_name: + return "DW_AT_linkage_name"; + case DW_AT_string_length_bit_size: + return "DW_AT_string_length_bit_size"; + case DW_AT_string_length_byte_size: + return "DW_AT_string_length_byte_size"; + case DW_AT_rank: + return "DW_AT_rank"; + case DW_AT_str_offsets_base: + return "DW_AT_str_offsets_base"; + case DW_AT_addr_base: + return "DW_AT_addr_base"; + case DW_AT_rnglists_base: + return "DW_AT_rnglists_base"; + // case DW_AT_dwo_id: CAN'T FIND IN PDF + // return "DW_AT_dwo_id"; + case DW_AT_dwo_name: + return "DW_AT_dwo_name"; + case DW_AT_reference: + return "DW_AT_reference"; + case DW_AT_rvalue_reference: + return "DW_AT_rvalue_reference"; + case DW_AT_macros: + return "DW_AT_macros"; + case DW_AT_call_all_calls: + return "DW_AT_call_all_calls"; + case DW_AT_call_all_source_calls: + return "DW_AT_call_all_source_calls"; + case DW_AT_call_all_tail_calls: + return "DW_AT_call_all_tail_calls"; + case DW_AT_call_return_pc: + return "DW_AT_call_return_pc"; + case DW_AT_call_value: + return "DW_AT_call_value"; + case DW_AT_call_origin: + return "DW_AT_call_origin"; + case DW_AT_call_parameter: + return "DW_AT_call_parameter"; + case DW_AT_call_pc: + return "DW_AT_call_pc"; + case DW_AT_call_tail_call: + return "DW_AT_call_tail_call"; + case DW_AT_call_target: + return "DW_AT_call_target"; + case DW_AT_call_target_clobbered: + return "DW_AT_call_target_clobbered"; + case DW_AT_call_data_location: + return "DW_AT_call_data_location"; + case DW_AT_call_data_value: + return "DW_AT_call_data_value"; + case DW_AT_noreturn: + return "DW_AT_noreturn"; + case DW_AT_alignment: + return "DW_AT_alignment"; + case DW_AT_export_symbols: + return "DW_AT_export_symbols"; + case DW_AT_deleted: + return "DW_AT_deleted"; + case DW_AT_defaulted: + return "DW_AT_defaulted"; + case DW_AT_loclists_base: + return "DW_AT_loclists_base"; + // case DW_AT_ghs_namespace_alias: CAN'T FIND IN PDF + // return "DW_AT_ghs_namespace_alias"; + // case DW_AT_ghs_using_namespace: CAN'T FIND IN PDF + // return "DW_AT_ghs_using_namespace"; + // case DW_AT_ghs_using_declaration: CAN'T FIND IN PDF + // return "DW_AT_ghs_using_declaration"; + /* case DW_AT_HP_block_index: */ + /* return "DW_AT_HP_block_index"; */ + /* Skipping alternate spelling of value + 0x2000. DW_AT_lo_user */ + /* case DW_AT_MIPS_fde: */ + /* return "DW_AT_MIPS_fde"; */ + /* Skipping alternate spelling of value + 0x2001. DW_AT_HP_unmodifiable */ + /* Skipping alternate spelling of value + 0x2001. DW_AT_CPQ_discontig_ranges */ + /* case DW_AT_MIPS_loop_begin: */ + /* return "DW_AT_MIPS_loop_begin"; */ + /* Skipping alternate spelling of value + 0x2002. DW_AT_CPQ_semantic_events */ + /* case DW_AT_MIPS_tail_loop_begin: */ + /* return "DW_AT_MIPS_tail_loop_begin"; */ + /* Skipping alternate spelling of value + 0x2003. DW_AT_CPQ_split_lifetimes_var */ + /* case DW_AT_MIPS_epilog_begin: */ + /* return "DW_AT_MIPS_epilog_begin"; */ + /* Skipping alternate spelling of value + 0x2004. DW_AT_CPQ_split_lifetimes_rtn */ + /* case DW_AT_MIPS_loop_unroll_factor: */ + /* return "DW_AT_MIPS_loop_unroll_factor"; */ + /* Skipping alternate spelling of value + 0x2005. DW_AT_HP_prologue */ + /* Skipping alternate spelling of value + 0x2005. DW_AT_CPQ_prologue_length */ + /* case DW_AT_MIPS_software_pipeline_depth: */ + /* return "DW_AT_MIPS_software_pipeline_depth"; */ + /* case DW_AT_MIPS_linkage_name: */ + /* return "DW_AT_MIPS_linkage_name"; */ + /* Skipping alternate spelling of value + 0x2007. DW_AT_ghs_mangled */ + /* case DW_AT_MIPS_stride: */ + /* return "DW_AT_MIPS_stride"; */ + /* Skipping alternate spelling of value + 0x2008. DW_AT_HP_epilogue */ + /* case DW_AT_MIPS_abstract_name: */ + /* return "DW_AT_MIPS_abstract_name"; */ + /* case DW_AT_MIPS_clone_origin: */ + /* return "DW_AT_MIPS_clone_origin"; */ + /* case DW_AT_MIPS_has_inlines: */ + /* return "DW_AT_MIPS_has_inlines"; */ + /* case DW_AT_MIPS_stride_byte: */ + /* return "DW_AT_MIPS_stride_byte"; */ + /* case DW_AT_MIPS_stride_elem: */ + /* return "DW_AT_MIPS_stride_elem"; */ + /* case DW_AT_MIPS_ptr_dopetype: */ + /* return "DW_AT_MIPS_ptr_dopetype"; */ + /* case DW_AT_MIPS_allocatable_dopetype: */ + /* return "DW_AT_MIPS_allocatable_dopetype"; */ + /* case DW_AT_MIPS_assumed_shape_dopetype: */ + /* return "DW_AT_MIPS_assumed_shape_dopetype"; */ + /* Skipping alternate spelling of value + 0x2010. DW_AT_HP_actuals_stmt_list */ + /* case DW_AT_MIPS_assumed_size: */ + /* return "DW_AT_MIPS_assumed_size"; */ + /* Skipping alternate spelling of value + 0x2011. DW_AT_HP_proc_per_section */ + /* case DW_AT_HP_raw_data_ptr: */ + /* return "DW_AT_HP_raw_data_ptr"; */ + /* case DW_AT_HP_pass_by_reference: */ + /* return "DW_AT_HP_pass_by_reference"; */ + /* case DW_AT_HP_opt_level: */ + /* return "DW_AT_HP_opt_level"; */ + /* case DW_AT_HP_prof_version_id: */ + /* return "DW_AT_HP_prof_version_id"; */ + /* case DW_AT_HP_opt_flags: */ + /* return "DW_AT_HP_opt_flags"; */ + /* case DW_AT_HP_cold_region_low_pc: */ + /* return "DW_AT_HP_cold_region_low_pc"; */ + /* case DW_AT_HP_cold_region_high_pc: */ + /* return "DW_AT_HP_cold_region_high_pc"; */ + /* case DW_AT_HP_all_variables_modifiable: */ + /* return "DW_AT_HP_all_variables_modifiable"; */ + /* case DW_AT_HP_linkage_name: */ + /* return "DW_AT_HP_linkage_name"; */ + /* case DW_AT_HP_prof_flags: */ + /* return "DW_AT_HP_prof_flags"; */ + /* case DW_AT_HP_unit_name: */ + /* return "DW_AT_HP_unit_name"; */ + /* case DW_AT_HP_unit_size: */ + /* return "DW_AT_HP_unit_size"; */ + /* case DW_AT_HP_widened_byte_size: */ + /* return "DW_AT_HP_widened_byte_size"; */ + /* case DW_AT_HP_definition_points: */ + /* return "DW_AT_HP_definition_points"; */ + /* case DW_AT_HP_default_location: */ + /* return "DW_AT_HP_default_location"; */ + /* case DW_AT_INTEL_other_endian: */ + /* return "DW_AT_INTEL_other_endian"; */ + /* case DW_AT_HP_is_result_param: */ + /* return "DW_AT_HP_is_result_param"; */ + /* case DW_AT_ghs_rsm: */ + /* return "DW_AT_ghs_rsm"; */ + /* case DW_AT_ghs_frsm: */ + /* return "DW_AT_ghs_frsm"; */ + /* case DW_AT_ghs_frames: */ + /* return "DW_AT_ghs_frames"; */ + /* case DW_AT_ghs_rso: */ + /* return "DW_AT_ghs_rso"; */ + /* case DW_AT_ghs_subcpu: */ + /* return "DW_AT_ghs_subcpu"; */ + /* case DW_AT_ghs_lbrace_line: */ + /* return "DW_AT_ghs_lbrace_line"; */ + /* case DW_AT_sf_names: */ + /* return "DW_AT_sf_names"; */ + /* case DW_AT_src_info: */ + /* return "DW_AT_src_info"; */ + /* case DW_AT_mac_info: */ + /* return "DW_AT_mac_info"; */ + /* case DW_AT_src_coords: */ + /* return "DW_AT_src_coords"; */ + /* case DW_AT_body_begin: */ + /* return "DW_AT_body_begin"; */ + /* case DW_AT_body_end: */ + /* return "DW_AT_body_end"; */ + /* case DW_AT_GNU_vector: */ + /* return "DW_AT_GNU_vector"; */ + /* case DW_AT_GNU_guarded_by: */ + /* return "DW_AT_GNU_guarded_by"; */ + /* case DW_AT_GNU_pt_guarded_by: */ + /* return "DW_AT_GNU_pt_guarded_by"; */ + /* case DW_AT_GNU_guarded: */ + /* return "DW_AT_GNU_guarded"; */ + /* case DW_AT_GNU_pt_guarded: */ + /* return "DW_AT_GNU_pt_guarded"; */ + /* case DW_AT_GNU_locks_excluded: */ + /* return "DW_AT_GNU_locks_excluded"; */ + /* case DW_AT_GNU_exclusive_locks_required: */ + /* return "DW_AT_GNU_exclusive_locks_required"; */ + /* case DW_AT_GNU_shared_locks_required: */ + /* return "DW_AT_GNU_shared_locks_required"; */ + /* case DW_AT_GNU_odr_signature: */ + /* return "DW_AT_GNU_odr_signature"; */ + /* case DW_AT_GNU_template_name: */ + /* return "DW_AT_GNU_template_name"; */ + /* case DW_AT_GNU_call_site_value: */ + /* return "DW_AT_GNU_call_site_value"; */ + /* case DW_AT_GNU_call_site_data_value: */ + /* return "DW_AT_GNU_call_site_data_value"; */ + /* case DW_AT_GNU_call_site_target: */ + /* return "DW_AT_GNU_call_site_target"; */ + /* case DW_AT_GNU_call_site_target_clobbered: */ + /* return "DW_AT_GNU_call_site_target_clobbered"; */ + /* case DW_AT_GNU_tail_call: */ + /* return "DW_AT_GNU_tail_call"; */ + /* case DW_AT_GNU_all_tail_call_sites: */ + /* return "DW_AT_GNU_all_tail_call_sites"; */ + /* case DW_AT_GNU_all_call_sites: */ + /* return "DW_AT_GNU_all_call_sites"; */ + /* case DW_AT_GNU_all_source_call_sites: */ + /* return "DW_AT_GNU_all_source_call_sites"; */ + /* case DW_AT_GNU_macros: */ + /* return "DW_AT_GNU_macros"; */ + /* case DW_AT_GNU_deleted: */ + /* return "DW_AT_GNU_deleted"; */ + /* case DW_AT_GNU_dwo_name: */ + /* return "DW_AT_GNU_dwo_name"; */ + /* case DW_AT_GNU_dwo_id: */ + /* return "DW_AT_GNU_dwo_id"; */ + /* case DW_AT_GNU_ranges_base: */ + /* return "DW_AT_GNU_ranges_base"; */ + /* case DW_AT_GNU_addr_base: */ + /* return "DW_AT_GNU_addr_base"; */ + /* case DW_AT_GNU_pubnames: */ + /* return "DW_AT_GNU_pubnames"; */ + /* case DW_AT_GNU_pubtypes: */ + /* return "DW_AT_GNU_pubtypes"; */ + /* case DW_AT_GNU_discriminator: */ + /* return "DW_AT_GNU_discriminator"; */ + /* case DW_AT_GNU_locviews: */ + /* return "DW_AT_GNU_locviews"; */ + /* case DW_AT_GNU_entry_view: */ + /* return "DW_AT_GNU_entry_view"; */ + /* case DW_AT_SUN_template: */ + /* return "DW_AT_SUN_template"; */ + /* /\* Skipping alternate spelling of value */ + /* 0x2201. DW_AT_VMS_rtnbeg_pd_address *\/ */ + /* case DW_AT_SUN_alignment: */ + /* return "DW_AT_SUN_alignment"; */ + /* case DW_AT_SUN_vtable: */ + /* return "DW_AT_SUN_vtable"; */ + /* case DW_AT_SUN_count_guarantee: */ + /* return "DW_AT_SUN_count_guarantee"; */ + /* case DW_AT_SUN_command_line: */ + /* return "DW_AT_SUN_command_line"; */ + /* case DW_AT_SUN_vbase: */ + /* return "DW_AT_SUN_vbase"; */ + /* case DW_AT_SUN_compile_options: */ + /* return "DW_AT_SUN_compile_options"; */ + /* case DW_AT_SUN_language: */ + /* return "DW_AT_SUN_language"; */ + /* case DW_AT_SUN_browser_file: */ + /* return "DW_AT_SUN_browser_file"; */ + /* case DW_AT_SUN_vtable_abi: */ + /* return "DW_AT_SUN_vtable_abi"; */ + /* case DW_AT_SUN_func_offsets: */ + /* return "DW_AT_SUN_func_offsets"; */ + /* case DW_AT_SUN_cf_kind: */ + /* return "DW_AT_SUN_cf_kind"; */ + /* case DW_AT_SUN_vtable_index: */ + /* return "DW_AT_SUN_vtable_index"; */ + /* case DW_AT_SUN_omp_tpriv_addr: */ + /* return "DW_AT_SUN_omp_tpriv_addr"; */ + /* case DW_AT_SUN_omp_child_func: */ + /* return "DW_AT_SUN_omp_child_func"; */ + /* case DW_AT_SUN_func_offset: */ + /* return "DW_AT_SUN_func_offset"; */ + /* case DW_AT_SUN_memop_type_ref: */ + /* return "DW_AT_SUN_memop_type_ref"; */ + /* case DW_AT_SUN_profile_id: */ + /* return "DW_AT_SUN_profile_id"; */ + /* case DW_AT_SUN_memop_signature: */ + /* return "DW_AT_SUN_memop_signature"; */ + /* case DW_AT_SUN_obj_dir: */ + /* return "DW_AT_SUN_obj_dir"; */ + /* case DW_AT_SUN_obj_file: */ + /* return "DW_AT_SUN_obj_file"; */ + /* case DW_AT_SUN_original_name: */ + /* return "DW_AT_SUN_original_name"; */ + /* case DW_AT_SUN_hwcprof_signature: */ + /* return "DW_AT_SUN_hwcprof_signature"; */ + /* case DW_AT_SUN_amd64_parmdump: */ + /* return "DW_AT_SUN_amd64_parmdump"; */ + /* case DW_AT_SUN_part_link_name: */ + /* return "DW_AT_SUN_part_link_name"; */ + /* case DW_AT_SUN_link_name: */ + /* return "DW_AT_SUN_link_name"; */ + /* case DW_AT_SUN_pass_with_const: */ + /* return "DW_AT_SUN_pass_with_const"; */ + /* case DW_AT_SUN_return_with_const: */ + /* return "DW_AT_SUN_return_with_const"; */ + /* case DW_AT_SUN_import_by_name: */ + /* return "DW_AT_SUN_import_by_name"; */ + /* case DW_AT_SUN_f90_pointer: */ + /* return "DW_AT_SUN_f90_pointer"; */ + /* case DW_AT_SUN_pass_by_ref: */ + /* return "DW_AT_SUN_pass_by_ref"; */ + /* case DW_AT_SUN_f90_allocatable: */ + /* return "DW_AT_SUN_f90_allocatable"; */ + /* case DW_AT_SUN_f90_assumed_shape_array: */ + /* return "DW_AT_SUN_f90_assumed_shape_array"; */ + /* case DW_AT_SUN_c_vla: */ + /* return "DW_AT_SUN_c_vla"; */ + /* case DW_AT_SUN_return_value_ptr: */ + /* return "DW_AT_SUN_return_value_ptr"; */ + /* case DW_AT_SUN_dtor_start: */ + /* return "DW_AT_SUN_dtor_start"; */ + /* case DW_AT_SUN_dtor_length: */ + /* return "DW_AT_SUN_dtor_length"; */ + /* case DW_AT_SUN_dtor_state_initial: */ + /* return "DW_AT_SUN_dtor_state_initial"; */ + /* case DW_AT_SUN_dtor_state_final: */ + /* return "DW_AT_SUN_dtor_state_final"; */ + /* case DW_AT_SUN_dtor_state_deltas: */ + /* return "DW_AT_SUN_dtor_state_deltas"; */ + /* case DW_AT_SUN_import_by_lname: */ + /* return "DW_AT_SUN_import_by_lname"; */ + /* case DW_AT_SUN_f90_use_only: */ + /* return "DW_AT_SUN_f90_use_only"; */ + /* case DW_AT_SUN_namelist_spec: */ + /* return "DW_AT_SUN_namelist_spec"; */ + /* case DW_AT_SUN_is_omp_child_func: */ + /* return "DW_AT_SUN_is_omp_child_func"; */ + /* case DW_AT_SUN_fortran_main_alias: */ + /* return "DW_AT_SUN_fortran_main_alias"; */ + /* case DW_AT_SUN_fortran_based: */ + /* return "DW_AT_SUN_fortran_based"; */ + /* case DW_AT_ALTIUM_loclist: */ + /* return "DW_AT_ALTIUM_loclist"; */ + /* case DW_AT_use_GNAT_descriptive_type: */ + /* return "DW_AT_use_GNAT_descriptive_type"; */ + /* case DW_AT_GNAT_descriptive_type: */ + /* return "DW_AT_GNAT_descriptive_type"; */ + /* case DW_AT_GNU_numerator: */ + /* return "DW_AT_GNU_numerator"; */ + /* case DW_AT_GNU_denominator: */ + /* return "DW_AT_GNU_denominator"; */ + /* case DW_AT_GNU_bias: */ + /* return "DW_AT_GNU_bias"; */ + /* case DW_AT_go_kind: */ + /* return "DW_AT_go_kind"; */ + /* case DW_AT_go_key: */ + /* return "DW_AT_go_key"; */ + /* case DW_AT_go_elem: */ + /* return "DW_AT_go_elem"; */ + /* case DW_AT_go_embedded_field: */ + /* return "DW_AT_go_embedded_field"; */ + /* case DW_AT_go_runtime_type: */ + /* return "DW_AT_go_runtime_type"; */ + /* case DW_AT_upc_threads_scaled: */ + /* return "DW_AT_upc_threads_scaled"; */ + /* case DW_AT_IBM_wsa_addr: */ + /* return "DW_AT_IBM_wsa_addr"; */ + /* case DW_AT_IBM_home_location: */ + /* return "DW_AT_IBM_home_location"; */ + /* case DW_AT_IBM_alt_srcview: */ + /* return "DW_AT_IBM_alt_srcview"; */ + /* case DW_AT_PGI_lbase: */ + /* return "DW_AT_PGI_lbase"; */ + /* case DW_AT_PGI_soffset: */ + /* return "DW_AT_PGI_soffset"; */ + /* case DW_AT_PGI_lstride: */ + /* return "DW_AT_PGI_lstride"; */ + /* case DW_AT_BORLAND_property_read: */ + /* return "DW_AT_BORLAND_property_read"; */ + /* case DW_AT_BORLAND_property_write: */ + /* return "DW_AT_BORLAND_property_write"; */ + /* case DW_AT_BORLAND_property_implements: */ + /* return "DW_AT_BORLAND_property_implements"; */ + /* case DW_AT_BORLAND_property_index: */ + /* return "DW_AT_BORLAND_property_index"; */ + /* case DW_AT_BORLAND_property_default: */ + /* return "DW_AT_BORLAND_property_default"; */ + /* case DW_AT_BORLAND_Delphi_unit: */ + /* return "DW_AT_BORLAND_Delphi_unit"; */ + /* case DW_AT_BORLAND_Delphi_class: */ + /* return "DW_AT_BORLAND_Delphi_class"; */ + /* case DW_AT_BORLAND_Delphi_record: */ + /* return "DW_AT_BORLAND_Delphi_record"; */ + /* case DW_AT_BORLAND_Delphi_metaclass: */ + /* return "DW_AT_BORLAND_Delphi_metaclass"; */ + /* case DW_AT_BORLAND_Delphi_constructor: */ + /* return "DW_AT_BORLAND_Delphi_constructor"; */ + /* case DW_AT_BORLAND_Delphi_destructor: */ + /* return "DW_AT_BORLAND_Delphi_destructor"; */ + /* case DW_AT_BORLAND_Delphi_anonymous_method: */ + /* return "DW_AT_BORLAND_Delphi_anonymous_method"; */ + /* case DW_AT_BORLAND_Delphi_interface: */ + /* return "DW_AT_BORLAND_Delphi_interface"; */ + /* case DW_AT_BORLAND_Delphi_ABI: */ + /* return "DW_AT_BORLAND_Delphi_ABI"; */ + /* case DW_AT_BORLAND_Delphi_frameptr: */ + /* return "DW_AT_BORLAND_Delphi_frameptr"; */ + /* case DW_AT_BORLAND_closure: */ + /* return "DW_AT_BORLAND_closure"; */ + /* case DW_AT_LLVM_include_path: */ + /* return "DW_AT_LLVM_include_path"; */ + /* case DW_AT_LLVM_config_macros: */ + /* return "DW_AT_LLVM_config_macros"; */ + /* case DW_AT_LLVM_sysroot: */ + /* return "DW_AT_LLVM_sysroot"; */ + /* case DW_AT_LLVM_tag_offset: */ + /* return "DW_AT_LLVM_tag_offset"; */ + /* case DW_AT_LLVM_apinotes: */ + /* return "DW_AT_LLVM_apinotes"; */ + /* case DW_AT_LLVM_active_lane: */ + /* return "DW_AT_LLVM_active_lane"; */ + /* case DW_AT_LLVM_augmentation: */ + /* return "DW_AT_LLVM_augmentation"; */ + /* case DW_AT_LLVM_lanes: */ + /* return "DW_AT_LLVM_lanes"; */ + /* case DW_AT_LLVM_lane_pc: */ + /* return "DW_AT_LLVM_lane_pc"; */ + /* case DW_AT_LLVM_vector_size: */ + /* return "DW_AT_LLVM_vector_size"; */ + /* case DW_AT_APPLE_optimized: */ + /* return "DW_AT_APPLE_optimized"; */ + /* case DW_AT_APPLE_flags: */ + /* return "DW_AT_APPLE_flags"; */ + /* case DW_AT_APPLE_isa: */ + /* return "DW_AT_APPLE_isa"; */ + /* case DW_AT_APPLE_block: */ + /* return "DW_AT_APPLE_block"; */ + /* case DW_AT_APPLE_major_runtime_vers: */ + /* return "DW_AT_APPLE_major_runtime_vers"; */ + /* case DW_AT_APPLE_runtime_class: */ + /* return "DW_AT_APPLE_runtime_class"; */ + /* case DW_AT_APPLE_omit_frame_ptr: */ + /* return "DW_AT_APPLE_omit_frame_ptr"; */ + /* case DW_AT_APPLE_property_name: */ + /* return "DW_AT_APPLE_property_name"; */ + /* case DW_AT_APPLE_property_getter: */ + /* return "DW_AT_APPLE_property_getter"; */ + /* case DW_AT_APPLE_property_setter: */ + /* return "DW_AT_APPLE_property_setter"; */ + /* case DW_AT_APPLE_property_attribute: */ + /* return "DW_AT_APPLE_property_attribute"; */ + /* case DW_AT_APPLE_objc_complete_type: */ + /* return "DW_AT_APPLE_objc_complete_type"; */ + /* case DW_AT_APPLE_property: */ + /* return "DW_AT_APPLE_property"; */ + /* case DW_AT_APPLE_objc_direct: */ + /* return "DW_AT_APPLE_objc_direct"; */ + /* case DW_AT_APPLE_sdk: */ + /* return "DW_AT_APPLE_sdk"; */ + case DW_AT_hi_user: + return "DW_AT_hi_user"; + default: break; + } + return ""; +} + +const char * dwarf_get_FORM_name (unsigned int val) +{ + switch (val) { + case DW_FORM_addr: + return "DW_FORM_addr"; + case DW_FORM_block2: + return "DW_FORM_block2"; + case DW_FORM_block4: + return "DW_FORM_block4"; + case DW_FORM_data2: + return "DW_FORM_data2"; + case DW_FORM_data4: + return "DW_FORM_data4"; + case DW_FORM_data8: + return "DW_FORM_data8"; + case DW_FORM_string: + return "DW_FORM_string"; + case DW_FORM_block: + return "DW_FORM_block"; + case DW_FORM_block1: + return "DW_FORM_block1"; + case DW_FORM_data1: + return "DW_FORM_data1"; + case DW_FORM_flag: + return "DW_FORM_flag"; + case DW_FORM_sdata: + return "DW_FORM_sdata"; + case DW_FORM_strp: + return "DW_FORM_strp"; + case DW_FORM_udata: + return "DW_FORM_udata"; + case DW_FORM_ref_addr: + return "DW_FORM_ref_addr"; + case DW_FORM_ref1: + return "DW_FORM_ref1"; + case DW_FORM_ref2: + return "DW_FORM_ref2"; + case DW_FORM_ref4: + return "DW_FORM_ref4"; + case DW_FORM_ref8: + return "DW_FORM_ref8"; + case DW_FORM_ref_udata: + return "DW_FORM_ref_udata"; + case DW_FORM_indirect: + return "DW_FORM_indirect"; + case DW_FORM_sec_offset: + return "DW_FORM_sec_offset"; + case DW_FORM_exprloc: + return "DW_FORM_exprloc"; + case DW_FORM_flag_present: + return "DW_FORM_flag_present"; + case DW_FORM_strx: + return "DW_FORM_strx"; + case DW_FORM_addrx: + return "DW_FORM_addrx"; + case DW_FORM_ref_sup4: + return "DW_FORM_ref_sup4"; + case DW_FORM_strp_sup: + return "DW_FORM_strp_sup"; + case DW_FORM_data16: + return "DW_FORM_data16"; + case DW_FORM_line_strp: + return "DW_FORM_line_strp"; + case DW_FORM_ref_sig8: + return "DW_FORM_ref_sig8"; + case DW_FORM_implicit_const: + return "DW_FORM_implicit_const"; + case DW_FORM_loclistx: + return "DW_FORM_loclistx"; + case DW_FORM_rnglistx: + return "DW_FORM_rnglistx"; + case DW_FORM_ref_sup8: + return "DW_FORM_ref_sup8"; + case DW_FORM_strx1: + return "DW_FORM_strx1"; + case DW_FORM_strx2: + return "DW_FORM_strx2"; + case DW_FORM_strx3: + return "DW_FORM_strx3"; + case DW_FORM_strx4: + return "DW_FORM_strx4"; + case DW_FORM_addrx1: + return "DW_FORM_addrx1"; + case DW_FORM_addrx2: + return "DW_FORM_addrx2"; + case DW_FORM_addrx3: + return "DW_FORM_addrx3"; + case DW_FORM_addrx4: + return "DW_FORM_addrx4"; + /* case DW_FORM_GNU_addr_index: */ + /* return "DW_FORM_GNU_addr_index"; */ + /* case DW_FORM_GNU_str_index: */ + /* return "DW_FORM_GNU_str_index"; */ + /* case DW_FORM_GNU_ref_alt: */ + /* return "DW_FORM_GNU_ref_alt"; */ + /* case DW_FORM_GNU_strp_alt: */ + /* return "DW_FORM_GNU_strp_alt"; */ + /* case DW_FORM_LLVM_addrx_offset: */ + /* return "DW_FORM_LLVM_addrx_offset"; */ + default: break; + } + return ""; +} + +const char * dwarf_get_LANG_name (unsigned int val) +{ + switch(val) + { + case DW_LANG_C89 : return "DW_LANG_C89"; + case DW_LANG_C : return "DW_LANG_C"; + case DW_LANG_Ada83 : return "DW_LANG_Ada83"; + case DW_LANG_C_plus_plus : return "DW_LANG_C_plus_plus"; + case DW_LANG_Cobol74 : return "DW_LANG_Cobol74"; + case DW_LANG_Cobol85 : return "DW_LANG_Cobol85"; + case DW_LANG_Fortran77 : return "DW_LANG_Fortran77"; + case DW_LANG_Fortran90 : return "DW_LANG_Fortran90"; + case DW_LANG_Pascal83 : return "DW_LANG_Pascal83"; + case DW_LANG_Modula2 : return "DW_LANG_Modula2"; + case DW_LANG_Java : return "DW_LANG_Java"; + case DW_LANG_C99 : return "DW_LANG_C99"; + case DW_LANG_Ada95 : return "DW_LANG_Ada95"; + case DW_LANG_Fortran95 : return "DW_LANG_Fortran95"; + case DW_LANG_PLI : return "DW_LANG_PLI"; + case DW_LANG_ObjC : return "DW_LANG_ObjC"; + case DW_LANG_ObjC_plus_plus : return "DW_LANG_ObjC_plus_plus"; + case DW_LANG_UPC : return "DW_LANG_UPC"; + case DW_LANG_D : return "DW_LANG_D"; + case DW_LANG_Python : return "DW_LANG_Python"; + case DW_LANG_OpenCL : return "DW_LANG_OpenCL"; + case DW_LANG_Go : return "DW_LANG_Go"; + case DW_LANG_Modula3 : return "DW_LANG_Modula3"; + case DW_LANG_Haskell : return "DW_LANG_Haskell"; + case DW_LANG_C_plus_plus_03 : return "DW_LANG_C_plus_plus_03"; + case DW_LANG_C_plus_plus_11 : return "DW_LANG_C_plus_plus_11"; + case DW_LANG_OCaml : return "DW_LANG_OCaml"; + case DW_LANG_Rust : return "DW_LANG_Rust"; + case DW_LANG_C11 : return "DW_LANG_C11"; + case DW_LANG_Swift : return "DW_LANG_Swift"; + case DW_LANG_Julia : return "DW_LANG_Julia"; + case DW_LANG_Dylan : return "DW_LANG_Dylan"; + case DW_LANG_C_plus_plus_14 : return "DW_LANG_C_plus_plus_14"; + case DW_LANG_Fortran03 : return "DW_LANG_Fortran03"; + case DW_LANG_Fortran08 : return "DW_LANG_Fortran08"; + case DW_LANG_RenderScript : return "DW_LANG_RenderScript"; + case DW_LANG_BLISS : return "DW_LANG_BLISS"; + case DW_LANG_lo_user : return "DW_LANG_lo_user"; + case DW_LANG_hi_user : return "DW_LANG_hi_user"; + default: break; + } + return ""; +} diff --git a/enums.h b/enums.h new file mode 100644 index 0000000..0b2f90d --- /dev/null +++ b/enums.h @@ -0,0 +1,309 @@ +#pragma once + +// Table 7.4, page 207 +typedef enum { + DW_CHILDREN_no = 0x00, + DW_CHILDREN_yes = 0x01 +} children_encoding_t; + + +// Table 7.3, page 204-206 +typedef enum { + DW_TAG_array_type = 0x01, + DW_TAG_class_type = 0x02, + DW_TAG_entry_point = 0x03, + DW_TAG_enumeration_type = 0x04, + DW_TAG_formal_parameter = 0x05, + DW_TAG_imported_declaration = 0x08, + DW_TAG_label = 0x0a, + DW_TAG_lexical_block = 0x0b, + DW_TAG_member = 0x0d, + DW_TAG_pointer_type = 0x0f, + DW_TAG_reference_type = 0x10, + DW_TAG_compile_unit = 0x11, + DW_TAG_string_type = 0x12, + DW_TAG_structure_type = 0x13, + DW_TAG_subroutine_type = 0x15, + DW_TAG_typedef = 0x16, + DW_TAG_union_type = 0x17, + DW_TAG_unspecified_parameters = 0x18, + DW_TAG_variant = 0x19, + DW_TAG_common_block = 0x1a, + DW_TAG_common_inclusion = 0x1b, + DW_TAG_inheritance = 0x1c, + DW_TAG_inlined_subroutine = 0x1d, + DW_TAG_module = 0x1e, + DW_TAG_ptr_to_member_type = 0x1f, + DW_TAG_set_type = 0x20, + DW_TAG_subrange_type = 0x21, + DW_TAG_with_stmt = 0x22, + DW_TAG_access_declaration = 0x23, + DW_TAG_base_type = 0x24, + DW_TAG_catch_block = 0x25, + DW_TAG_const_type = 0x26, + DW_TAG_constant = 0x27, + DW_TAG_enumerator = 0x28, + DW_TAG_file_type = 0x29, + DW_TAG_friend = 0x2a, + DW_TAG_namelist = 0x2b, + DW_TAG_namelist_item = 0x2c, + DW_TAG_packed_type = 0x2d, + DW_TAG_subprogram = 0x2e, + DW_TAG_template_type_parameter = 0x2f, + DW_TAG_template_value_parameter = 0x30, + DW_TAG_thrown_type = 0x31, + DW_TAG_try_block = 0x32, + DW_TAG_variant_part = 0x33, + DW_TAG_variable = 0x34, + DW_TAG_volatile_type = 0x35, + DW_TAG_dwarf_procedure = 0x36, + DW_TAG_restrict_type = 0x37, + DW_TAG_interface_type = 0x38, + DW_TAG_namespace = 0x39, + DW_TAG_imported_module = 0x3a, + DW_TAG_unspecified_type = 0x3b, + DW_TAG_partial_unit = 0x3c, + DW_TAG_imported_unit = 0x3d, + DW_TAG_condition = 0x3f, + DW_TAG_shared_type = 0x40, + DW_TAG_type_unit = 0x41, + DW_TAG_rvalue_reference_type = 0x42, + DW_TAG_template_alias = 0x43, + DW_TAG_coarray_type = 0x44, + DW_TAG_generic_subrange = 0x45, + DW_TAG_dynamic_type = 0x46, + DW_TAG_atomic_type = 0x47, + DW_TAG_call_site = 0x48, + DW_TAG_call_site_parameter = 0x49, + DW_TAG_skeleton_unit = 0x4a, + DW_TAG_immutable_type = 0x4b, + DW_TAG_lo_user = 0x4080, + DW_TAG_hi_user = 0xffff +} tag_type_t; + + +// Table 7.5, page 207-212 +typedef enum { + DW_AT_sibling = 0x01, + DW_AT_location = 0x02, + DW_AT_name = 0x03, + DW_AT_ordering = 0x09, + DW_AT_byte_size = 0x0b, + DW_AT_bit_size = 0x0d, + DW_AT_stmt_list = 0x10, + DW_AT_low_pc = 0x11, + DW_AT_high_pc = 0x12, + DW_AT_language = 0x13, + DW_AT_discr = 0x15, + DW_AT_discr_value = 0x16, + DW_AT_visibility = 0x17, + DW_AT_import = 0x18, + DW_AT_string_length = 0x19, + DW_AT_common_reference = 0x1a, + DW_AT_comp_dir = 0x1b, + DW_AT_const_value = 0x1c, + DW_AT_containing_type = 0x1d, + DW_AT_default_value = 0x1e, + DW_AT_inline = 0x20, + DW_AT_is_optional = 0x21, + DW_AT_lower_bound = 0x22, + DW_AT_producer = 0x25, + DW_AT_prototyped = 0x27, + DW_AT_return_addr = 0x2a, + DW_AT_start_scope = 0x2c, + DW_AT_bit_stride = 0x2e, + DW_AT_upper_bound = 0x2f, + DW_AT_abstract_origin = 0x31, + DW_AT_accessibility = 0x32, + DW_AT_address_class = 0x33, + DW_AT_artificial = 0x34, + DW_AT_base_types = 0x35, + DW_AT_calling_convention = 0x36, + DW_AT_count = 0x37, + DW_AT_data_member_location = 0x38, + DW_AT_decl_column = 0x39, + DW_AT_decl_file = 0x3a, + DW_AT_decl_line = 0x3b, + DW_AT_declaration = 0x3c, + DW_AT_discr_list = 0x3d, + DW_AT_encoding = 0x3e, + DW_AT_external = 0x3f, + DW_AT_frame_base = 0x40, + DW_AT_friend = 0x41, + DW_AT_identifier_case = 0x42, + DW_AT_namelist_item = 0x44, + DW_AT_priority = 0x45, + DW_AT_segment = 0x46, + DW_AT_specification = 0x47, + DW_AT_static_link = 0x48, + DW_AT_type = 0x49, + DW_AT_use_location = 0x4a, + DW_AT_variable_parameter = 0x4b, + DW_AT_virtuality = 0x4c, + DW_AT_vtable_elem_location = 0x4d, + DW_AT_allocated = 0x4e, + DW_AT_associated = 0x4f, + DW_AT_data_location = 0x50, + DW_AT_byte_stride = 0x51, + DW_AT_entry_pc = 0x52, + DW_AT_use_UTF8 = 0x53, + DW_AT_extension = 0x54, + DW_AT_ranges = 0x55, + DW_AT_trampoline = 0x56, + DW_AT_call_column = 0x57, + DW_AT_call_file = 0x58, + DW_AT_call_line = 0x59, + DW_AT_description = 0x5a, + DW_AT_binary_scale = 0x5b, + DW_AT_decimal_scale = 0x5c, + DW_AT_small = 0x5d, + DW_AT_decimal_sign = 0x5e, + DW_AT_digit_count = 0x5f, + DW_AT_picture_string = 0x60, + DW_AT_mutable = 0x61, + DW_AT_threads_scaled = 0x62, + DW_AT_explicit = 0x63, + DW_AT_object_pointer = 0x64, + DW_AT_endianity = 0x65, + DW_AT_elemental = 0x66, + DW_AT_pure = 0x67, + DW_AT_recursive = 0x68, + DW_AT_signature = 0x69, + DW_AT_main_subprogram = 0x6a, + DW_AT_data_bit_offset = 0x6b, + DW_AT_const_expr = 0x6c, + DW_AT_enum_class = 0x6d, + DW_AT_linkage_name = 0x6e, + DW_AT_string_length_bit_size = 0x6f, + DW_AT_string_length_byte_size = 0x70, + DW_AT_rank = 0x71, + DW_AT_str_offsets_base = 0x72, + DW_AT_addr_base = 0x73, + DW_AT_rnglists_base = 0x74, + DW_AT_dwo_name = 0x76, + DW_AT_reference = 0x77, + DW_AT_rvalue_reference = 0x78, + DW_AT_macros = 0x79, + DW_AT_call_all_calls = 0x7a, + DW_AT_call_all_source_calls = 0x7b, + DW_AT_call_all_tail_calls = 0x7c, + DW_AT_call_return_pc = 0x7d, + DW_AT_call_value = 0x7e, + DW_AT_call_origin = 0x7f, + DW_AT_call_parameter = 0x80, + DW_AT_call_pc = 0x81, + DW_AT_call_tail_call = 0x82, + DW_AT_call_target = 0x83, + DW_AT_call_target_clobbered = 0x84, + DW_AT_call_data_location = 0x85, + DW_AT_call_data_value = 0x86, + DW_AT_noreturn = 0x87, + DW_AT_alignment = 0x88, + DW_AT_export_symbols = 0x89, + DW_AT_deleted = 0x8a, + DW_AT_defaulted = 0x8b, + DW_AT_loclists_base = 0x8c, + DW_AT_lo_user = 0x2000, + DW_AT_hi_user = 0x3ffff +} attribute_encoding_t; + +typedef enum { + DW_FORM_addr = 0x01, + DW_FORM_block2 = 0x03, + DW_FORM_block4 = 0x04, + DW_FORM_data2 = 0x05, + DW_FORM_data4 = 0x06, + DW_FORM_data8 = 0x07, + DW_FORM_string = 0x08, + DW_FORM_block = 0x09, + DW_FORM_block1 = 0x0a, + DW_FORM_data1 = 0x0b, + DW_FORM_flag = 0x0c, + DW_FORM_sdata = 0x0d, + DW_FORM_strp = 0x0e, + DW_FORM_udata = 0x0f, + DW_FORM_ref_addr = 0x10, + DW_FORM_ref1 = 0x11, + DW_FORM_ref2 = 0x12, + DW_FORM_ref4 = 0x13, + DW_FORM_ref8 = 0x14, + DW_FORM_ref_udata = 0x15, + DW_FORM_indirect = 0x16, + DW_FORM_sec_offset = 0x17, + DW_FORM_exprloc = 0x18, + DW_FORM_flag_present = 0x19, + DW_FORM_strx = 0x1a, + DW_FORM_addrx = 0x1b, + DW_FORM_ref_sup4 = 0x1c, + DW_FORM_strp_sup = 0x1d, + DW_FORM_data16 = 0x1e, + DW_FORM_line_strp = 0x1f, + DW_FORM_ref_sig8 = 0x20, + DW_FORM_implicit_const = 0x21, + DW_FORM_loclistx = 0x22, + DW_FORM_rnglistx = 0x23, + DW_FORM_ref_sup8 = 0x24, + DW_FORM_strx1 = 0x25, + DW_FORM_strx2 = 0x26, + DW_FORM_strx3 = 0x27, + DW_FORM_strx4 = 0x28, + DW_FORM_addrx1 = 0x29, + DW_FORM_addrx2 = 0x2a, + DW_FORM_addrx3 = 0x2b, + DW_FORM_addrx4 = 0x2c, +} attribute_form_t; + + +typedef enum { + DW_LANG_C89 = 0x01, + DW_LANG_C = 0x02, + DW_LANG_Ada83 = 0x03, + DW_LANG_C_plus_plus = 0x04, + DW_LANG_Cobol74 = 0x05, + DW_LANG_Cobol85 = 0x06, + DW_LANG_Fortran77 = 0x07, + DW_LANG_Fortran90 = 0x08, + DW_LANG_Pascal83 = 0x09, + DW_LANG_Modula2 = 0x0a, + DW_LANG_Java = 0x0b, + DW_LANG_C99 = 0x0c, + DW_LANG_Ada95 = 0x0d, + DW_LANG_Fortran95 = 0x0e, + DW_LANG_PLI = 0x0f, + DW_LANG_ObjC = 0x10, + DW_LANG_ObjC_plus_plus = 0x11, + DW_LANG_UPC = 0x12, + DW_LANG_D = 0x13, + DW_LANG_Python = 0x14, + DW_LANG_OpenCL = 0x15, + DW_LANG_Go = 0x16, + DW_LANG_Modula3 = 0x17, + DW_LANG_Haskell = 0x18, + DW_LANG_C_plus_plus_03 = 0x19, + DW_LANG_C_plus_plus_11 = 0x1a, + DW_LANG_OCaml = 0x1b, + DW_LANG_Rust = 0x1c, + DW_LANG_C11 = 0x1d, + DW_LANG_Swift = 0x1e, + DW_LANG_Julia = 0x1f, + DW_LANG_Dylan = 0x20, + DW_LANG_C_plus_plus_14 = 0x21, + DW_LANG_Fortran03 = 0x22, + DW_LANG_Fortran08 = 0x23, + DW_LANG_RenderScript = 0x24, + DW_LANG_BLISS = 0x25, + DW_LANG_lo_user = 0x8000, + DW_LANG_hi_user = 0xffff, +} language_type_t; + +// Table 7.2, page 199 +typedef enum { + DW_UT_compile = 0x01, + DW_UT_type = 0x02, + DW_UT_partial = 0x03, + DW_UT_skeleton = 0x04, + DW_UT_split_compile = 0x05, + DW_UT_split_type = 0x06, + DW_UT_lo_user = 0x80, + DW_UT_hi_user = 0xff, +} unit_header_types_t; diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..f8cb041 --- /dev/null +++ b/main.cpp @@ -0,0 +1,470 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "enums.h" +#include "enum_names.h" + +// STD +// TODO: maybe do not use this +#include + +#define _STRINGIFY(symbol) #symbol +#define STRINGIFY(symbol) _STRINGIFY(symbol) + + +// TODO: dwarf32 +// page 200 +typedef struct __attribute__((packed)) { + uint32_t preface; // should be 0xFFFFFFFF for 64b + uint64_t unit_length; + uint16_t version; // should be 5 + uint8_t unit_type; // should be DW_UT_compile or DW_UT_partial + uint8_t address_size; // should be 8 for 64b systems + uint64_t debug_abbrev_offset; +} compilation_unit_header_t; + + +// TODO: dwarf32 +typedef struct __attribute__((packed)) { + uint32_t preface; // should be 0xFFFFFFFF for 64b + uint64_t unit_length; + uint16_t version; + uint64_t debug_info_offset; + uint8_t address_size; // should be 8 for 64b systems + uint8_t segment_selector_size; +} debug_aranges_header_t; + +static_assert(sizeof(debug_aranges_header_t) == 24); + +typedef struct { + uint64_t abbrev_code; // ? + uint32_t abbrev_tag; // DW_TAG_* + uint8_t children; // DW_CHILDREN_* +} debug_abbrev_entry_t; + +typedef struct { + uint64_t name; // DW_AT_* + uint64_t form; // DW_FORM_* + uint64_t value; // if DW_FORM_implicit_const +} attribute_spec_t; + +// TODO: Store this in a more space-sensitive way +typedef struct { + std::vector entries; + std::vector> specs; +} abbrev_table_t; + +abbrev_table_t abbrev_table; + +// function signatures +void parse_debuginfo_section(const void *file); +void parse_aranges_section(const void *file, uint64_t offset); +uint64_t get_alignment_of_section(const void *file, const char *name); +uint64_t get_offset_of_section(const void *file, const char *name); +void parse_section_names(const void *file, Elf64_Shdr* table, int n, int strtab_index); +void print_header(Elf64_Ehdr *header); + +// TODO: Deal with cases where size of LEB128 > word size +inline int decode_leb128(uint8_t *src, uint64_t *dest) +{ + *dest = 0; + int shift = 0; + uint8_t val; + do { + val = *src++; + *dest |= (val & 0x7f) << shift; + shift += 7; + } while (val & 0x80); + // return the number of bytes that we should move the src pointer + return shift / 8 + (shift % 8 != 0); +} + +// globals +uint64_t cu_header_offset = 0; + +void parse_debuginfo_section(const void *file) +{ + char *p = (char*)file; + + uint64_t debuginfo_offset = get_offset_of_section(file, ".debug_info"); + fprintf(stdout, "Offset of .debug_info section: %d\n", debuginfo_offset); + fprintf(stdout, "Offset of CUH in section: %d\n", cu_header_offset); + p += debuginfo_offset + cu_header_offset; + + compilation_unit_header_t* cuh = (compilation_unit_header_t*)p; + + fprintf(stdout, "CUH length: %#x\n", cuh->unit_length); + fprintf(stdout, "CUH version: %d\n", cuh->version); + // TODO: multifile dwarf + fprintf(stdout, "CUH unit_type: %d (%s)\n", cuh->unit_type, (cuh->unit_type == DW_UT_compile ? STRINGIFY(DW_UT_compile) : "?")); + fprintf(stdout, "CUH address_size: %d\n", cuh->address_size); + fprintf(stdout, "CUH debug_abbrev_offset: %d\n", cuh->debug_abbrev_offset); + + uint64_t abbrev_section_offset = get_offset_of_section(file, ".debug_abbrev"); + // Pointer to .debug_abbrev section memory for current CU + char *cu_abbrev = ((char*)file) + abbrev_section_offset + cuh->debug_abbrev_offset; + + fprintf(stdout, "ABBREV for this compilation unit should start at: %x\n", abbrev_section_offset + cuh->debug_abbrev_offset); + + // begin parsing proper + uint64_t abbrev_code; + uint64_t abbrev_tag; + + // TODO: Error handling + do { + cu_abbrev += decode_leb128((uint8_t*)cu_abbrev, &abbrev_code); + // The entries for a compilation unit end with a 0-byte abbrev code + if (!abbrev_code) + break; + cu_abbrev += decode_leb128((uint8_t*)cu_abbrev, &abbrev_tag); + + bool children = *cu_abbrev++; + fprintf(stdout, " %d %s, children = %s\n", abbrev_code, dwarf_get_TAG_name(abbrev_tag), children ? "yes" : "no"); + + abbrev_table.entries.push_back({abbrev_code, (uint32_t)abbrev_tag, children}); + + std::vector attr_specs = {}; // for this code + + uint64_t attrib_name; + uint64_t attrib_form; + uint64_t implicit_const = 0; + // TODO: Error handling + do { + cu_abbrev += decode_leb128((uint8_t*)cu_abbrev, &attrib_name); + cu_abbrev += decode_leb128((uint8_t*)cu_abbrev, &attrib_form); + if (attrib_form == DW_FORM_implicit_const) + { + cu_abbrev += decode_leb128((uint8_t*)cu_abbrev, &implicit_const); + fprintf(stdout, "\t%-26s %s value: %d\n", dwarf_get_AT_name(attrib_name), dwarf_get_FORM_name(attrib_form), implicit_const); + } + else if (!attrib_name && !attrib_form) + fprintf(stdout, "\t0\n"); + else + fprintf(stdout, "\t%-26s %s\n", dwarf_get_AT_name(attrib_name), dwarf_get_FORM_name(attrib_form)); + + if (attrib_name && attrib_form) + { + attr_specs.push_back({attrib_name, attrib_form, implicit_const}); + } + } while (attrib_name && attrib_form); + abbrev_table.specs.push_back(attr_specs); + } while (true); + + p += sizeof(compilation_unit_header_t); + + fprintf(stdout, "==================================\n"); + uint64_t code; + fprintf(stdout, ".debug_info offset for first DIE: %#x\n", ((uint64_t)p - (uint64_t)file)); + // TODO: 32bit size + for (; ((uint64_t)p - (uint64_t)cuh) < cuh->unit_length - 12;) + { + p += decode_leb128((uint8_t*)p, &code); + + fprintf(stdout, "%d (%s)\n", code, dwarf_get_TAG_name(abbrev_table.entries[code-1].abbrev_tag)); + for (size_t i = 0; i < abbrev_table.specs[code-1].size(); ++i) + { + fprintf(stdout, "\t%s\t\t", dwarf_get_AT_name(abbrev_table.specs[code-1][i].name)); + // Get the desired value according to FORM + switch (abbrev_table.specs[code-1][i].form) + { + case DW_FORM_addr: // 0x01 + { + // TODO: 32bit addresses + uint64_t addr_value = *(uint64_t*)p; + p+= 8; + fprintf(stdout, "\t%#x\n", addr_value); + } break; + case DW_FORM_data2: // 0x05 + { + uint16_t data = *(uint16_t*)p; + p += 2; + fprintf(stdout, "\t%#x\n", data); + } break; + case DW_FORM_data4: // 0x06 + { + uint32_t data = *(uint32_t*)p; + p += 4; + fprintf(stdout, "\t%#x\n", data); + } break; + case DW_FORM_data8: // 0x06 + { + uint64_t data = *(uint64_t*)p; + p += 8; + fprintf(stdout, "\t%#x\n", data); + } break; + case DW_FORM_string: // 0x08 + { + // String is inside the .debug_info, just read it and advance pointer past null terminator + fprintf(stdout, "\t%s\n", p); + while (*p++); + } break; + case DW_FORM_data1: // 0x13 + { + uint8_t data = *(uint8_t*)p; + p += 1; + if (abbrev_table.specs[code-1][i].name == DW_AT_language) + fprintf(stdout, "\t%s\n", dwarf_get_LANG_name(data)); + else + fprintf(stdout, "\t%#x\n", data); + } break; + + case DW_FORM_ref8: + { + uint64_t data = *(uint64_t*)p; + p += 8; + fprintf(stdout, "\t%#x\n", data); + } break; + case DW_FORM_sec_offset: // 0x17 + { + // TODO: 32 addresses + // TODO: read more about this. Could both files exist at the same time? + // NOTE: objdump does not seem to try reading the string, instead outputs the pointer value + // read offset into .debug_rnglists or .debug_loclists of desired string + uint64_t str_offset = *(uint64_t*)p; + p+= 8; + uint64_t section_offset = get_offset_of_section(file, ".debug_rnglists"); + char *string = (char*)file + section_offset + str_offset; + fprintf(stdout, "\t%s\n", string); + } break; + case DW_FORM_exprloc: // 0x18 + { + uint64_t length; + p += decode_leb128((uint8_t*)p, &length); + // TODO: save this data + p += length; + fprintf(stdout, "(%d bytes data)\n"); + } break; + case DW_FORM_flag_present: + { + // Nothing to read here, flag_present just indicates that a flag is ON. We output '1' just like objdump does + fprintf(stdout, "\t1\n"); + } break; + case DW_FORM_implicit_const: + { + // We already have the value, do not advance the pointer at all + fprintf(stdout, "\t%#x\n", abbrev_table.specs[code-1][i].value); + } break; + case DW_FORM_strp: // 0x0e + { + // TODO: 32 addresses + // read offset into .debug_str of desired string + uint64_t str_offset = *(uint64_t*)p; + p+= 8; + uint64_t section_offset = get_offset_of_section(file, ".debug_str"); + char *string = (char*)file + section_offset + str_offset; + fprintf(stdout, "\t%s\n", string); + } break; + + case DW_FORM_line_strp: // 0x1f + { + // TODO: 32 addresses + // read offset into .debug_line_str of desired string + uint64_t str_offset = *(uint64_t*)p; + p+= 8; + uint64_t section_offset = get_offset_of_section(file, ".debug_line_str"); + char *string = (char*)file + section_offset + str_offset; + fprintf(stdout, "\t%s\n", string); + } break; + default: + fprintf(stdout, "\tTODO\n"); + break; + } + } + fprintf(stdout, "\n"); + } +} + +void parse_aranges_section(const void *file, uint64_t offset) +{ + debug_aranges_header_t *headerinfo = (debug_aranges_header_t*)((char*)file + offset); + fprintf(stdout, ".debug_aranges info:\n"); + fprintf(stdout, "\tunit_length: %d\n", headerinfo->unit_length); + fprintf(stdout, "\tversion: %d\n", headerinfo->version); + fprintf(stdout, "\tdebug_info_offset: %d\n", headerinfo->debug_info_offset); + fprintf(stdout, "\taddress_size: %d\n", headerinfo->address_size); + fprintf(stdout, "\tsegment_selector_size: %d\n", headerinfo->segment_selector_size); + // TODO: Deal with more than one address + cu_header_offset = headerinfo->debug_info_offset; + + fprintf(stdout, "\tADDRESS\tLENGTH:\n"); + char *p = (char*)headerinfo; + int padding_boundary = headerinfo->segment_selector_size + headerinfo->address_size * 2; + int curr_padding = sizeof(debug_aranges_header_t); + while (curr_padding % padding_boundary) + ++curr_padding; + p = p + curr_padding; + while (1) + { + // TODO: dwarf32 + if (headerinfo->address_size != 8) + { + fprintf(stderr, "Address_size != 8 not implemented yet"); + exit(1); + } + if (headerinfo->segment_selector_size) + { + fprintf(stderr, "Segment selectors are not implemented yet"); + exit(1); + } + uint64_t address = *((uint64_t*)p); + fprintf(stdout, "\t%x", address); + p = p + headerinfo->address_size; + uint64_t length = *((uint64_t*)p); + fprintf(stdout, "\t%x\n", length); + p = p + headerinfo->address_size; + + if (!address && !length) + break; + } +} + +uint64_t get_alignment_of_section(const void *file, const char *name) +{ + Elf64_Ehdr *elf_header = (Elf64_Ehdr *)file; + Elf64_Shdr *elf_section_table = (Elf64_Shdr *)((char*)file + elf_header->e_shoff); + Elf64_Half strtab_index = elf_header->e_shstrndx; + + Elf64_Shdr* strtable_header = (elf_section_table + strtab_index); + char *strings = (char*)file + (ptrdiff_t)strtable_header->sh_offset; + + Elf64_Half nheaders = elf_header->e_shnum; + for (int i = 0; i < nheaders; ++i) + { + if (elf_section_table[i].sh_type == SHT_NULL) + continue; + + Elf64_Off str_idx = elf_section_table[i].sh_name; + char *str = &strings[str_idx]; + + if (!strcmp(str, name)) + return elf_section_table[i].sh_addralign; + } + return -1; +} + +uint64_t get_offset_of_section(const void *file, const char *name) +{ + Elf64_Ehdr *elf_header = (Elf64_Ehdr *)file; + Elf64_Shdr *elf_section_table = (Elf64_Shdr *)((char*)file + elf_header->e_shoff); + Elf64_Half strtab_index = elf_header->e_shstrndx; + + Elf64_Shdr* strtable_header = (elf_section_table + strtab_index); + char *strings = (char*)file + (ptrdiff_t)strtable_header->sh_offset; + + Elf64_Half nheaders = elf_header->e_shnum; + for (int i = 0; i < nheaders; ++i) + { + if (elf_section_table[i].sh_type == SHT_NULL) + continue; + + Elf64_Off str_idx = elf_section_table[i].sh_name; + char *str = &strings[str_idx]; + + if (!strcmp(str, name)) + return elf_section_table[i].sh_offset; + } + return -1; +} + +void parse_section_names(const void *file, Elf64_Shdr* table, int n, int strtab_index) +{ + Elf64_Shdr* strtable = (table + strtab_index); + char *strings = (char*)file + (ptrdiff_t)strtable->sh_offset; + for (int i = 0; i < n; ++i) + { + if (table[i].sh_type == SHT_NULL || table[i].sh_type == SHT_SHLIB) + continue; + Elf64_Off str_idx = table[i].sh_name; + fprintf(stdout, "Section #%d: %s\n", i, &strings[str_idx]); + } +} + +void print_header(Elf64_Ehdr *header) +{ + fprintf(stdout, "ELF identification:\n"); + fprintf(stdout, "\tEL_MAG0: %#13x\n", header->e_ident[0]); + fprintf(stdout, "\tEL_MAG1: %10c\n", header->e_ident[1]); + fprintf(stdout, "\tEL_MAG2: %10c\n", header->e_ident[2]); + fprintf(stdout, "\tEL_MAG3: %10c\n", header->e_ident[3]); + fprintf(stdout, "\tEL_CLASS: %9d (ELFCLASS%d)\n", header->e_ident[4], header->e_ident[4] * 32); + fprintf(stdout, "\tEL_DATA: %10d (ELFDATA2%cSB)\n", header->e_ident[5], header->e_ident[5] == 1 ? 'L' : 'M'); + fprintf(stdout, "\tEL_VERSION: %7d (%s)\n", header->e_ident[6], header->e_ident[6] == 1 ? "EV_CURRENT" : "?"); + fprintf(stdout, "\tEL_OSABI: %9d (ELFOSABI_%s)\n", header->e_ident[7], header->e_ident[7] == 0 ? "SYSV" : header->e_ident[7] == 1 ? "HPUX" : "STANDALONE"); + fprintf(stdout, "\tEL_ABIVERSION: %4d\n", header->e_ident[8]); + fprintf(stdout, "\tEL_PAD: /* Padding bytes */\n"); + fprintf(stdout, "\tEL_NIDENT: %8d\n", header->e_ident[15]); + + fprintf(stdout, "Object file type: "); + +#define ET_CASE(name) case name: fprintf(stdout, "(" #name ")\n"); break + switch (header->e_type) + { + ET_CASE(ET_NONE); + ET_CASE(ET_REL); + ET_CASE(ET_EXEC); + ET_CASE(ET_DYN); + ET_CASE(ET_CORE); + ET_CASE(ET_LOOS); + ET_CASE(ET_HIOS); + ET_CASE(ET_LOPROC); + ET_CASE(ET_HIPROC); + } +#undef ET_CASE + + fprintf(stdout, "Machine type: %#x\n", header->e_machine); + fprintf(stdout, "Object file version: %d (%s)\n", header->e_version, header->e_version == 1 ? "EV_CURRENT" : "?"); + fprintf(stdout, "Entry point address: %#x:\n", header->e_entry); + fprintf(stdout, "Program header offset: %d:\n", header->e_phoff); + fprintf(stdout, "Section header offset: %d:\n", header->e_shoff); + fprintf(stdout, "Processor-specific flags: %#x\n", header->e_flags); + fprintf(stdout, "ELF header size: %d\n", header->e_ehsize); + fprintf(stdout, "Program header entry size: %d\n", header->e_phentsize); + fprintf(stdout, "# of program header entries: %d\n", header->e_phnum); + fprintf(stdout, "Size of section header entry: %d\n", header->e_shentsize); + fprintf(stdout, "# of section header entries: %d\n", header->e_shnum); + fprintf(stdout, "Section name string table index: %d\n", header->e_shstrndx); +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) + { + fprintf(stdout, "Usage: pesticide [ELF binary path]\n"); + return 1; + } + fprintf(stdout, "Trying to read %s\n", argv[1]); + int fd = open(argv[1], O_RDONLY); + if (fd < 0) + { + fprintf(stdout, "Error trying to read %s\n", argv[1]); + return 1; + } + struct stat st; + fstat(fd, &st); + fprintf(stdout, "MMapping %d bytes\n", st.st_size); + void *addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (addr == MAP_FAILED) + { + fprintf(stdout, "Error MMapping %s\n", argv[1]); + return 1; + } + + Elf64_Ehdr *elf_header = (Elf64_Ehdr *)addr; + print_header(elf_header); + + Elf64_Shdr *elf_section_table = (Elf64_Shdr *)((char*)addr + elf_header->e_shoff); + parse_section_names(addr, elf_section_table, elf_header->e_shnum, elf_header->e_shstrndx); + fprintf(stdout, "Offset of section .debug_aranges is %d\n", get_offset_of_section(addr, ".debug_aranges")); + fprintf(stdout, "Byte alignment of section .debug_aranges is %d\n", get_alignment_of_section(addr, ".debug_aranges")); + parse_aranges_section(addr, get_offset_of_section(addr, ".debug_aranges")); + parse_debuginfo_section(addr); +} diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..c05b263 --- /dev/null +++ b/notes.txt @@ -0,0 +1,4 @@ +What is the deal with DW_FORM_GNU_* and DW_FORM_LLVM_* values? They're obviously not on the DWARF5 spec +Same for DW_AT_APPLE_* +DW_AT_subscr_data, DW_AT_subscr_data, DW_AT_element_list, DW_AT_member, DW_AT_dwo_id, DW_AT_ghs_namespace_alias, DW_AT_ghs_rsm, DW_AT_ghs_frsm, DW_AT_ghs_frames, DW_AT_ghs_rso, DW_AT_ghs_subcpu, DW_AT_ghs_lbrace_line, DW_AT_sf_names, DW_AT_src_info, DW_AT_mac_info, DW_AT_src_coords, DW_AT_body_begin, DW_AT_body_end is not to be found on the PDF +DW_AT_bit_offset, DW_AT_macro_info, DW_TAG_mutable_type is deprecated