|
|
|
@ -478,6 +478,62 @@ enum dwarf_expression_op {
@@ -478,6 +478,62 @@ enum dwarf_expression_op {
|
|
|
|
|
DW_OP_hi_user = 0xff |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
enum dwarf_cfa_op_base { |
|
|
|
|
DW_CFA_advance_loc = 0x1, |
|
|
|
|
DW_CFA_offset = 0x2, |
|
|
|
|
DW_CFA_restore = 0x3 |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
enum dwarf_cfa_op { |
|
|
|
|
DW_CFA_nop = 0x00, |
|
|
|
|
DW_CFA_set_loc = 0x01, |
|
|
|
|
DW_CFA_advance_loc1 = 0x02, |
|
|
|
|
DW_CFA_advance_loc2 = 0x03, |
|
|
|
|
DW_CFA_advance_loc4 = 0x04, |
|
|
|
|
DW_CFA_offset_extended = 0x05, |
|
|
|
|
DW_CFA_restore_extended = 0x06, |
|
|
|
|
DW_CFA_undefined = 0x07, |
|
|
|
|
DW_CFA_same_value = 0x08, |
|
|
|
|
DW_CFA_register = 0x09, |
|
|
|
|
DW_CFA_remember_state = 0x0a, |
|
|
|
|
DW_CFA_restore_state = 0x0b, |
|
|
|
|
DW_CFA_def_cfa = 0x0c, |
|
|
|
|
DW_CFA_def_cfa_register = 0x0d, |
|
|
|
|
DW_CFA_def_cfa_offset = 0x0e, |
|
|
|
|
DW_CFA_def_cfa_expression = 0x0f, |
|
|
|
|
DW_CFA_expression = 0x10, |
|
|
|
|
DW_CFA_offset_extended_sf = 0x11, |
|
|
|
|
DW_CFA_def_cfa_sf = 0x12, |
|
|
|
|
DW_CFA_def_cfa_offset_sf = 0x13, |
|
|
|
|
DW_CFA_val_offset = 0x14, |
|
|
|
|
DW_CFA_val_offset_sf = 0x15, |
|
|
|
|
DW_CFA_val_expression = 0x16, |
|
|
|
|
DW_CFA_lo_user = 0x1c, |
|
|
|
|
DW_CFA_hi_user = 0x3f, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
enum dwarf_cie_pointer_format { |
|
|
|
|
DW_EH_PE_absptr = 0x00, |
|
|
|
|
DW_EH_PE_uleb128 = 0x01, |
|
|
|
|
DW_EH_PE_udata2 = 0x02, |
|
|
|
|
DW_EH_PE_udata4 = 0x03, |
|
|
|
|
DW_EH_PE_udata8 = 0x04, |
|
|
|
|
DW_EH_PE_sleb128 = 0x09, |
|
|
|
|
DW_EH_PE_sdata2 = 0x0A, |
|
|
|
|
DW_EH_PE_sdata4 = 0x0B, |
|
|
|
|
DW_EH_PE_sdata8 = 0x0C, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
enum dwarf_cie_pointer_application { |
|
|
|
|
DW_EH_PE_pcrel = 0x10, |
|
|
|
|
DW_EH_PE_textrel = 0x20, |
|
|
|
|
DW_EH_PE_datarel = 0x30, |
|
|
|
|
DW_EH_PE_funcrel = 0x40, |
|
|
|
|
DW_EH_PE_aligned = 0x50, |
|
|
|
|
DW_EH_PE_indirect = 0x80, |
|
|
|
|
DW_EH_PE_omit = 0xFF, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
#pragma pack(1) |
|
|
|
|
struct elf_header_x64 { |
|
|
|
|
char magic[4]; |
|
|
|
@ -585,166 +641,28 @@ struct dwarf_line_number_state {
@@ -585,166 +641,28 @@ struct dwarf_line_number_state {
|
|
|
|
|
u32 discriminator; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct dwarf_cie_header { |
|
|
|
|
u32 length; |
|
|
|
|
u8 version; |
|
|
|
|
u32 code_alignment; |
|
|
|
|
s32 data_alignment; |
|
|
|
|
u32 return_address_register; |
|
|
|
|
u32 augmentation_data_length; |
|
|
|
|
u8 *augmentation_data; |
|
|
|
|
|
|
|
|
|
int has_z; |
|
|
|
|
|
|
|
|
|
enum dwarf_cie_pointer_format pointer_format; |
|
|
|
|
enum dwarf_cie_pointer_application pointer_application; |
|
|
|
|
u8 pointer_indirect; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static char * |
|
|
|
|
attribute_to_str(enum dwarf_die_tag attr) |
|
|
|
|
{ |
|
|
|
|
switch (attr) { |
|
|
|
|
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: { return "DW_AT_subscr_data"; } |
|
|
|
|
case DW_AT_byte_size: { return "DW_AT_byte_size"; } |
|
|
|
|
case DW_AT_bit_offset: { return "DW_AT_bit_offset"; } |
|
|
|
|
case DW_AT_bit_size: { return "DW_AT_bit_size"; } |
|
|
|
|
case DW_AT_element_list: { 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: { 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_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_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: { 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_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: { 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"; } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return(NULL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static char * |
|
|
|
|
tag_to_str(enum dwarf_die_tag tag) { |
|
|
|
|
switch (tag) { |
|
|
|
|
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"; } |
|
|
|
|
case DW_TAG_packed_type: { return "DW_TAG_packed_type"; } |
|
|
|
|
case DW_TAG_subprogram: { return "DW_TAG_subprogram"; } |
|
|
|
|
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_lo_user: { return "DW_TAG_lo_user"; } |
|
|
|
|
case DW_TAG_MIPS_loop: { return "DW_TAG_MIPS_loop"; } |
|
|
|
|
default: { return "unknown tag"; } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
assert(0); |
|
|
|
|
|
|
|
|
|
return(NULL); |
|
|
|
|
} |
|
|
|
|
struct dwarf_fde_header { |
|
|
|
|
u32 length; |
|
|
|
|
u64 optional_length; |
|
|
|
|
struct dwarf_cie_header *cie; |
|
|
|
|
u64 low_pc; |
|
|
|
|
u64 high_pc; |
|
|
|
|
u32 augmentation_data_length; |
|
|
|
|
u8 *augmentation_data; |
|
|
|
|
}; |