]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Allow DW_AT_ranges with const form, as gnu version 2 extension.
authorMark Wielaard <mjw@redhat.com>
Wed, 30 Mar 2011 10:44:14 +0000 (12:44 +0200)
committerMark Wielaard <mjw@redhat.com>
Thu, 31 Mar 2011 10:55:20 +0000 (12:55 +0200)
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.

dwarflint/dwarf_gnu.cc
dwarflint/dwarf_gnu.hh
dwarflint/dwarf_version.cc

index b70a6d2d5dd4e59f495fa7d0df904155bf925d32..6fa50bef0e77fbd322fa6bf9314f4cc1683e908d 100644 (file)
@@ -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;
 }
index dde52f4f3c881070a45738fa5cd78f2544799e47..14ce31c0b96b5203699756bedd6a6e319cb2ee51 100644 (file)
@@ -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
index a74e1699b87c1f84ef34395b352a422510b52167..60021521da4034b4544e9fd1bcc0c621253cec8b 100644 (file)
@@ -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;
       }