diff options
author | Mark Wielaard <mjw@redhat.com> | 2011-03-30 12:44:14 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2011-03-31 12:55:20 +0200 |
commit | 71f19d6c7760055c12ae521f8e62124fc963252a (patch) | |
tree | 5647ee5d66286b683bd93222b68ea503b02fbab5 | |
parent | 01b2cde6b5d1839dcc73381ecb442f5ba8346674 (diff) | |
download | elfutils-71f19d6c7760055c12ae521f8e62124fc963252a.tar.gz |
dwarflint: Allow DW_AT_ranges with const form, as gnu version 2 extension.
Without -gstrict-dwarf gcc allows usage of attributes from
later versions. One strange case is DW_AT_ranges in version 2
since that version doesn't actually define a rangelistptr
class. This case is added in the form_allowed override for dwarf_gnu,
for version 2. In gnu mode form_allowed checks both variants, source
and extension, in no-gnu mode, only the latest is allowed.
-rw-r--r-- | dwarflint/dwarf_gnu.cc | 26 | ||||
-rw-r--r-- | dwarflint/dwarf_gnu.hh | 2 | ||||
-rw-r--r-- | dwarflint/dwarf_version.cc | 22 |
3 files changed, 39 insertions, 11 deletions
diff --git a/dwarflint/dwarf_gnu.cc b/dwarflint/dwarf_gnu.cc index b70a6d2d..6fa50bef 100644 --- a/dwarflint/dwarf_gnu.cc +++ b/dwarflint/dwarf_gnu.cc @@ -86,13 +86,27 @@ namespace struct dwarf_gnu_ext_t : public std_dwarf { - dwarf_gnu_ext_t () - : std_dwarf (dwarf_gnu_attributes (), form_table ()) - {} + unsigned _m_version; - virtual bool + dwarf_gnu_ext_t (unsigned version) + : std_dwarf (dwarf_gnu_attributes (), form_table ()), + _m_version (version) + { } + + bool form_allowed (attribute const *attr, form const *form) const { + // Without -gstrict-dwarf gcc allows usage of attributes from + // later versions. One strange case is DW_AT_ranges in version 2 + // since that version doesn't actually define a rangelistptr + // class. So we just allow data4 or data8 here. + if (_m_version == 2 && attr->name () == DW_AT_ranges) + { + form_width_t width = form->width (NULL); + return (form->classes ()[cl_constant] + && (width == fw_4 || width == fw_8)); + } + if (attr->name () == DW_AT_GNU_odr_signature) return form->classes ()[cl_constant] && form->width (NULL) == fw_8; else @@ -102,8 +116,8 @@ namespace } dwarf_version const * -dwarf_gnu_ext () +dwarf_gnu_ext (unsigned version) { - static dwarf_gnu_ext_t dw; + static dwarf_gnu_ext_t dw (version); return &dw; } diff --git a/dwarflint/dwarf_gnu.hh b/dwarflint/dwarf_gnu.hh index dde52f4f..14ce31c0 100644 --- a/dwarflint/dwarf_gnu.hh +++ b/dwarflint/dwarf_gnu.hh @@ -28,6 +28,6 @@ #include "dwarf_version.ii" -dwarf_version const *dwarf_gnu_ext (); +dwarf_version const *dwarf_gnu_ext (unsigned version); #endif//DWARFLINT_DWARF_GNU_HH diff --git a/dwarflint/dwarf_version.cc b/dwarflint/dwarf_version.cc index a74e1699..60021521 100644 --- a/dwarflint/dwarf_version.cc +++ b/dwarflint/dwarf_version.cc @@ -219,6 +219,18 @@ namespace ret = _m_source->ambiguous_class (form, attribute, candidates); return ret; } + + bool + form_allowed (attribute const *attr, form const *form) const + { + // In GNU mode any combination of new attribute/old form goes, + // in strict mode only the latest. + if (opt_nognu) + return _m_extension->form_allowed (attr, form); + else + return (_m_source->form_allowed (attr, form) + || _m_extension->form_allowed (attr, form)); + } }; } @@ -235,7 +247,7 @@ dwarf_version::extend (dwarf_version const *source, namespace { - dwarf_version const *get_ext () + dwarf_version const *get_ext (unsigned version) { // xxx The GNU toolchain commonly uses DW_AT_MIPS_linkage_name, // which is part of the MIPS extensions. So that's what we @@ -247,31 +259,33 @@ namespace if (opt_nognu) return dwarf_mips_ext (); else - return dwarf_version::extend (dwarf_mips_ext (), dwarf_gnu_ext ()); + return dwarf_version::extend (dwarf_mips_ext (), + dwarf_gnu_ext (version)); } } dwarf_version const * dwarf_version::get (unsigned version) { - static dwarf_version const *ext = get_ext (); - switch (version) { case 2: { + static dwarf_version const *ext = get_ext (2); static dwarf_version const *dw = extend (dwarf_2 (), ext); return dw; } case 3: { + static dwarf_version const *ext = get_ext (3); static dwarf_version const *dw = extend (dwarf_3 (), ext); return dw; } case 4: { + static dwarf_version const *ext = get_ext (4); static dwarf_version const *dw = extend (dwarf_4 (), ext); return dw; } |