]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Move .debug_line checks to new infrastructure
authorPetr Machata <pmachata@redhat.com>
Wed, 21 Oct 2009 19:28:49 +0000 (21:28 +0200)
committerPetr Machata <pmachata@redhat.com>
Wed, 18 Aug 2010 12:55:12 +0000 (14:55 +0200)
src/dwarflint/checks-low.cc
src/dwarflint/checks-low.hh
src/dwarflint/checks.hh
src/dwarflint/low.c
src/dwarflint/low.h
src/dwarflint/main.cc

index 6e870ff2d87056c0919f1e860b096f500ba54a76..1f6ac8fb1451901ca529c7b4053f272962980bf2 100644 (file)
@@ -32,6 +32,7 @@
 #include <map>
 #include <sstream>
 #include <cstring>
+#include <cassert>
 
 struct secentry
 {
@@ -256,6 +257,13 @@ load_sections::load_sections (dwarflint &lint)
   elf_file_init (&file, lint.elf ());
 }
 
+load_sections::~load_sections ()
+{
+  if (file.ebl != NULL)
+    ebl_closebackend (file.ebl);
+  free (file.sec);
+}
+
 sec &
 section_base::get_sec_or_throw (section_id secid)
 {
@@ -310,8 +318,26 @@ check_debug_info::check_debug_info (dwarflint &lint)
 
   for (cu *cu = chain; cu != NULL; cu = cu->next)
     cus.push_back (*cu);
-  // cu_free (chain); xxx
-  cu_chain = chain;
+
+  // re-link CUs so that they form a chain again.  This is to
+  // interface with C-level code.  The last CU's next is null, so we
+  // don't have to re-link it.
+  cu *last = NULL;
+  for (std::vector<cu>::iterator it = cus.begin ();
+       it != cus.end (); ++it)
+    {
+      cu *cur = &*it;
+      if (last != NULL)
+       last->next = cur;
+      last = cur;
+    }
+  if (cus.size () > 0)
+    assert (cus.back ().next == NULL);
+}
+
+check_debug_info::~check_debug_info ()
+{
+  cu_free (&cus.back ());
 }
 
 check_debug_ranges::check_debug_ranges (dwarflint &lint)
@@ -320,7 +346,7 @@ check_debug_ranges::check_debug_ranges (dwarflint &lint)
 {
   if (!check_loc_or_range_structural (&_m_sec_ranges->file,
                                      &_m_sec_ranges->sect,
-                                     _m_cus->cu_chain,
+                                     &_m_cus->cus.front (),
                                      &_m_cus->cu_cov))
     throw check_base::failed (""); //xxx
 }
@@ -333,7 +359,8 @@ check_debug_aranges::check_debug_aranges (dwarflint &lint)
     = _m_cus->cu_cov.need_ranges ? NULL : &_m_cus->cu_cov.cov;
   if (!check_aranges_structural (&_m_sec_aranges->file,
                                 &_m_sec_aranges->sect,
-                                _m_cus->cu_chain, cov))
+                                &_m_cus->cus.front (),
+                                cov))
     throw check_base::failed (""); //xxx
 }
 
@@ -343,7 +370,8 @@ check_debug_loc::check_debug_loc (dwarflint &lint)
 {
   if (!check_loc_or_range_structural (&_m_sec_loc->file,
                                      &_m_sec_loc->sect,
-                                     _m_cus->cu_chain, NULL))
+                                     &_m_cus->cus.front (),
+                                     NULL))
     throw check_base::failed (""); //xxx
 }
 
@@ -363,7 +391,7 @@ namespace
     {
       if (!check_pub_structural (&_m_sec->file,
                                 &_m_sec->sect,
-                                _m_cus->cu_chain))
+                                &_m_cus->cus.front ()))
        throw check_base::failed (""); //xxx
     }
   };
@@ -371,3 +399,44 @@ namespace
   reg<check_debug_pub<sec_pubnames> > reg_debug_pubnames;
   reg<check_debug_pub<sec_pubtypes> > reg_debug_pubtypes;
 }
+
+namespace
+{
+  class check_debug_line
+    : public check<check_debug_line>
+  {
+    section<sec_line> *_m_sec;
+
+  public:
+    explicit check_debug_line (dwarflint &lint)
+      : _m_sec (lint.check (_m_sec))
+    {
+      addr_record line_tables;
+      WIPE (line_tables);
+      if (!check_line_structural (&_m_sec->file,
+                                 &_m_sec->sect,
+                                 &line_tables))
+       throw check_base::failed (""); //xxx
+
+      check_debug_info *info = NULL;
+      info = toplev_check (lint, info);
+      if (info != NULL)
+       for (std::vector<cu>::iterator it = info->cus.begin ();
+            it != info->cus.end (); ++it)
+         for (size_t i = 0; i < it->line_refs.size; ++i)
+           {
+             struct ref *ref = it->line_refs.refs + i;
+             if (!addr_record_has_addr (&line_tables, ref->addr))
+               {
+                 std::stringstream ss;
+                 ss << ": unresolved reference to .debug_line table "
+                    << "0x" << std::hex << ref->addr << ".";
+                 wr_error (&ref->who, "%s\n", ss.str ().c_str ());
+               }
+           }
+      addr_record_free (&line_tables);
+    }
+  };
+
+  reg<check_debug_line> reg_debug_line;
+}
index 0e5bddc4a8a024508886e3265cc63d66df9f3dbd..60b52bcb1aecf41f234b741f66bac107ee20791f 100644 (file)
@@ -7,6 +7,7 @@ class load_sections
 public:
   elf_file file;
   explicit load_sections (dwarflint &lint);
