]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Move more checks to the new dependency infrastructure
authorPetr Machata <pmachata@redhat.com>
Tue, 20 Oct 2009 15:54:40 +0000 (17:54 +0200)
committerPetr Machata <pmachata@redhat.com>
Wed, 18 Aug 2010 12:55:11 +0000 (14:55 +0200)
src/Makefile.am
src/dwarflint-check_expected_trees.cc [new file with mode: 0644]
src/dwarflint-hl.cc [deleted file]

index 616d00ff8337fa0371926e6a6df03c7c6d770175..616df335cd4516108b084097512f90d130f200c3 100644 (file)
@@ -81,7 +81,7 @@ dwarfcmp_test_LDADD = $(dwarfcmp_LDADD)
 dwarflint_SOURCES = dwarfstrings.c \
                    dwarflint-main.cc dwarflint-main.hh dwarflint-misc.h \
                    dwarflint-low.c dwarflint-low.h \
-                   dwarflint-hl.cc dwarflint-expected-at.cc dwarflint-expected.hh \
+                   dwarflint-expected-at.cc dwarflint-expected.hh \
                    dwarflint-coverage.cc dwarflint-coverage.h \
                    dwarflint-readctx.c  dwarflint-readctx.h \
                    dwarflint-messages.cc dwarflint-messages.h \
@@ -91,7 +91,8 @@ dwarflint_SOURCES = dwarfstrings.c \
                    dwarflint-checks-low.cc dwarflint-checks-low.hh \
                    dwarflint-checks-high.hh \
                    dwarflint-check_matching_ranges.cc \
-                   dwarflint-check_range_out_of_scope.cc
+                   dwarflint-check_range_out_of_scope.cc \
+                   dwarflint-check_expected_trees.cc
 
 readelf_SOURCES = readelf.c dwarfstrings.c
 
