From 4edcbd214746153f9591835260438949947d60b2 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Wed, 6 Oct 2010 15:52:07 +0200 Subject: [PATCH] dwarflint: Make a bunch of internal types related to dwarf_version public --- dwarflint/check_debug_abbrev.cc | 9 +- dwarflint/check_debug_info.cc | 11 +- dwarflint/tables.cc | 438 ++++++++++++++------------------ dwarflint/tables.hh | 99 ++++++-- 4 files changed, 285 insertions(+), 272 deletions(-) diff --git a/dwarflint/check_debug_abbrev.cc b/dwarflint/check_debug_abbrev.cc index e62445d23..3e0f4495d 100644 --- a/dwarflint/check_debug_abbrev.cc +++ b/dwarflint/check_debug_abbrev.cc @@ -415,18 +415,21 @@ namespace << "excessive DW_AT_sibling attribute at childless abbrev." << std::endl; - switch (ver->check_sibling_form (attrib_form)) + switch (sibling_form_suitable (ver, attrib_form)) { - case -1: + case sfs_long: wr_message (where, cat (mc_die_rel, mc_impact_2)) << "DW_AT_sibling attribute with form DW_FORM_ref_addr." << std::endl; break; - case -2: + case sfs_invalid: wr_error (where) << "DW_AT_sibling attribute with non-reference form " << pri::form (attrib_form) << '.' << std::endl; + + case sfs_ok: + ; }; } diff --git a/dwarflint/check_debug_info.cc b/dwarflint/check_debug_info.cc index a13eaf057..b91d4a889 100644 --- a/dwarflint/check_debug_info.cc +++ b/dwarflint/check_debug_info.cc @@ -643,19 +643,22 @@ namespace } if (it->name == DW_AT_sibling) - switch (ver->check_sibling_form (form)) + switch (sibling_form_suitable (ver, form)) { - case -1: + case sfs_long: wr_message (where, cat (mc_die_rel, mc_impact_2)) << "DW_AT_sibling attribute with (indirect) form " "DW_FORM_ref_addr." << std::endl; break; - case -2: + case sfs_invalid: wr_error (where) << "DW_AT_sibling attribute with non-reference " "(indirect) form \"" << pri::form (value) << "\"." << std::endl; + + case sfs_ok: + ; } } @@ -797,7 +800,7 @@ namespace } } - dwarf_version::form_width_t width = ver->form_width (form, cu); + form_width_t width = ver->form_width (form, cu); /* Setup per-form checking & relocation. */ switch (form) diff --git a/dwarflint/tables.cc b/dwarflint/tables.cc index 65016b8d3..0595fc89e 100644 --- a/dwarflint/tables.cc +++ b/dwarflint/tables.cc @@ -32,62 +32,20 @@ #include "../libdw/dwarf.h" #include -#include #include -namespace +dw_class_set::dw_class_set (dw_class a, dw_class b, dw_class c, + dw_class d, dw_class e) { - enum dw_class { - cl_address, - cl_block, - cl_constant, - cl_exprloc, - cl_flag, - cl_reference, - cl_string, - cl_loclistptr, - cl_lineptr, - cl_macptr, - cl_rangelistptr, - max_dw_class - }; - - enum storage_class_t { - sc_value, - sc_block, - sc_string, - max_storage_class - }; - - typedef std::bitset dw_class_set; - - dw_class_set dw_classes (dw_class a = max_dw_class, dw_class b = max_dw_class, - dw_class c = max_dw_class, dw_class d = max_dw_class, - dw_class e = max_dw_class) - { - dw_class_set s; -#define ADD(V) if (V != max_dw_class) s[V] = true - ADD (a); - ADD (b); - ADD (c); - ADD (d); - ADD (e); +#define ADD(V) if (V != max_dw_class) (*this)[V] = true + ADD (a); + ADD (b); + ADD (c); + ADD (d); + ADD (e); #undef ADD - return s; - } } -class form -{ -public: - virtual int name () const = 0; - virtual dw_class_set const &classes () const = 0; - virtual dwarf_version::form_width_t width (cu const *cu = NULL) const = 0; - //virtual storage_class_t storage_class () const = 0; - - virtual ~form () {} -}; - namespace { struct dwarf_row { @@ -122,12 +80,6 @@ namespace { else return NULL; } - - bool - has_form (int f) const - { - return get (f) != NULL; - } }; class basic_form @@ -159,16 +111,15 @@ namespace { : public basic_form { protected: - dwarf_version::form_width_t _m_width; + form_width_t _m_width; public: - fixed_form (int a_name, dw_class_set a_classes, - dwarf_version::form_width_t a_width) + fixed_form (int a_name, dw_class_set a_classes, form_width_t a_width) : basic_form (a_name, a_classes) , _m_width (a_width) {} - dwarf_version::form_width_t + form_width_t width (__attribute__ ((unused)) struct cu const *cu = NULL) const { return _m_width; @@ -176,14 +127,14 @@ namespace { }; struct width_off { - static dwarf_version::form_width_t width (struct cu const *cu) { - return static_cast (cu->head->offset_size); + static form_width_t width (struct cu const *cu) { + return static_cast (cu->head->offset_size); } }; struct width_addr { - static dwarf_version::form_width_t width (struct cu const *cu) { - return static_cast (cu->head->address_size); + static form_width_t width (struct cu const *cu) { + return static_cast (cu->head->address_size); } }; @@ -194,10 +145,10 @@ namespace { public: template selwidth_form (int a_name, Clss... a_classes) - : basic_form (a_name, dw_classes (a_classes...)) + : basic_form (a_name, dw_class_set (a_classes...)) {} - dwarf_version::form_width_t + form_width_t width (struct cu const *cu) const { return Sel::width (cu); @@ -212,8 +163,8 @@ namespace { : public fixed_form { public: - simple_form (int a_name, dwarf_version::form_width_t a_width) - : fixed_form (a_name, dw_classes (Clss...), a_width) + simple_form (int a_name, form_width_t a_width) + : fixed_form (a_name, dw_class_set (Clss...), a_width) {} }; @@ -223,91 +174,90 @@ namespace { typedef simple_form flag_form; dwarf_row const dwarf_2_at_table[] = { - {DW_AT_sibling, dw_classes (cl_reference)}, - {DW_AT_location, dw_classes (cl_block, cl_constant)}, - {DW_AT_name, dw_classes (cl_string)}, - {DW_AT_ordering, dw_classes (cl_constant)}, - {DW_AT_byte_size, dw_classes (cl_constant)}, - {DW_AT_bit_offset, dw_classes (cl_constant)}, - {DW_AT_bit_size, dw_classes (cl_constant)}, - {DW_AT_stmt_list, dw_classes (cl_constant)}, - {DW_AT_low_pc, dw_classes (cl_address)}, - {DW_AT_high_pc, dw_classes (cl_address)}, - {DW_AT_language, dw_classes (cl_constant)}, - {DW_AT_discr, dw_classes (cl_reference)}, - {DW_AT_discr_value, dw_classes (cl_constant)}, - {DW_AT_visibility, dw_classes (cl_constant)}, - {DW_AT_import, dw_classes (cl_reference)}, - {DW_AT_string_length, dw_classes (cl_block, cl_constant)}, - {DW_AT_common_reference, dw_classes (cl_reference)}, - {DW_AT_comp_dir, dw_classes (cl_string)}, - {DW_AT_const_value, dw_classes (cl_string, cl_constant, cl_block)}, - {DW_AT_containing_type, dw_classes (cl_reference)}, - {DW_AT_default_value, dw_classes (cl_reference)}, - {DW_AT_inline, dw_classes (cl_constant)}, - {DW_AT_is_optional, dw_classes (cl_flag)}, - {DW_AT_lower_bound, dw_classes (cl_constant, cl_reference)}, - {DW_AT_producer, dw_classes (cl_string)}, - {DW_AT_prototyped, dw_classes (cl_flag)}, - {DW_AT_return_addr, dw_classes (cl_block, cl_constant)}, - {DW_AT_start_scope, dw_classes (cl_constant)}, - {DW_AT_bit_stride, dw_classes (cl_constant)}, - {DW_AT_upper_bound, dw_classes (cl_constant, cl_reference)}, - {DW_AT_abstract_origin, dw_classes (cl_constant)}, - {DW_AT_accessibility, dw_classes (cl_reference)}, - {DW_AT_address_class, dw_classes (cl_constant)}, - {DW_AT_artificial, dw_classes (cl_flag)}, - {DW_AT_base_types, dw_classes (cl_reference)}, - {DW_AT_calling_convention, dw_classes (cl_constant)}, - {DW_AT_count, dw_classes (cl_constant, cl_reference)}, - {DW_AT_data_member_location, dw_classes (cl_block, cl_reference)}, - {DW_AT_decl_column, dw_classes (cl_constant)}, - {DW_AT_decl_file, dw_classes (cl_constant)}, - {DW_AT_decl_line, dw_classes (cl_constant)}, - {DW_AT_declaration, dw_classes (cl_flag)}, - {DW_AT_discr_list, dw_classes (cl_block)}, - {DW_AT_encoding, dw_classes (cl_constant)}, - {DW_AT_external, dw_classes (cl_flag)}, - {DW_AT_frame_base, dw_classes (cl_block, cl_constant)}, - {DW_AT_friend, dw_classes (cl_reference)}, - {DW_AT_identifier_case, dw_classes (cl_constant)}, - {DW_AT_macro_info, dw_classes (cl_constant)}, - {DW_AT_namelist_item, dw_classes (cl_block)}, - {DW_AT_priority, dw_classes (cl_reference)}, - {DW_AT_segment, dw_classes (cl_block, cl_constant)}, - {DW_AT_specification, dw_classes (cl_reference)}, - {DW_AT_static_link, dw_classes (cl_block, cl_constant)}, - {DW_AT_type, dw_classes (cl_reference)}, - {DW_AT_use_location, dw_classes (cl_block, cl_constant)}, - {DW_AT_variable_parameter, dw_classes (cl_flag)}, - {DW_AT_virtuality, dw_classes (cl_constant)}, - {DW_AT_vtable_elem_location, dw_classes (cl_block, cl_reference)}, - {0, dw_classes ()} + {DW_AT_sibling, dw_class_set (cl_reference)}, + {DW_AT_location, dw_class_set (cl_block, cl_constant)}, + {DW_AT_name, dw_class_set (cl_string)}, + {DW_AT_ordering, dw_class_set (cl_constant)}, + {DW_AT_byte_size, dw_class_set (cl_constant)}, + {DW_AT_bit_offset, dw_class_set (cl_constant)}, + {DW_AT_bit_size, dw_class_set (cl_constant)}, + {DW_AT_stmt_list, dw_class_set (cl_constant)}, + {DW_AT_low_pc, dw_class_set (cl_address)}, + {DW_AT_high_pc, dw_class_set (cl_address)}, + {DW_AT_language, dw_class_set (cl_constant)}, + {DW_AT_discr, dw_class_set (cl_reference)}, + {DW_AT_discr_value, dw_class_set (cl_constant)}, + {DW_AT_visibility, dw_class_set (cl_constant)}, + {DW_AT_import, dw_class_set (cl_reference)}, + {DW_AT_string_length, dw_class_set (cl_block, cl_constant)}, + {DW_AT_common_reference, dw_class_set (cl_reference)}, + {DW_AT_comp_dir, dw_class_set (cl_string)}, + {DW_AT_const_value, dw_class_set (cl_string, cl_constant, cl_block)}, + {DW_AT_containing_type, dw_class_set (cl_reference)}, + {DW_AT_default_value, dw_class_set (cl_reference)}, + {DW_AT_inline, dw_class_set (cl_constant)}, + {DW_AT_is_optional, dw_class_set (cl_flag)}, + {DW_AT_lower_bound, dw_class_set (cl_constant, cl_reference)}, + {DW_AT_producer, dw_class_set (cl_string)}, + {DW_AT_prototyped, dw_class_set (cl_flag)}, + {DW_AT_return_addr, dw_class_set (cl_block, cl_constant)}, + {DW_AT_start_scope, dw_class_set (cl_constant)}, + {DW_AT_bit_stride, dw_class_set (cl_constant)}, + {DW_AT_upper_bound, dw_class_set (cl_constant, cl_reference)}, + {DW_AT_abstract_origin, dw_class_set (cl_constant)}, + {DW_AT_accessibility, dw_class_set (cl_reference)}, + {DW_AT_address_class, dw_class_set (cl_constant)}, + {DW_AT_artificial, dw_class_set (cl_flag)}, + {DW_AT_base_types, dw_class_set (cl_reference)}, + {DW_AT_calling_convention, dw_class_set (cl_constant)}, + {DW_AT_count, dw_class_set (cl_constant, cl_reference)}, + {DW_AT_data_member_location, dw_class_set (cl_block, cl_reference)}, + {DW_AT_decl_column, dw_class_set (cl_constant)}, + {DW_AT_decl_file, dw_class_set (cl_constant)}, + {DW_AT_decl_line, dw_class_set (cl_constant)}, + {DW_AT_declaration, dw_class_set (cl_flag)}, + {DW_AT_discr_list, dw_class_set (cl_block)}, + {DW_AT_encoding, dw_class_set (cl_constant)}, + {DW_AT_external, dw_class_set (cl_flag)}, + {DW_AT_frame_base, dw_class_set (cl_block, cl_constant)}, + {DW_AT_friend, dw_class_set (cl_reference)}, + {DW_AT_identifier_case, dw_class_set (cl_constant)}, + {DW_AT_macro_info, dw_class_set (cl_constant)}, + {DW_AT_namelist_item, dw_class_set (cl_block)}, + {DW_AT_priority, dw_class_set (cl_reference)}, + {DW_AT_segment, dw_class_set (cl_block, cl_constant)}, + {DW_AT_specification, dw_class_set (cl_reference)}, + {DW_AT_static_link, dw_class_set (cl_block, cl_constant)}, + {DW_AT_type, dw_class_set (cl_reference)}, + {DW_AT_use_location, dw_class_set (cl_block, cl_constant)}, + {DW_AT_variable_parameter, dw_class_set (cl_flag)}, + {DW_AT_virtuality, dw_class_set (cl_constant)}, + {DW_AT_vtable_elem_location, dw_class_set (cl_block, cl_reference)}, + {0, dw_class_set ()} }; form const *dwarf_2_forms[] = { - new block_form (DW_FORM_block, dwarf_version::fw_leb), - new block_form (DW_FORM_block1, dwarf_version::fw_1), - new block_form (DW_FORM_block2, dwarf_version::fw_2), - new block_form (DW_FORM_block4, dwarf_version::fw_4), - - new const_form (DW_FORM_data1, dwarf_version::fw_1), - new const_form (DW_FORM_data2, dwarf_version::fw_2), - new const_form (DW_FORM_data4, dwarf_version::fw_4), - new const_form (DW_FORM_data8, dwarf_version::fw_8), - new const_form (DW_FORM_sdata, dwarf_version::fw_leb), - new const_form (DW_FORM_udata, dwarf_version::fw_leb), - - new flag_form (DW_FORM_flag, dwarf_version::fw_1), - - new ref_form (DW_FORM_ref1, dwarf_version::fw_1), - new ref_form (DW_FORM_ref2, dwarf_version::fw_2), - new ref_form (DW_FORM_ref4, dwarf_version::fw_4), - new ref_form (DW_FORM_ref8, dwarf_version::fw_8), - new ref_form (DW_FORM_ref_udata, dwarf_version::fw_leb), - - new fixed_form (DW_FORM_string, dw_classes (cl_string), - dwarf_version::fw_unknown), + new block_form (DW_FORM_block, fw_leb), + new block_form (DW_FORM_block1, fw_1), + new block_form (DW_FORM_block2, fw_2), + new block_form (DW_FORM_block4, fw_4), + + new const_form (DW_FORM_data1, fw_1), + new const_form (DW_FORM_data2, fw_2), + new const_form (DW_FORM_data4, fw_4), + new const_form (DW_FORM_data8, fw_8), + new const_form (DW_FORM_sdata, fw_leb), + new const_form (DW_FORM_udata, fw_leb), + + new flag_form (DW_FORM_flag, fw_1), + + new ref_form (DW_FORM_ref1, fw_1), + new ref_form (DW_FORM_ref2, fw_2), + new ref_form (DW_FORM_ref4, fw_4), + new ref_form (DW_FORM_ref8, fw_8), + new ref_form (DW_FORM_ref_udata, fw_leb), + + new fixed_form (DW_FORM_string, dw_class_set (cl_string), fw_unknown), new w_off_form (DW_FORM_strp, cl_string), new w_addr_form (DW_FORM_addr, cl_address), new w_addr_form (DW_FORM_ref_addr, cl_reference), @@ -317,105 +267,106 @@ namespace { /* Changes from dwarf_2_*_table: */ dwarf_row const dwarf_3_at_table[] = { - {DW_AT_location, dw_classes (cl_block, cl_loclistptr)}, - {DW_AT_byte_size, dw_classes (cl_block, cl_constant, cl_reference)}, - {DW_AT_bit_offset, dw_classes (cl_block, cl_constant, cl_reference)}, - {DW_AT_bit_size, dw_classes (cl_block, cl_constant, cl_reference)}, - {DW_AT_stmt_list, dw_classes (cl_lineptr)}, - {DW_AT_string_length, dw_classes (cl_block, cl_loclistptr)}, - {DW_AT_const_value, dw_classes (cl_block, cl_constant, cl_string)}, - {DW_AT_lower_bound, dw_classes (cl_block, cl_constant, cl_reference)}, - {DW_AT_return_addr, dw_classes (cl_block, cl_loclistptr)}, - {DW_AT_bit_stride, dw_classes (cl_constant)}, - {DW_AT_upper_bound, dw_classes (cl_block, cl_constant, cl_reference)}, - {DW_AT_count, dw_classes (cl_block, cl_constant, cl_reference)}, - {DW_AT_data_member_location, dw_classes (cl_block, cl_constant, + {DW_AT_location, dw_class_set (cl_block, cl_loclistptr)}, + {DW_AT_byte_size, dw_class_set (cl_block, cl_constant, cl_reference)}, + {DW_AT_bit_offset, dw_class_set (cl_block, cl_constant, cl_reference)}, + {DW_AT_bit_size, dw_class_set (cl_block, cl_constant, cl_reference)}, + {DW_AT_stmt_list, dw_class_set (cl_lineptr)}, + {DW_AT_string_length, dw_class_set (cl_block, cl_loclistptr)}, + {DW_AT_const_value, dw_class_set (cl_block, cl_constant, cl_string)}, + {DW_AT_lower_bound, dw_class_set (cl_block, cl_constant, cl_reference)}, + {DW_AT_return_addr, dw_class_set (cl_block, cl_loclistptr)}, + {DW_AT_bit_stride, dw_class_set (cl_constant)}, + {DW_AT_upper_bound, dw_class_set (cl_block, cl_constant, cl_reference)}, + {DW_AT_count, dw_class_set (cl_block, cl_constant, cl_reference)}, + {DW_AT_data_member_location, dw_class_set (cl_block, cl_constant, cl_loclistptr)}, - {DW_AT_frame_base, dw_classes (cl_block, cl_loclistptr)}, - {DW_AT_macro_info, dw_classes (cl_macptr)}, - {DW_AT_segment, dw_classes (cl_block, cl_loclistptr)}, - {DW_AT_static_link, dw_classes (cl_block, cl_loclistptr)}, - {DW_AT_use_location, dw_classes (cl_block, cl_loclistptr)}, - {DW_AT_vtable_elem_location, dw_classes (cl_block, cl_loclistptr)}, - {DW_AT_associated, dw_classes (cl_block, cl_constant, cl_reference)}, - {DW_AT_data_location, dw_classes (cl_block)}, - {DW_AT_byte_stride, dw_classes (cl_block, cl_constant, cl_reference)}, - {DW_AT_entry_pc, dw_classes (cl_address)}, - {DW_AT_use_UTF8, dw_classes (cl_flag)}, - {DW_AT_extension, dw_classes (cl_reference)}, - {DW_AT_ranges, dw_classes (cl_rangelistptr)}, - {DW_AT_trampoline, dw_classes (cl_address, cl_flag, cl_reference, + {DW_AT_frame_base, dw_class_set (cl_block, cl_loclistptr)}, + {DW_AT_macro_info, dw_class_set (cl_macptr)}, + {DW_AT_segment, dw_class_set (cl_block, cl_loclistptr)}, + {DW_AT_static_link, dw_class_set (cl_block, cl_loclistptr)}, + {DW_AT_use_location, dw_class_set (cl_block, cl_loclistptr)}, + {DW_AT_vtable_elem_location, dw_class_set (cl_block, cl_loclistptr)}, + {DW_AT_associated, dw_class_set (cl_block, cl_constant, cl_reference)}, + {DW_AT_data_location, dw_class_set (cl_block)}, + {DW_AT_byte_stride, dw_class_set (cl_block, cl_constant, cl_reference)}, + {DW_AT_entry_pc, dw_class_set (cl_address)}, + {DW_AT_use_UTF8, dw_class_set (cl_flag)}, + {DW_AT_extension, dw_class_set (cl_reference)}, + {DW_AT_ranges, dw_class_set (cl_rangelistptr)}, + {DW_AT_trampoline, dw_class_set (cl_address, cl_flag, cl_reference, cl_string)}, - {DW_AT_call_column, dw_classes (cl_constant)}, - {DW_AT_call_file, dw_classes (cl_constant)}, - {DW_AT_call_line, dw_classes (cl_constant)}, - {DW_AT_description, dw_classes (cl_string)}, - {DW_AT_binary_scale, dw_classes (cl_constant)}, - {DW_AT_decimal_scale, dw_classes (cl_constant)}, - {DW_AT_small, dw_classes (cl_reference)}, - {DW_AT_decimal_sign, dw_classes (cl_constant)}, - {DW_AT_digit_count, dw_classes (cl_constant)}, - {DW_AT_picture_string, dw_classes (cl_string)}, - {DW_AT_mutable, dw_classes (cl_flag)}, - {DW_AT_threads_scaled, dw_classes (cl_flag)}, - {DW_AT_explicit, dw_classes (cl_flag)}, - {DW_AT_object_pointer, dw_classes (cl_reference)}, - {DW_AT_endianity, dw_classes (cl_constant)}, - {DW_AT_elemental, dw_classes (cl_flag)}, - {DW_AT_pure, dw_classes (cl_flag)}, - {DW_AT_recursive, dw_classes (cl_flag)}, - {0, dw_classes ()} + {DW_AT_call_column, dw_class_set (cl_constant)}, + {DW_AT_call_file, dw_class_set (cl_constant)}, + {DW_AT_call_line, dw_class_set (cl_constant)}, + {DW_AT_description, dw_class_set (cl_string)}, + {DW_AT_binary_scale, dw_class_set (cl_constant)}, + {DW_AT_decimal_scale, dw_class_set (cl_constant)}, + {DW_AT_small, dw_class_set (cl_reference)}, + {DW_AT_decimal_sign, dw_class_set (cl_constant)}, + {DW_AT_digit_count, dw_class_set (cl_constant)}, + {DW_AT_picture_string, dw_class_set (cl_string)}, + {DW_AT_mutable, dw_class_set (cl_flag)}, + {DW_AT_threads_scaled, dw_class_set (cl_flag)}, + {DW_AT_explicit, dw_class_set (cl_flag)}, + {DW_AT_object_pointer, dw_class_set (cl_reference)}, + {DW_AT_endianity, dw_class_set (cl_constant)}, + {DW_AT_elemental, dw_class_set (cl_flag)}, + {DW_AT_pure, dw_class_set (cl_flag)}, + {DW_AT_recursive, dw_class_set (cl_flag)}, + {0, dw_class_set ()} }; typedef simple_form dw3_data_form; form const *dwarf_3_forms[] = { - new dw3_data_form (DW_FORM_data4, dwarf_version::fw_4), - new dw3_data_form (DW_FORM_data8, dwarf_version::fw_8), + new dw3_data_form (DW_FORM_data4, fw_4), + new dw3_data_form (DW_FORM_data8, fw_8), new w_off_form (DW_FORM_ref_addr, cl_reference), NULL }; /* Changes from dwarf_3_*_table: */ dwarf_row const dwarf_4_at_table[] = { - {DW_AT_location, dw_classes (cl_exprloc, cl_loclistptr)}, - {DW_AT_bit_offset, dw_classes (cl_constant, cl_exprloc, cl_reference)}, - {DW_AT_bit_size, dw_classes (cl_constant, cl_exprloc, cl_reference)}, - {DW_AT_high_pc, dw_classes (cl_address, cl_constant)}, - {DW_AT_string_length, dw_classes (cl_exprloc, cl_loclistptr)}, - {DW_AT_const_value, dw_classes (cl_block, cl_constant, cl_string)}, - {DW_AT_lower_bound, dw_classes (cl_constant, cl_exprloc, cl_reference)}, - {DW_AT_return_addr, dw_classes (cl_exprloc, cl_loclistptr)}, - {DW_AT_bit_stride, dw_classes (cl_constant, cl_exprloc, cl_reference)}, - {DW_AT_upper_bound, dw_classes (cl_constant, cl_exprloc, cl_reference)}, - {DW_AT_count, dw_classes (cl_constant, cl_exprloc, cl_reference)}, - {DW_AT_data_member_location, dw_classes (cl_constant, cl_exprloc, - cl_loclistptr)}, - {DW_AT_frame_base, dw_classes (cl_exprloc, cl_loclistptr)}, - {DW_AT_namelist_item, dw_classes (cl_reference)}, - {DW_AT_segment, dw_classes (cl_exprloc, cl_loclistptr)}, - {DW_AT_static_link, dw_classes (cl_exprloc, cl_loclistptr)}, - {DW_AT_use_location, dw_classes (cl_exprloc, cl_loclistptr)}, - {DW_AT_vtable_elem_location, dw_classes (cl_exprloc, cl_loclistptr)}, - {DW_AT_allocated, dw_classes (cl_constant, cl_exprloc, cl_reference)}, - {DW_AT_associated, dw_classes (cl_constant, cl_exprloc, cl_reference)}, - {DW_AT_data_location, dw_classes (cl_exprloc)}, - {DW_AT_byte_stride, dw_classes (cl_constant, cl_exprloc, cl_reference)}, - {DW_AT_signature, dw_classes (cl_reference)}, - {DW_AT_main_subprogram, dw_classes (cl_flag)}, - {DW_AT_data_bit_offset, dw_classes (cl_constant)}, - {DW_AT_const_expr, dw_classes (cl_flag)}, - {0, dw_classes ()} + {DW_AT_location, dw_class_set (cl_exprloc, cl_loclistptr)}, + {DW_AT_bit_offset, dw_class_set (cl_constant, cl_exprloc, cl_reference)}, + {DW_AT_bit_size, dw_class_set (cl_constant, cl_exprloc, cl_reference)}, + {DW_AT_high_pc, dw_class_set (cl_address, cl_constant)}, + {DW_AT_string_length, dw_class_set (cl_exprloc, cl_loclistptr)}, + {DW_AT_const_value, dw_class_set (cl_block, cl_constant, cl_string)}, + {DW_AT_lower_bound, dw_class_set (cl_constant, cl_exprloc, cl_reference)}, + {DW_AT_return_addr, dw_class_set (cl_exprloc, cl_loclistptr)}, + {DW_AT_bit_stride, dw_class_set (cl_constant, cl_exprloc, cl_reference)}, + {DW_AT_upper_bound, dw_class_set (cl_constant, cl_exprloc, cl_reference)}, + {DW_AT_count, dw_class_set (cl_constant, cl_exprloc, cl_reference)}, + {DW_AT_data_member_location, + dw_class_set (cl_constant, cl_exprloc, cl_loclistptr)}, + {DW_AT_frame_base, dw_class_set (cl_exprloc, cl_loclistptr)}, + {DW_AT_namelist_item, dw_class_set (cl_reference)}, + {DW_AT_segment, dw_class_set (cl_exprloc, cl_loclistptr)}, + {DW_AT_static_link, dw_class_set (cl_exprloc, cl_loclistptr)}, + {DW_AT_use_location, dw_class_set (cl_exprloc, cl_loclistptr)}, + {DW_AT_vtable_elem_location, + dw_class_set (cl_exprloc, cl_loclistptr)}, + {DW_AT_allocated, dw_class_set (cl_constant, cl_exprloc, cl_reference)}, + {DW_AT_associated, dw_class_set (cl_constant, cl_exprloc, cl_reference)}, + {DW_AT_data_location, dw_class_set (cl_exprloc)}, + {DW_AT_byte_stride, dw_class_set (cl_constant, cl_exprloc, cl_reference)}, + {DW_AT_signature, dw_class_set (cl_reference)}, + {DW_AT_main_subprogram, dw_class_set (cl_flag)}, + {DW_AT_data_bit_offset, dw_class_set (cl_constant)}, + {DW_AT_const_expr, dw_class_set (cl_flag)}, + {0, dw_class_set ()} }; form const *dwarf_4_forms[] = { - new const_form (DW_FORM_data4, dwarf_version::fw_4), - new const_form (DW_FORM_data8, dwarf_version::fw_8), + new const_form (DW_FORM_data4, fw_4), + new const_form (DW_FORM_data8, fw_8), new w_off_form (DW_FORM_sec_offset, cl_lineptr, cl_loclistptr, cl_macptr, cl_rangelistptr), - new simple_form (DW_FORM_exprloc, dwarf_version::fw_leb), - new flag_form (DW_FORM_flag_present, dwarf_version::fw_0), - new ref_form (DW_FORM_ref_sig8, dwarf_version::fw_8), + new simple_form (DW_FORM_exprloc, fw_leb), + new flag_form (DW_FORM_flag_present, fw_0), + new ref_form (DW_FORM_ref_sig8, fw_8), NULL }; @@ -462,13 +413,6 @@ namespace { return NULL; } - bool - form_allowed (int form) const - { - return _m_formtab.has_form (form) - || (_m_parent != NULL && _m_parent->form_allowed (form)); - } - dw_class_set const & get_attr_classes (int at) const { @@ -519,15 +463,21 @@ dwarf_version::get_latest () return get (4); } -int -dwarf_version::check_sibling_form (int form) const +sibling_form_suitable_t +sibling_form_suitable (dwarf_version const *ver, int form) { - if (!form_allowed (DW_AT_sibling, form)) - return -2; + if (!ver->form_allowed (DW_AT_sibling, form)) + return sfs_invalid; else if (form == DW_FORM_ref_addr) - return -1; + return sfs_long; else - return 0; + return sfs_ok; +} + +bool +dwarf_version::form_allowed (int form) const +{ + return get_form (form) != NULL; } #if 0 diff --git a/dwarflint/tables.hh b/dwarflint/tables.hh index 2fbabe83a..f78f83d2d 100644 --- a/dwarflint/tables.hh +++ b/dwarflint/tables.hh @@ -28,47 +28,104 @@ #define DWARFLINT_TABLES_HH #include +#include #include "check_debug_info.ii" typedef int die_tag; class locexpr_op {}; -class form; - -class dwarf_version +enum dw_class + { + cl_address, + cl_block, + cl_constant, + cl_exprloc, + cl_flag, + cl_reference, + cl_string, + cl_loclistptr, + cl_lineptr, + cl_macptr, + cl_rangelistptr, + max_dw_class + }; + +class dw_class_set + : public std::bitset { public: - enum form_width_t - { - fw_0 = 0, - fw_1 = 1, - fw_2 = 2, - fw_4 = 4, - fw_8 = 8, - fw_leb, - fw_unknown - }; - // Return width of data stored with given form. CU may be NULL if - // you are sure that the form size doesn't depend on addr_64 or off. - // Forms for which width makes no sense, such as DW_FORM_string, get - // fw_unknown. Unknown forms get an assert. - virtual form_width_t - form_width (int form, struct cu const *cu = NULL) const = 0; + dw_class_set (dw_class a = max_dw_class, dw_class b = max_dw_class, + dw_class c = max_dw_class, dw_class d = max_dw_class, + dw_class e = max_dw_class); +}; +enum form_width_t + { + fw_0 = 0, + fw_1 = 1, + fw_2 = 2, + fw_4 = 4, + fw_8 = 8, + fw_leb, + fw_unknown + }; + +enum storage_class_t + { + sc_value, + sc_block, + sc_string, + }; + +class form +{ public: - virtual bool form_allowed (int form) const = 0; + virtual int name () const = 0; + virtual dw_class_set const &classes () const = 0; + virtual form_width_t width (cu const *cu = NULL) const = 0; + //virtual storage_class_t storage_class () const = 0; + + virtual ~form () {} +}; +class dwarf_version +{ +public: + /// Return form object for given form name. Return NULL for unknown + /// forms. virtual form const *get_form (int form) const = 0; + /// Shortcut for get_form (form) != NULL. + bool form_allowed (int form) const; + + /// Figure out whether, in given DWARF version, given attribute is + /// allowed to have given form. virtual bool form_allowed (int attr, int form) const = 0; - int check_sibling_form (int form) const; + /// Return width of data stored with given form. CU may be NULL if + /// you are sure that the form size doesn't depend on addr_64 or + /// off. Forms for which width makes no sense, such as + /// DW_FORM_string, get fw_unknown. Unknown forms get an assert. + virtual form_width_t + form_width (int form, struct cu const *cu = NULL) const = 0; + /// Return dwarf_version object for given DWARF version. static dwarf_version const *get (unsigned version) __attribute__ ((pure)); + /// Return dwarf_version object for latest supported DWARF version. static dwarf_version const *get_latest () __attribute__ ((pure)); }; +/// Check that the form is suitable for the DW_AT_sibling attribute. +enum sibling_form_suitable_t + { + sfs_ok, ///< This form is OK for DW_AT_sibling + sfs_long, ///< Global reference form, unnecessary for DW_AT_sibling + sfs_invalid, ///< This form isn't allowed at DW_AT_sibling + }; +sibling_form_suitable_t sibling_form_suitable (dwarf_version const *ver, + int form); + #endif//DWARFLINT_TABLES_HH -- 2.47.2