]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Avoid some use of C interfaces
authorPetr Machata <pmachata@redhat.com>
Mon, 30 Nov 2009 07:19:48 +0000 (08:19 +0100)
committerPetr Machata <pmachata@redhat.com>
Wed, 18 Aug 2010 12:55:14 +0000 (14:55 +0200)
src/dwarflint/check_debug_info.cc
src/dwarflint/checks-low.hh

index 623dbc30af3bf8e97173dfa6da9c1bd37f65bfe3..dda8b5a131a0a04b41c61a5d7c397e56774ef66e 100644 (file)
@@ -954,11 +954,12 @@ namespace
 
     return got_die ? 1 : 0;
   }
+
   bool
   check_cu_structural (struct elf_file *file,
                       struct read_ctx *ctx,
                       struct cu *const cu,
-                      struct abbrev_table *abbrev_chain,
+                      check_debug_abbrev::abbrev_map &abbrev_tables,
                       Elf_Data *strings,
                       struct coverage *strings_coverage,
                       struct relocation_data *reloc,
@@ -972,30 +973,28 @@ namespace
     assert (ver != NULL);
 
     /* Look up Abbrev table for this CU.  */
-    struct abbrev_table *abbrevs = abbrev_chain;
-    for (; abbrevs != NULL; abbrevs = abbrevs->next)
-      if (abbrevs->offset == cu->head->abbrev_offset)
-       break;
-
-    if (abbrevs == NULL)
+    check_debug_abbrev::abbrev_map::iterator abbrev_it
+      = abbrev_tables.find (cu->head->abbrev_offset);
+    if (abbrev_it == abbrev_tables.end ())
       {
-       wr_error (&cu->head->where,
-                 ": couldn't find abbrev section with offset %" PRId64 ".\n",
-                 cu->head->abbrev_offset);
+       wr_error (cu->head->where)
+         << "couldn't find abbrev section with offset "
+         << pri::addr (cu->head->abbrev_offset) << '.' << std::endl;
        return false;
       }
+    struct abbrev_table &abbrevs = abbrev_it->second;
 
     /* Read DIEs.  */
     struct ref_record local_die_refs;
     WIPE (local_die_refs);
 
     cu->cudie_offset = read_ctx_get_offset (ctx) + cu->head->offset;
-    if (read_die_chain (ver, 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)
       {
-       abbrevs->skip_check = true;
+       abbrevs.skip_check = true;
        retval = false;
       }
     else if (!check_die_references (cu, &local_die_refs))
@@ -1004,149 +1003,148 @@ namespace
     ref_record_free (&local_die_refs);
     return retval;
   }
+}
 