diff --git a/src/dwarflint-check_expected_trees.cc b/src/dwarflint-check_expected_trees.cc
new file mode 100644 (file)
index 0000000..a43424a
--- /dev/null
@@ -0,0 +1,167 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "dwarflint-checks-high.hh"
+#include "dwarflint-expected.hh"
+#include "dwarfstrings.h"
+#include "../libdw/c++/dwarf-knowledge.cc"
+
+using elfutils::dwarf;
+
+namespace
+{
+  class check_expected_trees
+    : public highlevel_check<check_expected_trees>
+  {
+  public:
+    explicit check_expected_trees (dwarflint &lint);
+  };
+
+  reg<check_expected_trees> reg_check_expected_trees;
+
+  const expected_at_map expected_at;
+  //static const expected_children_map expected_children;
+
+  struct name_extractor {
+    int operator () (dwarf::attribute const &at) {
+      return at.first;
+    }
+  } extract_name;
+
+  std::ostream &
+  operator << (std::ostream &o, dwarf::value_space vs)
+  {
+    switch (vs)
+      {
+      case dwarf::VS_flag: return o << "flag";
+      case dwarf::VS_dwarf_constant: return o << "dwarf_constant";
+      case dwarf::VS_discr_list: return o << "discr_list";
+      case dwarf::VS_reference: return o << "reference";
+      case dwarf::VS_lineptr: return o << "lineptr";
+      case dwarf::VS_macptr: return o << "macptr";
+      case dwarf::VS_rangelistptr: return o << "rangelistptr";
+      case dwarf::VS_identifier: return o << "identifier";
+      case dwarf::VS_string: return o << "string";
+      case dwarf::VS_source_file: return o << "source_file";
+      case dwarf::VS_source_line: return o << "source_line";
+      case dwarf::VS_source_column: return o << "source_column";
+      case dwarf::VS_address: return o << "address";
+      case dwarf::VS_constant: return o << "constant";
+      case dwarf::VS_location: return o << "location";
+      };
+
+    abort ();
+  }
+}
+
+check_expected_trees::check_expected_trees (dwarflint &lint)
+  : highlevel_check<check_expected_trees> (lint)
+{
+  lint.check <check_debug_info> ();
+
+  try
+    {
+      struct
+      {
+       void operator () (dwarf::compile_unit const &cu,
+                         dwarf::debug_info_entry const &parent)
+       {
+         struct where where = WHERE (sec_info, NULL);
+         where_reset_1 (&where, cu.offset ());
+         where_reset_2 (&where, parent.offset ());
+
+         int parent_tag = parent.tag ();
+
+         // Set of attributes of this DIE.
+         std::set <int> attributes;
+         std::transform (parent.attributes ().begin (),
+                         parent.attributes ().end (),
+                         std::inserter (attributes, attributes.end ()),
+                         extract_name);
+
+         // Attributes that we expect at this DIE.
+         expected_set::expectation_map const &expect
+           = expected_at.map (parent_tag);
+
+         // Check missing attributes.
+         for (expected_set::expectation_map::const_iterator jt
+                = expect.begin (); jt != expect.end (); ++jt)
+           {
+             std::set <int>::iterator kt = attributes.find (jt->first);
+             if (kt == attributes.end ())
+               switch (jt->second)
+                 {
+                 case opt_required:
+                   wr_message (cat (mc_impact_4, mc_info), &where,
+                               ": %s lacks required attribute %s.\n",
+                               dwarf_tag_string (parent_tag),
+                               dwarf_attr_string (jt->first));
+                   break;
+
+                 case opt_expected:
+                   wr_message (cat (mc_impact_2, mc_info), &where,
+                               ": %s should contain attribute %s.\n",
+                               dwarf_tag_string (parent_tag),
+                               dwarf_attr_string (jt->first));
+                 case opt_optional:
+                   break;
+                 };
+           }
+
+         // Check present attributes for expected-ness, and validate value space.
+         for (dwarf::debug_info_entry::attributes_type::const_iterator jt
+                = parent.attributes ().begin (), jte = parent.attributes ().end ();
+              jt != jte; ++jt)
+           {
+             unsigned name = extract_name (*jt);
+
+             expected_set::expectation_map::const_iterator kt = expect.find (name);
+             if (kt == expect.end ())
+               wr_message (cat (mc_impact_3, mc_info), &where,
+                           ": DIE \"%s\" has attribute \"%s\", which is not expected.\n",
+                           dwarf_tag_string (parent_tag),
+                           dwarf_attr_string (name));
+             try
+               {
+                 unsigned exp_vs = expected_value_space (name, parent_tag);
+                 dwarf::value_space vs = (*jt).second.what_space ();
+                 if ((exp_vs & (1U << vs)) == 0)
+                   wr_message (cat (mc_impact_3, mc_info), &where,
+                               ": in DIE \"%s\", attribute \"%s\" has value of unexpected type \"%u\".\n",
+                               dwarf_tag_string (parent_tag),
+                               dwarf_attr_string (name),
+                               vs);
+               }
+             // XXX more specific class when <dwarf> has it
+             catch (...)
+               {
+                 wr_message (cat (mc_impact_4, mc_info, mc_error), &where,
+                             ": in DIE \"%s\", couldn't obtain type of attribute \"%s\".\n",
+                             dwarf_tag_string (parent_tag),
+                             dwarf_attr_string (name));
+               }
+           }
+
+         // Check children recursively.
+         dwarf::debug_info_entry::children_type const &children
+           = parent.children ();
+         for (dwarf::debug_info_entry::children_type::const_iterator
+                jt = children.begin (); jt != children.end (); ++jt)
+           (*this) (cu, *jt);
+       }
+      } recursively_validate;
+
+      class dwarf::compile_units const &cus = dw.compile_units ();
+      for (dwarf::compile_units::const_iterator it = cus.begin ();
+          it != cus.end (); ++it)
+       recursively_validate (*it, *it);
+    }
+  // XXX more specific class when <dwarf> has it
+  catch (std::runtime_error &exc)
+    {
+      throw check_base::failed
+       (std::string ("Error while checking expected trees: ")
+        + exc.what () + ".\n");
+    }
+}
diff --git a/src/dwarflint-hl.cc b/src/dwarflint-hl.cc
deleted file mode 100644 (file)
index 33cd885..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/* Pedantic checking of DWARF files.  High level checks.
-   Copyright (C) 2009 Red Hat, Inc.
-   This file is part of Red Hat elfutils.
-   Written by Petr Machata <pmachata@redhat.com>, 2009.
-
-   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
-   <http://www.openinventionnetwork.com>.  */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <iostream>
-#include <set>
-#include <algorithm>
-#include <cinttypes>
-#include <cstdarg>
-#include <cassert>
-#include <iterator>
-
-#include "dwarflint-low.h"
-#include "dwarflint-coverage.hh"
-#include "dwarflint-expected.hh"
-#include "dwarfstrings.h"
-#include "c++/dwarf"
-#include "../libdw/libdwP.h"
-#include "../libdw/c++/dwarf-knowledge.cc"
-
-using namespace elfutils;
-
-class hl_ctx
-{
-  Dwarf *handle;
-
-public:
-  dwarf dw;
-
-  hl_ctx (Elf *elf)
-    : handle (dwarf_begin_elf (elf, DWARF_C_READ, NULL))
-    , dw (handle)
-  {
-    // See if we can iterate compile units.  If not, this throws an
-    // exception that gets caught in the C wrapper below.
-    dw.compile_units ().begin ();
-  }
-
-  ~hl_ctx ()
-  {
-    dwarf_end (handle);
-  }
-};
-
-hl_ctx *
-hl_ctx_new (Elf *elf)
-{
-  try
-    {
-      return new hl_ctx (elf);
-    }
-  catch (std::runtime_error &exc)
-    {
-      wr_error (NULL, "Cannot initialize high-level checking: %s.\n",
-               exc.what ());
-      return NULL;
-    }
-}
-
-void
-hl_ctx_delete (hl_ctx *hlctx)
-{
-  delete hlctx;
-}
-
-static const expected_at_map expected_at;
-//static const expected_children_map expected_children;
-
-struct name_extractor {
-  int operator () (dwarf::attribute const &at) {
-    return at.first;
-  }
-} extract_name;
-
-std::ostream &
-operator << (std::ostream &o, dwarf::value_space vs)
-{
-  switch (vs)
-    {
-    case dwarf::VS_flag: return o << "flag";
-    case dwarf::VS_dwarf_constant: return o << "dwarf_constant";
-    case dwarf::VS_discr_list: return o << "discr_list";
-    case dwarf::VS_reference: return o << "reference";
-    case dwarf::VS_lineptr: return o << "lineptr";
-    case dwarf::VS_macptr: return o << "macptr";
-    case dwarf::VS_rangelistptr: return o << "rangelistptr";
-    case dwarf::VS_identifier: return o << "identifier";
-    case dwarf::VS_string: return o << "string";
-    case dwarf::VS_source_file: return o << "source_file";
-    case dwarf::VS_source_line: return o << "source_line";
-    case dwarf::VS_source_column: return o << "source_column";
-    case dwarf::VS_address: return o << "address";
-    case dwarf::VS_constant: return o << "constant";
-    case dwarf::VS_location: return o << "location";
-    };
-
-  abort ();
-}
-
-bool
-check_expected_trees (hl_ctx *hlctx)
-{
-  try
-    {
-      struct
-      {
-       void operator () (dwarf::compile_unit const &cu,
-                         dwarf::debug_info_entry const &parent)
-       {
-         struct where where = WHERE (sec_info, NULL);
-         where_reset_1 (&where, cu.offset ());
-         where_reset_2 (&where, parent.offset ());
-
-         int parent_tag = parent.tag ();
-
-         // Set of attributes of this DIE.
-         std::set <int> attributes;
-         std::transform (parent.attributes ().begin (),
-                         parent.attributes ().end (),
-                         std::inserter (attributes, attributes.end ()),
-                         extract_name);
-
-         // Attributes that we expect at this DIE.
-         expected_set::expectation_map const &expect
-           = expected_at.map (parent_tag);
-
-         // Check missing attributes.
-         for (expected_set::expectation_map::const_iterator jt
-                = expect.begin (); jt != expect.end (); ++jt)
-           {
-             std::set <int>::iterator kt = attributes.find (jt->first);
-             if (kt == attributes.end ())
-               switch (jt->second)
-                 {
-                 case opt_required:
-                   wr_message (cat (mc_impact_4, mc_info), &where,
-                               ": %s lacks required attribute %s.\n",
-                               dwarf_tag_string (parent_tag),
-                               dwarf_attr_string (jt->first));
-                   break;
-
-                 case opt_expected:
-                   wr_message (cat (mc_impact_2, mc_info), &where,
-                               ": %s should contain attribute %s.\n",
-                               dwarf_tag_string (parent_tag),
-                               dwarf_attr_string (jt->first));
-                 case opt_optional:
-                   break;
-                 };
-           }
-
-         // Check present attributes for expected-ness, and validate value space.
-         for (dwarf::debug_info_entry::attributes_type::const_iterator jt
-                = parent.attributes ().begin (), jte = parent.attributes ().end ();
-              jt != jte; ++jt)
-           {
-             unsigned name = extract_name (*jt);
-
-             expected_set::expectation_map::const_iterator kt = expect.find (name);
-             if (kt == expect.end ())
-               wr_message (cat (mc_impact_3, mc_info), &where,
-                           ": DIE \"%s\" has attribute \"%s\", which is not expected.\n",
-                           dwarf_tag_string (parent_tag),
-                           dwarf_attr_string (name));
-             try
-               {
-                 unsigned exp_vs = expected_value_space (name, parent_tag);
-                 dwarf::value_space vs = (*jt).second.what_space ();
-                 if ((exp_vs & (1U << vs)) == 0)
-                   wr_message (cat (mc_impact_3, mc_info), &where,
-                               ": in DIE \"%s\", attribute \"%s\" has value of unexpected type \"%u\".\n",
-                               dwarf_tag_string (parent_tag),
-                               dwarf_attr_string (name),
-                               vs);
-               }
-             // XXX more specific class when <dwarf> has it
-             catch (...)
-               {
-                 wr_message (cat (mc_impact_4, mc_info, mc_error), &where,
-                             ": in DIE \"%s\", couldn't obtain type of attribute \"%s\".\n",
-                             dwarf_tag_string (parent_tag),
-                             dwarf_attr_string (name));
-               }
-           }
-
-         // Check children recursively.
-         dwarf::debug_info_entry::children_type const &children
-           = parent.children ();
-         for (dwarf::debug_info_entry::children_type::const_iterator
-                jt = children.begin (); jt != children.end (); ++jt)
-           (*this) (cu, *jt);
-       }
-      } recursively_validate;
-
-      class dwarf::compile_units const &cus = hlctx->dw.compile_units ();
-      for (dwarf::compile_units::const_iterator it = cus.begin ();
-          it != cus.end (); ++it)
-       recursively_validate (*it, *it);
-      return true;
-    }
-  // XXX more specific class when <dwarf> has it
-  catch (std::runtime_error &exc)
-    {
-      wr_error (NULL, "Error while checking expected trees: %s.\n",
-               exc.what ());
-      return false;
-    }
-}