]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Publish cudie_locus, create arange_locus, drop where
authorPetr Machata <pmachata@redhat.com>
Tue, 19 Apr 2011 09:59:34 +0000 (11:59 +0200)
committerPetr Machata <pmachata@redhat.com>
Tue, 19 Apr 2011 09:59:34 +0000 (11:59 +0200)
dwarflint/check_debug_aranges.cc
dwarflint/check_debug_aranges.hh
dwarflint/check_matching_ranges.cc
dwarflint/where.cc
dwarflint/where.hh

index f1c441f220b9692e8e190f65e049e72e375cab38..b43f9bd746dce1d384e4884f08ed2892c092beb7 100644 (file)
 #include "misc.hh"
 #include "pri.hh"
 
+std::string
+arange_locus::format (bool brief) const
+{
+  std::stringstream ss;
+  if (!brief)
+    ss << section_name[sec_aranges] << ": ";
+
+  if (_m_arange_offset != (Dwarf_Off)-1)
+    ss << "arange 0x" << std::hex << _m_arange_offset;
+  else if (_m_table_offset != (Dwarf_Off)-1)
+    ss << "table " << std::dec << _m_table_offset;
+  else
+    ss << "arange";
+
+  if (_m_cudie_locus != NULL)
+    ss << " (" << _m_cudie_locus->format (true) << ')';
+
+  return ss.str ();
+}
+
 checkdescriptor const *
 check_debug_aranges::descriptor ()
 {
@@ -162,13 +182,13 @@ compare_coverage (struct elf_file *file,
 inline static void
 aranges_coverage_add (struct coverage *aranges_coverage,
                      uint64_t begin, uint64_t length,
-                     struct where *where)
+                     locus const &loc)
 {
   if (aranges_coverage->is_overlap (begin, length))
     {
       char buf[128];
       /* Not a show stopper, this shouldn't derail high-level.  */
-      wr_message (*where, mc_aranges | mc_impact_2 | mc_error)
+      wr_message (loc, mc_aranges | mc_impact_2 | mc_error)
        << "the range " << range_fmt (buf, sizeof buf, begin, begin + length)
        << " overlaps with another one." << std::endl;
     }
@@ -176,17 +196,6 @@ aranges_coverage_add (struct coverage *aranges_coverage,
   aranges_coverage->add (begin, length);
 }
 
-namespace
-{
-  struct cudie_locus_n {
-    static char const *name () { return "CU DIE"; }
-  };
-
-  typedef fixed_locus<sec_info,
-                     cudie_locus_n::name,
-                     locus_simple_fmt::dec> cudie_locus;
-}
-
 /* COVERAGE is portion of address space covered by CUs (either via
    low_pc/high_pc pairs, or via DW_AT_ranges references).  If
    non-NULL, analysis of arange coverage is done against that set. */
@@ -206,9 +215,7 @@ check_aranges_structural (struct elf_file *file,
 
   while (!read_ctx_eof (&ctx))
     {
-      section_id const sec_id = sec_aranges;
-      struct where where = WHERE (sec_id, NULL);
-      where_reset_1 (&where, read_ctx_get_offset (&ctx));
+      arange_locus where (read_ctx_get_offset (&ctx));
       const unsigned char *atab_begin = ctx.ptr;
 
       /* Size.  */
@@ -280,9 +287,9 @@ check_aranges_structural (struct elf_file *file,
        wr_error (&where, ": unresolved reference to " PRI_CU ".\n", cu_offset);
 
       cudie_locus cudie_loc (cu != NULL ? cu->cudie_offset : -1);
-      where.ref = &cudie_loc;
       if (cu != NULL)
        {
+         where.set_cudie (&cudie_loc);
          if (cu->has_arange)
            wr_error (where)
              << "there has already been arange section for this CU."
@@ -354,7 +361,7 @@ check_aranges_structural (struct elf_file *file,
             way, the better to catch structural errors accurately.
             So report arange offset instead.  If this becomes a
             problem, we will achieve this by two-pass analysis.  */
-         where_reset_2 (&where, read_ctx_get_offset (&sub_ctx));
+         where.set_arange (read_ctx_get_offset (&sub_ctx));
 
          /* Record address.  */
          uint64_t address;
@@ -397,13 +404,13 @@ check_aranges_structural (struct elf_file *file,
            wr_error (&where, ": zero-length address range.\n");
          /* Skip coverage analysis if we have errors.  */
          else if (retval && aranges_coverage != NULL)
-           aranges_coverage_add (aranges_coverage, address, length, &where);
+           aranges_coverage_add (aranges_coverage, address, length, where);
        }
 
       if (sub_ctx.ptr != sub_ctx.end)
        {
          uint64_t start, end;
-         section_locus wh (sec_id);
+         section_locus wh (sec_aranges);
          if (read_check_zero_padding (&sub_ctx, &start, &end))
            wr_message_padding_0 (mc_aranges, wh, start, end);
          else
index ea18350b9f5f3b4b94bc3c3d62af79ce221e51fd..5254d846123fc92d668028a176fa36b251904a19 100644 (file)
@@ -1,5 +1,5 @@
 /* Low-level checking of .debug_aranges.
-   Copyright (C) 2009, 2010 Red Hat, Inc.
+   Copyright (C) 2009, 2010, 2011 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
 #include "check_debug_info_i.hh"
 #include "cu_coverage_i.hh"
 
+struct cudie_locus_n {
+  static char const *name () { return "CU DIE"; }
+};
+
+class cudie_locus
+  : public fixed_locus<sec_info,
+                      cudie_locus_n::name,
+                      locus_simple_fmt::dec>
+{
+public:
+  template <class T>
+  cudie_locus (T const &die)
+    : fixed_locus<sec_info, cudie_locus_n::name,
+                 locus_simple_fmt::dec> (die.offset ())
+  {}
+
+  cudie_locus (Dwarf_Off offset)
+    : fixed_locus<sec_info, cudie_locus_n::name,
+                 locus_simple_fmt::dec> (offset)
+  {}
+};
+
+class arange_locus
+  : public clonable_locus<arange_locus>
+{
+  Dwarf_Off _m_table_offset;
+  Dwarf_Off _m_arange_offset;
+  locus const *_m_cudie_locus;
+
+public:
+  explicit arange_locus (Dwarf_Off table_offset = -1,
+                        Dwarf_Off arange_offset = -1)
+    : _m_table_offset (table_offset)
+    , _m_arange_offset (arange_offset)
+    , _m_cudie_locus (NULL)
+  {}
+
+  explicit arange_locus (locus const &cudie_locus)
+    : _m_table_offset (-1)
+    , _m_arange_offset (-1)
+    , _m_cudie_locus (&cudie_locus)
+  {}
+
+  void
+  set_cudie (locus const *cudie_locus)
+  {
+    _m_cudie_locus = cudie_locus;
+  }
+
+  void
+  set_arange (Dwarf_Off arange_offset)
+  {
+    _m_arange_offset = arange_offset;
+  }
+
+  std::string format (bool brief = false) const;
+};
+
 class check_debug_aranges
   : public check<check_debug_aranges>
 {
index 4e5a4389e80120d015fc8df9edc5b48f9147389d..12e2d06cb2fc0a936344d068f298ce7e85a5d54f 100644 (file)
@@ -62,17 +62,15 @@ check_matching_ranges::check_matching_ranges (checkstack &stack,
 
   try
     {
-      struct where where_ar = WHERE (sec_aranges, NULL);
       char buf[128];
-
       const dwarf::aranges_map &aranges = dw.aranges ();
       for (dwarf::aranges_map::const_iterator i = aranges.begin ();
           i != aranges.end (); ++i)
        {
          const dwarf::compile_unit &cu = i->first;
-         die_locus where_ref (cu);
-         where_ar.ref = &where_ref;
+         cudie_locus where_ref (cu);
          loc_range_locus where_r (sec_ranges, where_ref);
+         arange_locus where_ar (where_ref);
 
          std::set<dwarf::ranges::key_type>
            cu_aranges = i->second,
index daedc4e3040b90b9b263874353ca677bab88ced4..830a72dc274e86b78887ab2819c6c7cadd19c3f2 100644 (file)
 #include "where.hh"
 #include "section_id.hh"
 
-#include <cinttypes>
-#include <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <array>
-#include <sstream>
-
-class where::simple_formatter
-  : public where::formatter
-{
-  char const *_m_name;
-  char const *_m_fmt1;
-  char const *_m_fmt2;
-  char const *_m_fmt3;
-
-public:
-  simple_formatter (char const *name = NULL,
-                   char const *fmt1 = NULL,
-                   char const *fmt2 = NULL,
-                   char const *fmt3 = NULL)
-    : _m_name (name)
-    , _m_fmt1 (fmt1)
-    , _m_fmt2 (fmt2)
-    , _m_fmt3 (fmt3)
-  {}
-
-  virtual std::string
-  format (where const &wh, bool brief) const
-  {
-    std::string ret;
-
-    brief = brief || _m_name == NULL;
-    if (!brief)
-      ret += _m_name;
-
-    char const *const *formats = &_m_fmt1;
-    uint64_t const *addrs = &wh._m_addr1;
-
-    for (size_t i = 3; i > 0; --i)
-      {
-       size_t idx = i - 1;
-       if (addrs[idx] == (uint64_t)-1)
-         continue;
-
-       assert (formats[idx] != NULL);
-
-       /* GCC insists on checking format parameters and emits a warning
-          when we don't use string literal.  With -Werror this ends up
-          being hard error.  So instead we walk around this warning by
-          using function pointer.  */
-       int (*x_asprintf)(char **strp, const char *fmt, ...) = asprintf;
-
-       if (!brief)
-         ret += ": ";
-       char *buf;
-       if (x_asprintf (&buf, formats[idx], addrs[idx]) >= 0)
-         {
-           ret += buf;
-           free (buf);
-         }
-       else
-         ret += formats[idx];
-
-       break;
-      }
-
-    if (wh.ref != NULL)
-      {
-       ret += " (";
-       ret += wh.ref->format (true);
-       ret += ')';
-      }
-
-    return ret;
-  }
-};
-
-namespace
-{
-  template<size_t size>
-  class simple_formatters
-    : public std::array<where::simple_formatter, size>
-  {
-  protected:
-    void
-    add (section_id id, char const *name,
-        char const *addr1f = NULL,
-        char const *addr2f = NULL,
-        char const *addr3f = NULL)
-    {
-      (*this)[id] = where::simple_formatter (name, addr1f, addr2f, addr3f);
-    }
-  };
-
-  class section_formatters
-    : public simple_formatters<count_debuginfo_sections>
-  {
-  public:
-    section_formatters ()
-    {
-      add (sec_aranges, ".debug_aranges",
-          "table %"PRId64, "arange %#"PRIx64);
-
-      add (sec_mac, ".debug_mac");
-    }
-  } const section_fmts;
-}
-
-namespace
-{
-  where::formatter const *
-  wf_for_section (section_id sec)
-  {
-    return &section_fmts[sec];
-  }
-}
-
 std::string
 format_simple_locus (char const *(*N) (),
                     void (*F) (std::stringstream &, uint64_t),
@@ -163,70 +45,3 @@ format_simple_locus (char const *(*N) (),
     }
   return ss.str ();
 }
-
-where
-WHERE (section_id sec, locus const *next)
-{
-  assert (sec != sec_abbrev);
-  assert (sec != sec_str);
-  assert (sec != sec_info);
-  assert (sec != sec_loc);
-  assert (sec != sec_ranges);
-  assert (sec != sec_pubtypes);
-  assert (sec != sec_pubnames);
-  assert (sec != sec_line);
-  where::formatter const *fmt = wf_for_section (sec);
-  return where (fmt, next);
-}
-
-where::where (formatter const *fmt, locus const *nxt)
-  : _m_formatter (fmt)
-  , _m_addr1 ((uint64_t)-1)
-  , _m_addr2 ((uint64_t)-1)
-  , _m_addr3 ((uint64_t)-1)
-  , ref (NULL)
-  , _m_next (nxt)
-{
-}
-
-where &
-where::operator= (where const &copy)
-{
-  _m_formatter = copy._m_formatter;
-
-  _m_addr1 = copy._m_addr1;
-  _m_addr2 = copy._m_addr2;
-  _m_addr3 = copy._m_addr3;
-
-  ref = copy.ref;
-  _m_next = copy._m_next;
-
-  return *this;
-}
-
-std::string
-where::format (bool brief) const
-{
-  assert (_m_formatter != NULL);
-  return _m_formatter->format (*this, brief);
-}
-
-void
-where::reset_1 (uint64_t addr)
-{
-  _m_addr1 = addr;
-  _m_addr2 = _m_addr3 = (uint64_t)-1;
-}
-
-void
-where::reset_2 (uint64_t addr)
-{
-  _m_addr2 = addr;
-  _m_addr3 = (uint64_t)-1;
-}
-
-void
-where::reset_3 (uint64_t addr)
-{
-  _m_addr3 = addr;
-}
index 9198dc4955f44283809bb7b32177e8fa14c4652c..70d148780cdf8a945a37016ee290f03bd52352e1 100644 (file)
@@ -111,75 +111,6 @@ struct locus_simple_fmt {
 typedef simple_locus<locus_simple_fmt::offset,
                     locus_simple_fmt::hex> section_locus;
 
-struct where
-  : public clonable_locus<where>
-{
-  class formatter
-  {
-  public:
-    virtual ~formatter () {}
-    virtual std::string format (where const &wh, bool brief = false) const = 0;
-  };
-
-  class simple_formatter;
-
-private:
-  formatter const *_m_formatter;
-
-  uint64_t _m_addr1; // E.g. a CU offset.
-  uint64_t _m_addr2; // E.g. a DIE address.
-  uint64_t _m_addr3; // E.g. an attribute.
-
-public:
-  locus const *ref; // Related reference, e.g. an abbrev related to
-                   // given DIE.
-  locus const *_m_next; // For forming "caused-by" chains.
-
-  explicit where (formatter const *fmt = NULL,
-                 locus const *nxt = NULL);
-
-  where &operator= (where const &copy);
-
-  std::string format (bool brief = false) const;
-
-  locus const *
-  next () const
-  {
-    return _m_next;
-  }
-
-  void
-  set_next (locus const *nxt)
-  {
-    assert (_m_next == NULL);
-    _m_next = nxt;
-  }
-
-  void reset_1 (uint64_t addr);
-  void reset_2 (uint64_t addr);
-  void reset_3 (uint64_t addr);
-};
-
-inline void
-where_reset_1 (struct where *wh, uint64_t addr)
-{
-  wh->reset_1 (addr);
-}
-
-inline void
-where_reset_2 (struct where *wh, uint64_t addr)
-{
-  wh->reset_2 (addr);
-}
-
-inline void
-where_reset_3 (struct where *wh, uint64_t addr)
-{
-  wh->reset_3 (addr);
-}
-
-where WHERE (section_id sec, locus const *next = NULL);
-
 inline std::ostream &
 operator << (std::ostream &os, locus const &loc)
 {