-  struct cu *
-  check_info_structural (struct elf_file *file,
-                        struct sec *sec,
-                        struct abbrev_table *abbrev_chain,
-                        Elf_Data *strings,
-                        struct cu_coverage *cu_coverage,
-                        std::vector <cu_head> const &cu_headers)
-  {
-    struct ref_record die_refs;
-    WIPE (die_refs);
+read_cu_headers::read_cu_headers (dwarflint &lint)
+  : _m_sec_info (lint.check (_m_sec_info))
+  , cu_headers (read_info_headers (&_m_sec_info->file,
+                                  &_m_sec_info->sect,
+                                  _m_sec_info->reldata ()))
+{
+}
 
-    struct cu *cu_chain = NULL;
-    bool success = true;
+struct cu *
+check_debug_info::check_info_structural (struct elf_file *file,
+                                        struct sec *sec,
+                                        Elf_Data *strings)
+{
+  std::vector <cu_head> const &cu_headers = _m_cu_headers->cu_headers;
+  struct ref_record die_refs;
+  WIPE (die_refs);
 
-    struct coverage strings_coverage_mem, *strings_coverage = NULL;
-    if (strings != NULL && check_category (mc_strings))
-      {
-       WIPE (strings_coverage_mem);
-       strings_coverage = &strings_coverage_mem;
-      }
+  struct cu *cu_chain = NULL;
+  bool success = true;
 
-    struct relocation_data *reloc = sec->rel.size > 0 ? &sec->rel : NULL;
-    if (reloc != NULL)
-      relocation_reset (reloc);
+  struct coverage strings_coverage_mem, *strings_coverage = NULL;
+  if (strings != NULL && check_category (mc_strings))
+    {
+      WIPE (strings_coverage_mem);
+      strings_coverage = &strings_coverage_mem;
+    }
 
-    struct read_ctx ctx;
-    read_ctx_init (&ctx, sec->data, file->other_byte_order);
-    for (std::vector <cu_head>::const_iterator it = cu_headers.begin ();
-        it != cu_headers.end (); ++it)
-      {
-       cu_head const &head = *it;
-       where const &where = head.where;
-       struct cu *cur = (cu *)xcalloc (1, sizeof (*cur));
-       cur->head = &head;
-       cur->low_pc = (uint64_t)-1;
-       cur->next = cu_chain;
-       cu_chain = cur;
-
-       assert (read_ctx_need_data (&ctx, head.total_size));
-
-       // Make CU context begin just before the CU length, so that
-       // DIE offsets are computed correctly.
-       struct read_ctx cu_ctx;
-       const unsigned char *cu_end = ctx.ptr + head.total_size;
-       read_ctx_init_sub (&cu_ctx, &ctx, ctx.ptr, cu_end);
-       cu_ctx.ptr += head.head_size;
-
-       if (!check_cu_structural (file, &cu_ctx, cur, abbrev_chain,
-                                 strings, strings_coverage, reloc,
-                                 cu_coverage))
-         {
-           success = false;
-           break;
-         }
+  struct relocation_data *reloc = sec->rel.size > 0 ? &sec->rel : NULL;
+  if (reloc != NULL)
+    relocation_reset (reloc);
 
-       if (cu_ctx.ptr != cu_ctx.end
-           && !check_zero_padding (&cu_ctx, mc_info, &where))
-         {
-           // Garbage coordinates:
-           uint64_t start
-             = read_ctx_get_offset (&ctx) + read_ctx_get_offset (&cu_ctx);
-           uint64_t end = read_ctx_get_offset (&ctx) + head.total_size;
-           wr_message_padding_n0 (mc_info, &where, start, end);
-         }
+  struct read_ctx ctx;
+  read_ctx_init (&ctx, sec->data, file->other_byte_order);
+  for (std::vector <cu_head>::const_iterator it = cu_headers.begin ();
+       it != cu_headers.end (); ++it)
+    {
+      cu_head const &head = *it;
+      where const &where = head.where;
+      cu *cur = (cu *)xcalloc (1, sizeof (struct cu));
+      cur->head = &head;
+      cur->low_pc = (uint64_t)-1;
+      cur->next = cu_chain;
+      cu_chain = cur;
+
+      assert (read_ctx_need_data (&ctx, head.total_size));
+
+      // Make CU context begin just before the CU length, so that
+      // DIE offsets are computed correctly.
+      struct read_ctx cu_ctx;
+      const unsigned char *cu_end = ctx.ptr + head.total_size;
+      read_ctx_init_sub (&cu_ctx, &ctx, ctx.ptr, cu_end);
+      cu_ctx.ptr += head.head_size;
+
+      if (!check_cu_structural (file, &cu_ctx, cur, _m_abbrevs->abbrevs,
+                               strings, strings_coverage, reloc,
+                               &cu_cov))
+       {
+         success = false;
+         break;
+       }
 
-       int i = read_ctx_skip (&ctx, head.total_size);
-       assert (i);
-      }
+      if (cu_ctx.ptr != cu_ctx.end
+         && !check_zero_padding (&cu_ctx, mc_info, &where))
+       {
+         // Garbage coordinates:
+         uint64_t start
+           = read_ctx_get_offset (&ctx) + read_ctx_get_offset (&cu_ctx);
+         uint64_t end = read_ctx_get_offset (&ctx) + head.total_size;
+         wr_message_padding_n0 (mc_info, &where, start, end);
+       }
 
-    if (success)
-      {
-       if (ctx.ptr != ctx.end)
-         /* Did we read up everything?  */
-         {
-           where wh = WHERE (sec_info, NULL);
-           wr_message (cat (mc_die_other, mc_impact_4), &wh,
-                       ": CU lengths don't exactly match Elf_Data contents.");
-         }
-       else
-         /* Did we consume all the relocations?  */
-         relocation_skip_rest (&sec->rel, sec->id);
-
-       /* If we managed to read up everything, now do abbrev usage
-          analysis.  */
-       for (struct abbrev_table *abbrevs = abbrev_chain;
-            abbrevs != NULL; abbrevs = abbrevs->next)
-         if (abbrevs->used && !abbrevs->skip_check)
-           for (size_t i = 0; i < abbrevs->size; ++i)
-             if (!abbrevs->abbr[i].used)
-               wr_message (mc_impact_3 | mc_acc_bloat | mc_abbrevs,
-                           &abbrevs->abbr[i].where,
-                           ": abbreviation is never used.\n");
-      }
+      int i = read_ctx_skip (&ctx, head.total_size);
+      assert (i);
+    }
 
+  if (success)
+    {
+      if (ctx.ptr != ctx.end)
+       /* Did we read up everything?  */
+       {
+         where wh = WHERE (sec_info, NULL);
+         wr_message (cat (mc_die_other, mc_impact_4), &wh,
+                     ": CU lengths don't exactly match Elf_Data contents.");
+       }
+      else
+       /* Did we consume all the relocations?  */
+       relocation_skip_rest (&sec->rel, sec->id);
+
+      /* If we managed to read up everything, now do abbrev usage
+        analysis.  */
+      for (check_debug_abbrev::abbrev_map::const_iterator it
+            = _m_abbrevs->abbrevs.begin ();
+          it != _m_abbrevs->abbrevs.end (); ++it)
+       if (it->second.used && !it->second.skip_check)
+         for (size_t i = 0; i < it->second.size; ++i)
+           if (!it->second.abbr[i].used)
+             wr_message (it->second.abbr[i].where,
+                         cat (mc_impact_3, mc_acc_bloat, mc_abbrevs))
+               << ": abbreviation is never used." << std::endl;
+    }
 
-    /* We used to check that all CUs have the same address size.  Now
-       that we validate address_size of each CU against the ELF header,
-       that's not necessary anymore.  */
 
-    bool references_sound = check_global_die_references (cu_chain);
-    ref_record_free (&die_refs);
+  /* We used to check that all CUs have the same address size.  Now
+     that we validate address_size of each CU against the ELF header,
+     that's not necessary anymore.  */
 
-    if (strings_coverage != NULL)
-      {
-       if (success)
-         {
-           struct hole_info info = {sec_str, mc_strings, strings->d_buf, 0};
-           coverage_find_holes (strings_coverage, 0, strings->d_size,
-                                found_hole, &info);
-         }
-       coverage_free (strings_coverage);
-      }
+  bool references_sound = check_global_die_references (cu_chain);
+  ref_record_free (&die_refs);
 
-    if (!success || !references_sound)
-      {
-       cu_free (cu_chain);
-       cu_chain = NULL;
-      }
+  if (strings_coverage != NULL)
+    {
+      if (success)
+       {
+         struct hole_info info = {sec_str, mc_strings, strings->d_buf, 0};
+         coverage_find_holes (strings_coverage, 0, strings->d_size,
+                              found_hole, &info);
+       }
+      coverage_free (strings_coverage);
+    }
 
-    /* Reverse the chain, so that it's organized "naturally".  Has
-       significant impact on performance when handling loc_ref and
-       range_ref fields in loc/range validation.  */
-    struct cu *last = NULL;
-    for (struct cu *it = cu_chain; it != NULL; )
-      {
-       struct cu *next = it->next;
-       it->next = last;
-       last = it;
-       it = next;
-      }
-    cu_chain = last;
+  if (!success || !references_sound)
+    {
+      cu_free (cu_chain);
+      cu_chain = NULL;
+    }
 
-    return cu_chain;
-  }
-}
+  /* Reverse the chain, so that it's organized "naturally".  Has
+     significant impact on performance when handling loc_ref and
+     range_ref fields in loc/range validation.  */
+  struct cu *last = NULL;
+  for (struct cu *it = cu_chain; it != NULL; )
+    {
+      struct cu *next = it->next;
+      it->next = last;
+      last = it;
+      it = next;
+    }
+  cu_chain = last;
 
