From 6fa0e4217f126f137c1b9bd6b712c1703b64010a Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Fri, 13 Nov 2009 19:43:23 +0100 Subject: [PATCH] dwarflint: Work on support of multiple versions --- src/Makefile.am | 3 +- src/dwarflint/check_debug_abbrev.cc | 13 +- src/dwarflint/low.c | 49 +-- src/dwarflint/low.h | 4 +- src/dwarflint/tables.cc | 523 ++++++++++++++++++++++++++++ src/dwarflint/tables.h | 53 +++ src/dwarflint/tables.hh | 75 ++++ 7 files changed, 683 insertions(+), 37 deletions(-) create mode 100644 src/dwarflint/tables.cc create mode 100644 src/dwarflint/tables.h create mode 100644 src/dwarflint/tables.hh diff --git a/src/Makefile.am b/src/Makefile.am index 0de9cef56..3f498e30e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -85,7 +85,7 @@ dwarflint_SOURCES = dwarfstrings.c \ dwarflint/expected-at.cc dwarflint/expected.hh \ dwarflint/coverage.cc dwarflint/coverage.h \ dwarflint/readctx.c dwarflint/readctx.h \ - dwarflint/pri.cc dwarflint/pri.h \ + dwarflint/pri.cc dwarflint/pri.hh \ dwarflint/messages.cc dwarflint/messages.h \ dwarflint/where.c dwarflint/where.h \ dwarflint/config.cc dwarflint/config.h \ @@ -93,6 +93,7 @@ dwarflint_SOURCES = dwarfstrings.c \ dwarflint/checks-low.cc dwarflint/checks-low.hh \ dwarflint/addr-record.cc dwarflint/addr-record.h \ dwarflint/reloc.cc dwarflint/reloc.h \ + dwarflint/tables.cc dwarflint/tables.hh dwarflint/tables.h \ dwarflint/all-dies-it.hh \ dwarflint/checks-high.hh \ dwarflint/check_debug_abbrev.cc \ diff --git a/src/dwarflint/check_debug_abbrev.cc b/src/dwarflint/check_debug_abbrev.cc index d2256b861..cf61ea1c8 100644 --- a/src/dwarflint/check_debug_abbrev.cc +++ b/src/dwarflint/check_debug_abbrev.cc @@ -29,6 +29,7 @@ #include "checks-low.hh" #include "pri.hh" +#include "tables.hh" #include #include @@ -134,6 +135,13 @@ namespace check_debug_abbrev::check_debug_abbrev (dwarflint &lint) : _m_sec_abbr (lint.check (_m_sec_abbr)) { + // xxx Hmm, we need to know a dwarf version to consider which + // attributes are legal for DW_AT_sibling. But there's no way to + // get it, we need to parse abbrevs first to parse info. We could + // peek to info to get CU version/table offset mapping though, but + // for the time being, just take version 2. + dwarf_version_h ver = get_dwarf_version (2); + read_ctx ctx; read_ctx_init (&ctx, _m_sec_abbr->sect.data, _m_sec_abbr->file.other_byte_order); @@ -312,7 +320,7 @@ check_debug_abbrev::check_debug_abbrev (dwarflint &lint) throw check_base::failed (); } - if (!attrib_form_valid (attrib_form)) + if (!ver->form_allowed (attrib_form)) { wr_error (where) << "invalid form " << pri::hex (attrib_form) @@ -350,7 +358,7 @@ check_debug_abbrev::check_debug_abbrev (dwarflint &lint) << std::endl; } - switch (check_sibling_form (attrib_form)) + switch (check_sibling_form (ver, attrib_form)) { case -1: wr_message (where, cat (mc_die_rel, mc_impact_2)) @@ -425,3 +433,4 @@ check_debug_abbrev::check_debug_abbrev (dwarflint &lint) last = &it->second; } } + diff --git a/src/dwarflint/low.c b/src/dwarflint/low.c index a9907018f..2eea902db 100644 --- a/src/dwarflint/low.c +++ b/src/dwarflint/low.c @@ -48,6 +48,7 @@ #include "readctx.h" #include "config.h" #include "dwarf-opcodes.h" +#include "tables.h" /* True if coverage analysis of .debug_ranges vs. ELF sections should be done. */ @@ -169,33 +170,15 @@ read_ctx_read_form (struct read_ctx *ctx, struct cu *cu, uint8_t form, return false; } -bool -attrib_form_valid (uint64_t form) -{ - return form > 0 && form <= DW_FORM_ref_sig8; -} - int -check_sibling_form (uint64_t form) +check_sibling_form (dwarf_version_h ver, uint64_t form) { - switch (form) - { - case DW_FORM_indirect: - /* Tolerate this in abbrev loading, even during the DIE loading. - We check that dereferenced indirect form yields valid form. */ - case DW_FORM_ref1: - case DW_FORM_ref2: - case DW_FORM_ref4: - case DW_FORM_ref8: - case DW_FORM_ref_udata: - return 0; - - case DW_FORM_ref_addr: - return -1; - - default: - return -2; - }; + if (!dwver_form_allowed (ver, DW_AT_sibling, form)) + return -2; + else if (form == DW_FORM_ref_addr) + return -1; + else + return 0; } bool @@ -769,7 +752,8 @@ check_range_relocations (enum message_category cat, +1 in case some dies were actually loaded */ static int -read_die_chain (struct elf_file *file, +read_die_chain (dwarf_version_h ver, + struct elf_file *file, struct read_ctx *ctx, struct cu *cu, struct abbrev_table *abbrevs, @@ -885,7 +869,7 @@ read_die_chain (struct elf_file *file, "indirect attribute form")) return -1; - if (!attrib_form_valid (value)) + if (!dwver_form_valid (ver, form)) { wr_error (&where, ": invalid indirect form 0x%" PRIx64 ".\n", value); @@ -894,7 +878,7 @@ read_die_chain (struct elf_file *file, form = value; if (it->name == DW_AT_sibling) - switch (check_sibling_form (form)) + switch (check_sibling_form (ver, form)) { case -1: wr_message (mc_die_rel | mc_impact_2, &where, @@ -1335,7 +1319,7 @@ read_die_chain (struct elf_file *file, if (abbrev->has_children) { - int st = read_die_chain (file, ctx, cu, abbrevs, strings, + int st = read_die_chain (ver, file, ctx, cu, abbrevs, strings, local_die_refs, strings_coverage, reloc, cu_coverage); @@ -1409,9 +1393,10 @@ check_cu_structural (struct elf_file *file, wr_error (&cu->where, ": can't read version.\n"); return false; } - if (!supported_version (version, 2, &cu->where, 2, 3)) + dwarf_version_h ver = get_dwarf_version (version); + if (ver == NULL) return false; - if (version == 2 && cu->offset_size == 8) + if (version == 2 && cu->offset_size == 8) // xxx? /* Keep going. It's a standard violation, but we may still be able to read the unit under consideration and do high-level checks. */ @@ -1465,7 +1450,7 @@ check_cu_structural (struct elf_file *file, WIPE (local_die_refs); cu->cudie_offset = read_ctx_get_offset (ctx) + cu->offset; - if (read_die_chain (file, ctx, cu, abbrevs, strings, + if (read_die_chain (ver, file, ctx, cu, abbrevs, strings, &local_die_refs, strings_coverage, (reloc != NULL && reloc->size > 0) ? reloc : NULL, cu_coverage) < 0) diff --git a/src/dwarflint/low.h b/src/dwarflint/low.h index 9b8299c2c..35f7a3a99 100644 --- a/src/dwarflint/low.h +++ b/src/dwarflint/low.h @@ -33,6 +33,7 @@ #include "readctx.h" #include "addr-record.h" #include "reloc.h" +#include "tables.h" #ifdef __cplusplus extern "C" @@ -161,8 +162,7 @@ extern "C" struct addr_record *line_tables); extern void cu_free (struct cu *cu_chain); - extern bool attrib_form_valid (uint64_t form); - extern int check_sibling_form (uint64_t form); + extern int check_sibling_form (dwarf_version_h ver, uint64_t form); extern bool is_location_attrib (uint64_t name); struct hole_info diff --git a/src/dwarflint/tables.cc b/src/dwarflint/tables.cc new file mode 100644 index 000000000..67143f3a6 --- /dev/null +++ b/src/dwarflint/tables.cc @@ -0,0 +1,523 @@ +// The tables here capture attribute/allowed forms depending on DWARF +// version. Apart from standardized DWARF formats, e.g. DWARF3+GNU is +// a version in its own. + +#include "tables.hh" +#include "tables.h" +#include "../libdw/dwarf.h" + +#include +#include +#include + +namespace +{ + enum dw_class { + cl_address, + cl_block, + cl_constant, + cl_exprloc, + cl_flag, + cl_reference, + cl_string, + max_dw_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_set s; +#define ADD(V) if (V != max_dw_class) s[V] = true + ADD (a); + ADD (b); + ADD (c); + ADD (d); +#undef ADD + return s; + } + + struct dwarf_at_row { + attr at; + dw_class_set classes; + }; + + + + struct dwarf_form_row { + form f; + dw_class cls; + }; + + dwarf_at_row 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 ()} + }; + + dwarf_form_row dwarf_2_form_table[] = { + {DW_FORM_addr, cl_address}, + {DW_FORM_block2, cl_block}, + {DW_FORM_block4, cl_block}, + {DW_FORM_data2, cl_constant}, + {DW_FORM_data4, cl_constant}, + {DW_FORM_data8, cl_constant}, + {DW_FORM_string, cl_string}, + {DW_FORM_block, cl_block}, + {DW_FORM_block1, cl_block}, + {DW_FORM_data1, cl_constant}, + {DW_FORM_flag, cl_flag}, + {DW_FORM_sdata, cl_constant}, + {DW_FORM_strp, cl_string}, + {DW_FORM_udata, cl_constant}, + {DW_FORM_ref_addr, cl_reference}, + {DW_FORM_ref1, cl_reference}, + {DW_FORM_ref2, cl_reference}, + {DW_FORM_ref4, cl_reference}, + {DW_FORM_ref8, cl_reference}, + {DW_FORM_ref_udata, cl_reference}, + {0, max_dw_class} + }; + + class std_dwarf + : public dwarf_version + { + typedef std::map _forms_t; + _forms_t _forms; + form_set_t all_forms; + + public: + std_dwarf (dwarf_at_row attrtab[], dwarf_form_row formtab[]) + { + for (unsigned i = 0; attrtab[i].at != 0; ++i) + for (unsigned c = 0; c < attrtab[i].classes.size (); ++c) + if (attrtab[i].classes[c]) + for (unsigned j = 0; formtab[j].f != 0; ++j) + if (formtab[j].cls == static_cast (c)) + _forms[attrtab[i].at].insert (formtab[j].f); + + for (unsigned j = 0; formtab[j].f != 0; ++j) + all_forms.insert (formtab[j].f); + + /* + std::cout << pri::attr (attrtab[i].at) << " {"; + for (std::set ::const_iterator it = forms.begin (); + it != forms.end (); ++it) + std::cout << (it == forms.begin () ? "" : ", ") << pri::form (*it); + std::cout << "}" << std::endl; + */ + } + + form_set_t const &allowed_forms () const { return all_forms; } + + form_set_t const &allowed_forms (attr at) const + { + _forms_t::const_iterator it = _forms.find (at); + assert (it != _forms.end ()); + return it->second; + } + + // Answer forms allowed at DIE with that tag. + form_set_t const &allowed_forms (attr at, + __attribute__ ((unused)) die_tag tag) const + { + return allowed_forms (at); + } + }; + + std_dwarf dwarf2 (dwarf_2_at_table, dwarf_2_form_table); + std_dwarf dwarf3 (dwarf_2_at_table, dwarf_2_form_table); // xxx for now till we get real dw3 table +} + +dwarf_version_h +get_dwarf_version (unsigned version) +{ + switch (version) + { + case 2: return &dwarf2; + case 3: return &dwarf3; + default: return NULL; + }; +} + +bool +dwver_form_valid (dwarf_version const *ver, int form) +{ + return ver->form_allowed (form); +} + +bool +dwver_form_allowed (dwarf_version const *ver, int attr, int form) +{ + return ver->form_allowed (attr, form); +} + +bool +dwver_form_allowed_in (dwarf_version const *ver, int attr, int form, int tag) +{ + return ver->form_allowed (attr, form, tag); +} + +#if 0 + +.at (DW_AT_abstract_origin) +.version (dwarf_2, dwarf_3, dwarf_4).classes (reference) + +.ad (DW_AT_accessibility) +.version (dwarf_2, dwarf_3, dwarf_4).classes (constant) + +.at (DW_AT_allocated) +.version (dwarf_3).classes (constant, block, reference) +.version (dwarf_4).classes (constant, exprloc, reference) + +; + + +{DW_AT_abstract_origin, 0x31 2,3,4 reference + +DW_AT_accessibility 0x32 2,3,4 constant + +DW_AT_address_class 0x33 2,3,4 constant + + +// compositions of dwarf_version: +// - extend (A, B): allow union of A and B +// - strict (A, B): allow intersection of A and B + +// AT->class +DW_AT_abstract_origin 0x31 /*2,3,4*/reference + +DW_AT_accessibility 0x32 /*2,3,4*/constant + +DW_AT_address_class 0x33 /*2,3,4*/constant + +DW_AT_allocated 0x4e /*3*/constant,block,reference +DW_AT_allocated 0x4e /*4*/constant,exprloc,reference + +DW_AT_artificial 0x34 /*2,3,4*/flag + +DW_AT_associated 0x4f /*3*/block,constant,reference +DW_AT_associated 0x4f /*4*/constant,exprloc,reference + +DW_AT_base_types 0x35 /*2,3,4*/reference + +DW_AT_binary_scale 0x5b /*3,4*/constant + +DW_AT_bit_offset 0x0c /*2*/constant +DW_AT_bit_offset 0x0c /*3*/block,constant,reference +DW_AT_bit_offset 0x0c /*4*/constant,exprloc,reference + +DW_AT_bit_size 0x0d /*2*/constant +DW_AT_bit_size 0x0d /*3*/block,constant,reference +DW_AT_bit_size 0x0d /*4*/constant,exprloc,reference + +DW_AT_bit_stride 0x2e /*3*/constant +DW_AT_bit_stride 0x2e /*4*/constant,exprloc,reference + +DW_AT_byte_size 0x0b /*2*/constant +DW_AT_byte_size 0x0b /*3*/block,constant,reference +DW_AT_byte_size 0x0b /*4*/constant,exprloc,reference + +DW_AT_byte_stride 0x51 /*3*/block,constant,reference +DW_AT_byte_stride 0x51 /*4*/constant,exprloc,reference + +DW_AT_call_column 0x57 /*3,4*/constant + +DW_AT_call_file 0x58 /*3,4*/constant + +DW_AT_call_line 0x59 /*3,4*/constant + +DW_AT_calling_convention 0x36 /*2,3,4*/constant + +DW_AT_common_reference 0x1a /*2,3,4*/reference + +DW_AT_comp_dir 0x1b /*2,3,4*/string + +DW_AT_const_expr 0x6c /*4*/flag + +DW_AT_const_value 0x1c /*2*/string,constant,block +DW_AT_const_value 0x1c /*3*/block,constant,string +DW_AT_const_value 0x1c /*4*/block,constant,string + +DW_AT_containing_type 0x1d /*2,3,4*/reference + +DW_AT_count 0x37 /*2*/constant,reference +DW_AT_count 0x37 /*3*/block,constant,reference +DW_AT_count 0x37 /*4*/constant,exprloc,reference + +DW_AT_data_bit_offset 0x6b /*4*/constant + +DW_AT_data_location 0x50 /*3*/block +DW_AT_data_location 0x50 /*4*/exprloc + +DW_AT_data_member_location 0x38 /*2*/block,reference +DW_AT_data_member_location 0x38 /*3*/block,constant,loclistptr +DW_AT_data_member_location 0x38 /*4*/constant,exprloc,loclistptr + +DW_AT_decimal_scale 0x5c /*3,4*/constant + +DW_AT_decimal_sign 0x5e /*3,4*/constant + +DW_AT_decl_column 0x39 /*2,3,4*/constant + +DW_AT_decl_file 0x3a /*2,3,4*/constant + +DW_AT_decl_line 0x3b /*2,3,4*/constant + +DW_AT_declaration 0x3c /*2,3,4*/flag + +DW_AT_default_value 0x1e /*2,3,4*/reference + +DW_AT_description 0x5a /*3,4*/string + +DW_AT_digit_count 0x5f /*3,4*/constant + +DW_AT_discr 0x15 /*2,3,4*/reference + +DW_AT_discr_list 0x3d /*2,3,4*/block + +DW_AT_discr_value 0x16 /*2,3,4*/constant + +DW_AT_elemental 0x66 /*3,4*/flag + +DW_AT_encoding 0x3e /*2,3,4*/constant + +DW_AT_endianity 0x65 /*3,4*/constant + +DW_AT_entry_pc 0x52 /*3,4*/address + +DW_AT_explicit 0x63 /*3,4*/flag + +DW_AT_extension 0x54 /*3,4*/reference + +DW_AT_external 0x3f /*2,3,4*/flag + +DW_AT_frame_base 0x40 /*2*/block,constant +DW_AT_frame_base 0x40 /*3*/block,loclistptr +DW_AT_frame_base 0x40 /*4*/exprloc,loclistptr + +DW_AT_friend 0x41 /*2,3,4*/reference + +DW_AT_high_pc 0x12 /*2,3*/address +DW_AT_high_pc 0x12 /*4*/address,constant + +DW_AT_identifier_case 0x42 /*2,3,4*/constant + +DW_AT_import 0x18 /*2,3,4*/reference + +DW_AT_inline 0x20 /*2,3,4*/constant + +DW_AT_is_optional 0x21 /*2,3,4*/flag + +DW_AT_language 0x13 /*2,3,4*/constant + +DW_AT_location 0x02 /*2*/block,constant +DW_AT_location 0x02 /*3*/block,loclistptr +DW_AT_location 0x02 /*4*/exprloc,loclistptr + +DW_AT_low_pc 0x11 /*2,3,4*/address + +DW_AT_lower_bound 0x22 /*2*/constant,reference +DW_AT_lower_bound 0x22 /*3*/block,constant,reference +DW_AT_lower_bound 0x22 /*4*/constant,exprloc,reference + +DW_AT_macro_info 0x43 /*2*/constant +DW_AT_macro_info 0x43 /*3,4*/macptr + +DW_AT_main_subprogram 0x6a /*4*/flag + +DW_AT_mutable 0x61 /*3,4*/flag + +DW_AT_name 0x03 /*2,3,4*/string + +DW_AT_namelist_item 0x44 /*2,3*/block +DW_AT_namelist_item 0x44 /*4*/reference + +DW_AT_object_pointer 0x64 /*3,4*/reference + +DW_AT_ordering 0x09 /*2,3,4*/constant + +DW_AT_picture_string 0x60 /*3,4*/string + +DW_AT_priority 0x45 /*2,3,4*/reference + +DW_AT_producer 0x25 /*2,3,4*/string + +DW_AT_prototyped 0x27 /*2,3,4*/flag + +DW_AT_pure 0x67 /*3,4*/flag + +DW_AT_ranges 0x55 /*3,4*/rangelistptr + +DW_AT_recursive 0x68 /*3,4*/flag + +DW_AT_return_addr 0x2a /*2*/block,constant +DW_AT_return_addr 0x2a /*3*/block,loclistptr +DW_AT_return_addr 0x2a /*4*/exprloc,loclistptr + +DW_AT_segment 0x46 /*2*/block,constant +DW_AT_segment 0x46 /*3*/block,loclistptr +DW_AT_segment 0x46 /*4*/exprloc,loclistptr + +DW_AT_sibling 0x01 /*2,3,4*/reference + +DW_AT_signature 0x69 /*4*/reference + +DW_AT_small 0x5d /*3,4*/reference + +DW_AT_specification 0x47 /*2,3,4*/reference + +DW_AT_start_scope 0x2c /*2,3,4*/constant + +DW_AT_static_link 0x48 /*2*/block,constant +DW_AT_static_link 0x48 /*3*/block,loclistptr +DW_AT_static_link 0x48 /*4*/exprloc,loclistptr + +DW_AT_stmt_list 0x10 /*2*/constant +DW_AT_stmt_list 0x10 /*3,4*/lineptr + +DW_AT_stride_size 0x2e /*2*/constant + +DW_AT_string_length 0x19 /*2*/block,constant +DW_AT_string_length 0x19 /*3*/block,loclistptr +DW_AT_string_length 0x19 /*4*/exprloc,loclistptr + +DW_AT_threads_scaled 0x62 /*3,4*/flag + +DW_AT_trampoline 0x56 /*3,4*/address,flag,reference,string + +DW_AT_type 0x49 /*2,3,4*/reference + +DW_AT_upper_bound 0x2f /*2*/constant +DW_AT_upper_bound 0x2f /*3*/block,constant,reference +DW_AT_upper_bound 0x2f /*4*/constant,exprloc,reference + +DW_AT_use_UTF8 0x53 /*3,4*/flag + +DW_AT_use_location 0x4a /*2*/block,constant +DW_AT_use_location 0x4a /*3*/block,loclistptr +DW_AT_use_location 0x4a /*4*/exprloc,loclistptr + +DW_AT_variable_parameter 0x4b /*2,3,4*/flag + +DW_AT_virtuality 0x4c /*2,3,4*/constant + +DW_AT_visibility 0x17 /*2,3,4*/constant + +DW_AT_vtable_elem_location 0x4d /*2*/block,reference +DW_AT_vtable_elem_location 0x4d /*3*/block,loclistptr +DW_AT_vtable_elem_location 0x4d /*4*/exprloc,loclistptr + + +// FORM->class +DW_FORM_addr 0x01 /*2,3,4*/address + +DW_FORM_block 0x09 /*2,3,4*/block + +DW_FORM_block1 0x0a /*2,3,4*/block + +DW_FORM_block2 0x03 /*2,3,4*/block + +DW_FORM_block4 0x04 /*2,3,4*/block + +DW_FORM_data1 0x0b /*2,3,4*/constant + +DW_FORM_data2 0x05 /*2,3,4*/constant + +DW_FORM_data4 0x06 /*2,4*/constant +DW_FORM_data4 0x06 /*3*/constant, lineptr, loclistptr, macptr, rangelistptr + +DW_FORM_data8 0x07 /*2,4*/constant +DW_FORM_data8 0x07 /*3*/constant, lineptr, loclistptr, macptr, rangelistptr + +DW_FORM_exprloc 0x18 /*4*/exprloc + +DW_FORM_flag 0x0c /*2,3,4*/flag + +DW_FORM_flag_present 0x19 /*4*/flag + +DW_FORM_indirect 0x16 /*2,3,4*/- + +DW_FORM_ref1 0x11 /*2,3,4*/reference + +DW_FORM_ref2 0x12 /*2,3,4*/reference + +DW_FORM_ref4 0x13 /*2,3,4*/reference + +DW_FORM_ref8 0x14 /*2,3,4*/reference + +DW_FORM_ref_addr 0x10 /*2,3,4*/reference + +DW_FORM_ref_sig8 0x20 /*4*/reference + +DW_FORM_ref_udata 0x15 /*2,3,4*/reference + +DW_FORM_sdata 0x0d /*2,3,4*/constant + +DW_FORM_sec_offset 0x17 /*4*/lineptr, loclistptr, macptr, rangelistptr + +DW_FORM_string 0x08 /*2,3,4*/string + +DW_FORM_strp 0x0e /*2,3,4*/string + +DW_FORM_udata 0x0f /*2,3,4*/constant + +#endif diff --git a/src/dwarflint/tables.h b/src/dwarflint/tables.h new file mode 100644 index 000000000..f5f36bf3a --- /dev/null +++ b/src/dwarflint/tables.h @@ -0,0 +1,53 @@ +/* Dwarf version tables, C binding. + + Copyright (C) 2009 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + . */ + +#ifndef DWARFLINT_TABLES_H +#define DWARFLINT_TABLES_H + +#ifdef __cplusplus +extern "C" +{ +#else +# include +#endif + + struct dwarf_version; + typedef struct dwarf_version const *dwarf_version_h; + + dwarf_version_h get_dwarf_version (unsigned version) + __attribute__ ((pure)); + + bool dwver_form_valid (dwarf_version_h ver, int form); + + bool dwver_form_allowed (dwarf_version_h ver, int attr, int form); + + bool dwver_form_allowed_in (dwarf_version_h ver, int attr,int form, int tag); + +#ifdef __cplusplus +} +#endif + +#endif//DWARFLINT_TABLES_H diff --git a/src/dwarflint/tables.hh b/src/dwarflint/tables.hh new file mode 100644 index 000000000..16ee24dc2 --- /dev/null +++ b/src/dwarflint/tables.hh @@ -0,0 +1,75 @@ +/* Dwarf version tables. + + Copyright (C) 2009 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + . */ + +#ifndef DWARFLINT_TABLES_HH +#define DWARFLINT_TABLES_HH + +#include + +typedef int form; +typedef int attr; +typedef int die_tag; +class locexpr_op {}; + +class dwarf_version +{ +protected: + typedef std::set
form_set_t; + +private: + inline static bool find_form (form_set_t const &s, int f) + { + return s.find (f) != s.end (); + } + +public: + // Answer all known forms. + virtual form_set_t const &allowed_forms () const = 0; + + // Answer all forms allowed in theory for this attribute. + virtual form_set_t const &allowed_forms (attr at) const = 0; + + // Answer forms allowed for this attribute at DIE with that tag. + virtual form_set_t const &allowed_forms (attr at, die_tag tag) const = 0; + +public: + bool form_allowed (form f) const + { + return find_form (allowed_forms (), f); + } + + bool form_allowed (attr at, form f) const + { + return find_form (allowed_forms (at), f); + } + + bool form_allowed (attr at, form f, die_tag tag) const + { + return find_form (allowed_forms (at, tag), f); + } +}; + +#endif//DWARFLINT_TABLES_HH -- 2.47.3