+  ~load_sections ();
 };
 
 class section_base
@@ -55,9 +56,9 @@ class check_debug_info
 public:
   cu_coverage cu_cov;
   std::vector<cu> cus;
-  cu *cu_chain; // xxx
 
   explicit check_debug_info (dwarflint &lint);
+  ~check_debug_info ();
 };
 static reg<check_debug_info> reg_debug_info;
 
index ba09504b9418fd09c4e03c8a531be57a5cb65102..e906e9fb2ec99074b93c39ff4f2a2f11318aee3e 100644 (file)
@@ -32,16 +32,18 @@ public:
 };
 
 template <class T>
-void
-toplev_check (dwarflint &lint)
+T *
+toplev_check (dwarflint &lint,
+             __attribute__ ((unused)) T *tag = NULL)
 {
   try
     {
-      lint.check<T> ();
+      return lint.check<T> ();
     }
   catch (check_base::failed const &f)
     {
       std::cout << f.what () << std::endl;
+      return NULL;
     }
 }
 
index e85e03540dc335c5dba3b914c23f335b6fa4d2aa..02a2ee11185c76e00cb79f8083496609011f705a 100644 (file)
@@ -3446,21 +3446,18 @@ read_rel (struct elf_file *file,
 bool
 check_line_structural (struct elf_file *file,
                       struct sec *sec,
-                      struct cu *cu_chain)
+                      struct addr_record *line_tables)
 {
   struct read_ctx ctx;
   read_ctx_init (&ctx, sec->data, file->other_byte_order);
   bool retval = true;
 
-  struct addr_record line_tables;
-  WIPE (line_tables);
-
   while (!read_ctx_eof (&ctx))
     {
       struct where where = WHERE (sec->id, NULL);
       uint64_t set_offset = read_ctx_get_offset (&ctx);
       where_reset_1 (&where, set_offset);
-      addr_record_add (&line_tables, set_offset);
+      addr_record_add (line_tables, set_offset);
       const unsigned char *set_begin = ctx.ptr;
 
       /* Size.  */
@@ -3932,19 +3929,7 @@ check_line_structural (struct elf_file *file,
     }
 
   if (retval)
-    {
-      relocation_skip_rest (sec);
-
-      for (struct cu *cu = cu_chain; cu != NULL; cu = cu->next)
-       for (size_t i = 0; i < cu->line_refs.size; ++i)
-         {
-           struct ref *ref = cu->line_refs.refs + i;
-           if (!addr_record_has_addr (&line_tables, ref->addr))
-             wr_error (&ref->who,
-                       ": unresolved reference to .debug_line table %#" PRIx64 ".\n",
-                       ref->addr);
-         }
-    }
+    relocation_skip_rest (sec);
 
   return retval;
 }
index a8b7539e036bdf21d29f897b5a1790fa931bcc60..5a0f2836ebe9d32db9af85595613befddcf4634b 100644 (file)
@@ -34,7 +34,6 @@
 #include "addr-record.h"
 
 #ifdef __cplusplus
-# include <string>
 extern "C"
 {
 #else
@@ -161,27 +160,10 @@ extern "C"
                                    struct cu *cu_chain);
   extern bool check_line_structural (struct elf_file *file,
                                     struct sec *sec,
-                                    struct cu *cu_chain);
+                                    struct addr_record *line_tables);
   extern void cu_free (struct cu *cu_chain);
 
 
-  void section_coverage_init (struct section_coverage *sco,
-                             struct sec *sec, bool warn);
-  bool coverage_map_init (struct coverage_map *coverage_map,
-                         struct elf_file *elf,
-                         Elf64_Xword mask,
-                         Elf64_Xword warn_mask,
-                         bool allow_overlap);
-  void coverage_map_add (struct coverage_map *coverage_map,
-                        uint64_t address, uint64_t length,
-                        struct where *where, enum message_category cat);
-  bool coverage_map_find_holes (struct coverage_map *coverage_map,
-                               bool (*cb) (uint64_t, uint64_t,
-                                           struct section_coverage *, void *),
-                               void *user);
-  void coverage_map_free (struct coverage_map *coverage_map);
-
-
   struct hole_info
   {
     enum section_id section;
index 4dfdaa157b6dcb66654d7935f3355571cf177c10..bc064916e51a98d313d9e2f040978daea4c465e2 100644 (file)
@@ -262,34 +262,6 @@ dwarflint::dwarflint (Elf *a_elf)
   : _m_elf (a_elf)
 {
   check_registrar::inst ()->enroll (*this);
-
-  struct elf_file file;
-  if (!elf_file_init (&file, a_elf))
-    return;
-
-  check_debug_info *check_info = check (check_info);
-  // xxx check_expected_trees
-  cu *cu_chain = check_info->cu_chain;
-
-#define SEC(sec) (file.debugsec[sec_##sec])
-#define HAS_SEC(sec) (SEC(sec) != NULL && SEC(sec)->data != NULL)
-
-  if (HAS_SEC(line))
-    check_line_structural (&file, SEC(line), cu_chain);
-  else if (!tolerate_nodebug)
-    {
-      where wh = WHERE (sec_line, NULL);
-      wr_message (mc_impact_4 | mc_acc_suboptimal | mc_elf | mc_loc,
-                 &wh, ": data not found.\n");
-    }
-
-  cu_free (cu_chain);
-  if (file.ebl != NULL)
-    ebl_closebackend (file.ebl);
-  free (file.sec);
-
-#undef SEC
-#undef HAS_SEC
 }
 
 int