-read_cu_headers::read_cu_headers (dwarflint &lint)
-  : _m_sec_info (lint.check (_m_sec_info))
-  , cu_headers (read_info_headers (&_m_sec_info->file,
-                                  &_m_sec_info->sect,
-                                  _m_sec_info->reldata ()))
-{
+  return cu_chain;
 }
 
 check_debug_info::check_debug_info (dwarflint &lint)
@@ -1158,11 +1156,8 @@ check_debug_info::check_debug_info (dwarflint &lint)
 {
   memset (&cu_cov, 0, sizeof (cu_cov));
 
-  cu *chain = check_info_structural
-    (&_m_sec_info->file, &_m_sec_info->sect,
-     &_m_abbrevs->abbrevs.begin ()->second,
-     _m_sec_str->sect.data, &cu_cov,
-     _m_cu_headers->cu_headers);
+  cu *chain = check_info_structural (&_m_sec_info->file, &_m_sec_info->sect,
+                                    _m_sec_str->sect.data);
 
   if (chain == NULL)
     throw check_base::failed ();
index de65107659eb5a9f76f3f8de7a51e0258e6fc572..b6905d14dcdfbc3647f4fbfc1523a6647ab8de8b 100644 (file)
@@ -101,6 +101,10 @@ class check_debug_info
   check_debug_abbrev *_m_abbrevs;
   read_cu_headers *_m_cu_headers;
 
+  struct cu *check_info_structural (elf_file *file,
+                                   struct sec *sec,
+                                   Elf_Data *strings);
+
 public:
   // The check pass adds all low_pc/high_pc ranges loaded from DIE
   // tree into this following cu_cov structure.  If it finds any