]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Add cu_locus, die_locus, use throughout, drop to_where
authorPetr Machata <pmachata@redhat.com>
Mon, 18 Apr 2011 11:29:58 +0000 (13:29 +0200)
committerPetr Machata <pmachata@redhat.com>
Mon, 18 Apr 2011 11:29:58 +0000 (13:29 +0200)
32 files changed:
dwarflint/Makefile.am
dwarflint/check_debug_abbrev.cc
dwarflint/check_debug_aranges.cc
dwarflint/check_debug_info.cc
dwarflint/check_debug_info.hh
dwarflint/check_debug_line.cc
dwarflint/check_debug_loc_range.cc
dwarflint/check_debug_loc_range.hh
dwarflint/check_debug_pub.cc
dwarflint/check_die_decl_call.cc
dwarflint/check_die_line_info.cc
dwarflint/check_die_tree.cc
dwarflint/check_duplicate_DW_tag_variable.cc
dwarflint/check_dups_abstract_origin.cc
dwarflint/check_expected_trees.cc
dwarflint/check_linkage_external_die.cc
dwarflint/check_matching_ranges.cc
dwarflint/check_range_out_of_scope.cc
dwarflint/check_self_referential_die.cc
dwarflint/checked_read.cc
dwarflint/checked_read.hh
dwarflint/cu_coverage.cc
dwarflint/die_locus.cc [new file with mode: 0644]
dwarflint/die_locus.hh [new file with mode: 0644]
dwarflint/highlevel_check.hh
dwarflint/locstats.cc
dwarflint/lowlevel_checks.cc
dwarflint/pri.cc
dwarflint/pri.hh
dwarflint/reloc.cc
dwarflint/tests/run-bad.sh
dwarflint/where.cc

index 1fc154afe36395fa7f8a99edd8cee5e688caf93f..c8e5c833fa19dc45f452ad4de4a1db6fd2af02d5 100644 (file)
@@ -48,6 +48,7 @@ dwarflint_SOURCES = \
        checks.hh checks_i.hh \
        coverage.cc coverage.hh \
        cu_coverage.cc cu_coverage.hh cu_coverage_i.hh \
+       die_locus.cc die_locus.hh \
        dwarf_2.cc dwarf_2.hh \
        dwarf_3.cc dwarf_3.hh \
        dwarf_4.cc dwarf_4.hh \
@@ -95,6 +96,7 @@ dwarflint_SOURCES = \
 
 locstats_SOURCES = \
        locstats.cc \
+       die_locus.cc die_locus.hh \
        files.cc files.hh \
        option.cc option.hh option_i.hh \
        section_id.cc section_id.hh \
index 5e03116085ec3f3efdd66188eaa2931b83168690..c818462fc5e89da1d26a0b51fc67f1cf858a052b 100644 (file)
@@ -79,8 +79,7 @@ abbrev_attrib_locus::abbrev_attrib_locus (abbrev_attrib_locus const &copy)
 std::string
 abbrev_attrib_locus::name () const
 {
-  assert (_m_name != -1);
-  return elfutils::dwarf::attributes::name (_m_name);
+  return pri::attr_name (_m_name);
 }
 
 void
index d775608bed6b8cde83f069db0b70901fc435bb9e..032a295fd6ecf8d56fb1a6224abdc219ddfa4aa9 100644 (file)
@@ -210,7 +210,7 @@ check_aranges_structural (struct elf_file *file,
          wr_error (&where, ": can't read table length.\n");
          return false;
        }
-      if (!read_size_extra (&ctx, size32, &size, &offset_size, &where))
+      if (!read_size_extra (&ctx, size32, &size, &offset_size, where))
        return false;
 
       struct read_ctx sub_ctx;
@@ -306,7 +306,7 @@ check_aranges_structural (struct elf_file *file,
       /* Address size.  */
       int address_size;
       error_code err = read_address_size (&sub_ctx, file->addr_64,
-                                         &address_size, &where);
+                                         &address_size, where);
       if (err != err_ok)
        retval = false;
       if (err == err_fatal)
index 42227e5d1ef46ab9e0f559d1ad633e536acedb9f..5aff2b996ee5af4d8146a243063d7ea66b5e45a4 100644 (file)
@@ -175,13 +175,8 @@ namespace
     while (!read_ctx_eof (&ctx))
       {
        const unsigned char *cu_begin = ctx.ptr;
-       struct where where = WHERE (sec_info, NULL);
        uint64_t offset = read_ctx_get_offset (&ctx);
-       where_reset_1 (&where, offset);
-
-       cu_head head;
-       head.offset = offset;
-       head.where = where;
+       cu_head head (offset);
 
        /* Reading CU head is a bit tricky, because we don't know if
           we have run into (superfluous but allowed) zero padding
@@ -190,7 +185,7 @@ namespace
        if (!read_ctx_need_data (&ctx, 4)
            && read_check_zero_padding (&ctx, &off_start, &off_end))
          {
-           wr_message_padding_0 (mc_info | mc_header, where,
+           wr_message_padding_0 (mc_info | mc_header, head.where,
                                  off_start, off_end);
            break;
          }
@@ -203,25 +198,25 @@ namespace
        uint32_t size32;
        if (!read_ctx_read_4ubyte (&ctx, &size32))
          {
-           wr_error (where) << "can't read CU length." << std::endl;
+           wr_error (head.where) << "can't read CU length." << std::endl;
            throw check_base::failed ();
          }
        if (size32 == 0
            && read_check_zero_padding (&ctx, &off_start, &off_end))
          {
-           wr_message_padding_0 (mc_info | mc_header, where,
+           wr_message_padding_0 (mc_info | mc_header, head.where,
                                  off_start, off_end);
            break;
          }
 
        Dwarf_Off cu_size;
        if (!read_size_extra (&ctx, size32, &cu_size,
-                             &head.offset_size, &where))
+                             &head.offset_size, head.where))
          throw check_base::failed ();
 
        if (!read_ctx_need_data (&ctx, cu_size))
          {
-           wr_error (where)
+           wr_error (head.where)
              << "section doesn't have enough data to read CU of size "
              << cu_size << '.' << std::endl;
            throw check_base::failed ();
@@ -241,7 +236,7 @@ namespace
        if (dwarf_version::get (version) == NULL)
          {
            wr_error (head.where) << "unsupported CU version "
-                                 << version << '.' << std::endl;
+                            << version << '.' << std::endl;
            throw check_base::failed ();
          }
        if (version == 2 && head.offset_size == 8) // xxx?
@@ -276,7 +271,7 @@ namespace
 
        /* Address size.  */
        error_code err = read_address_size (&ctx, file->addr_64,
-                                           &head.address_size, &head.where);
+                                           &head.address_size, head.where);
        if (err == err_fatal)
          throw check_base::failed ();
        else if (err == err_nohl)
@@ -288,7 +283,7 @@ namespace
 
        if (!read_ctx_skip (&ctx, head.size))
          {
-           wr_error (where) << pri::not_enough ("next CU") << std::endl;
+           wr_error (head.where) << pri::not_enough ("next CU") << std::endl;
            throw check_base::failed ();
          }
 
@@ -395,7 +390,7 @@ namespace
   struct value_check_cb_ctx
   {
     struct read_ctx *const ctx;
-    struct where *const where;
+    locus const *where;
     struct cu *const cu;
     struct ref_record *local_die_refs;
     Elf_Data *strings;
@@ -545,12 +540,11 @@ namespace
     uint64_t sibling_addr = 0;
     uint64_t die_off, prev_die_off = 0;
     struct abbrev *abbrev = NULL;
-    struct where where = WHERE (sec_info, NULL);
     unsigned long die_count = 0;
     int retval = 0;
 
     struct value_check_cb_ctx cb_ctx = {
-      ctx, &where, cu,
+      ctx, NULL, cu,
       local_die_refs,
       strings, strings_coverage,
       pc_coverage,
@@ -560,20 +554,18 @@ namespace
 
     while (!read_ctx_eof (ctx))
       {
-       where = cu->head->where;
        die_off = read_ctx_get_offset (ctx);
        /* Shift reported DIE offset by CU offset, to match the way
           readelf reports DIEs.  */
-       where_reset_2 (&where, die_off + cu->head->offset);
+       die_locus where (cu->head->offset + die_off);
+       cb_ctx.where = &where;
 
        uint64_t abbr_code;
 
        if (!checked_read_uleb128 (ctx, &abbr_code, where, "abbrev code"))
          return -1;
 
-#define DEF_PREV_WHERE                                                 \
-       struct where prev_where = where;                                \
-       where_reset_2 (&prev_where, prev_die_off + cu->head->offset)
+#define DEF_PREV_WHERE die_locus prev_where (cu->head->offset + prev_die_off)
 
        /* Check sibling value advertised last time through the loop.  */
        if (sibling_addr != 0)
@@ -671,7 +663,7 @@ namespace
        for (struct abbrev_attrib *it = abbrev->attribs;
             it->name != 0 || it->form != 0; ++it)
          {
-           where.ref = &it->where;
+           where.set_attrib_name (it->name);
            int form_name = it->form;
 
            // In following, attribute may be NULL, but form never
@@ -863,7 +855,7 @@ namespace
                    // field?  See check_debug_loc_range::op_read_form
                    if (!check_location_expression
                        (ver, file, &block, cu,
-                        expr_start, reloc, value, &where))
+                        expr_start, reloc, value, where))
                      return -1;
                  }
                else
@@ -928,7 +920,7 @@ namespace
            if (valuep != NULL)
              *valuep = value;
          }
-       where.ref = NULL;
+       where.set_attrib_name (-1);
 
        if (high_pc != (uint64_t)-1 && low_pc != (uint64_t)-1
            && high_pc_relative)
@@ -960,7 +952,7 @@ namespace
            else
              {
                if (!high_pc_relative)
-                 check_range_relocations (mc_die_other, &where,
+                 check_range_relocations (where, mc_die_other,
                                           &file,
                                           low_pc_symbol, high_pc_symbol,
                                           "DW_AT_low_pc and DW_AT_high_pc");
@@ -973,8 +965,6 @@ namespace
              }
          }
 
-       where.ref = &abbrev->where;
-
        if (abbrev->has_children)
          {
            int st = read_die_chain (ver, file, ctx, cu, abbrevs, strings,
@@ -1004,7 +994,7 @@ namespace
       }
 
     if (sibling_addr != 0)
-      wr_error (where)
+      wr_error (die_locus (cu->head->offset + prev_die_off))
        << "this DIE should have had its sibling at " << pri::hex (sibling_addr)
        << ", but the DIE chain ended." << std::endl;
 
@@ -1103,7 +1093,7 @@ check_debug_info::check_debug_info (checkstack &stack, dwarflint &lint)
        it != cu_headers.end (); ++it)
     {
       cu_head const &head = *it;
-      where const &where = head.where;
+      cu_locus where = head.where;
       {
        cu cur;
        memset (&cur, 0, sizeof (cur));
@@ -1150,7 +1140,7 @@ check_debug_info::check_debug_info (checkstack &stack, dwarflint &lint)
 
   if (success)
     {
-      where wh = WHERE (sec_info, NULL);
+      section_locus wh (sec_info);
       if (ctx.ptr != ctx.end)
        /* Did we read up everything?  */
        wr_message (mc_die_other | mc_impact_4, &wh,
index b82b18f6c92dcc76bd3287e6108f1bf7754176db..ad139c3af6651201fe34652eb35d4688bd2ebaca 100644 (file)
 #include "check_debug_line_i.hh"
 #include "check_debug_aranges_i.hh"
 #include "sections_i.hh"
+#include "die_locus.hh"
 
 struct cu_head
 {
-  uint64_t offset;
+  Dwarf_Off offset;
   Dwarf_Off size;               // Size of this CU.
   Dwarf_Off head_size;          // Size from begin to 1st byte of CU.
   Dwarf_Off total_size;         // size + head_size
 
-  int offset_size;             // Offset size in this CU.
-  ::where where;                // Where this section was defined.
+  int offset_size;              // Offset size in this CU.
   Dwarf_Off abbrev_offset;      // Abbreviation section that this CU uses.
   int version;                  // CU version
   int address_size;             // Address size in bytes on the target machine.
 
-  cu_head ()
-    : offset (0)
+  cu_locus where;
+
+  explicit cu_head (Dwarf_Off a_offset)
+    : offset (a_offset)
     , size (0)
     , head_size (0)
     , total_size (0)
     , offset_size (0)
-    , where ()
     , abbrev_offset (0)
     , version (0)
     , address_size (0)
+    , where (a_offset)
   {}
 };
 
index cc059991567a3b97a66813643389a0fb0267c6a0..b6b8309f1af75abc6b2134e4cb4986eb869802ef 100644 (file)
    Network licensing program, please visit www.openinventionnetwork.com
    <http://www.openinventionnetwork.com>.  */
 
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 #include "check_debug_line.hh"
 #include "check_debug_info.hh"
 #include "sections.hh"
@@ -171,7 +175,7 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint)
          wr_error (where) << "can't read table length." << std::endl;
          throw check_base::failed ();
        }
-      if (!read_size_extra (&ctx, size32, &size, &offset_size, &where))
+      if (!read_size_extra (&ctx, size32, &size, &offset_size, where))
        throw check_base::failed ();
 
       struct read_ctx sub_ctx;
index 611f1aec1cd8388b36ecdd3ba665c056ac1a72cb..1c09bd8397919e2a34913b4237dec679c3afa993 100644 (file)
@@ -455,7 +455,7 @@ namespace
                  wr_message (cat | mc_impact_2 | mc_reloc, &where,
                              ": end of address range is relocated, but the beginning wasn't.\n");
                else
-                 check_range_relocations (cat, &where, file,
+                 check_range_relocations (where, cat, file,
                                           begin_symbol, end_symbol,
                                           "begin and end address");
              }
@@ -518,7 +518,7 @@ namespace
                /* location expression itself */
                uint64_t expr_start = read_ctx_get_offset (&ctx);
                if (!check_location_expression
-                   (ver, *file, &ctx, cu, expr_start, &sec->rel, len, &where))
+                   (ver, *file, &ctx, cu, expr_start, &sec->rel, len, where))
                  return false;
                uint64_t expr_end = read_ctx_get_offset (&ctx);
                if (!overlap
@@ -865,13 +865,13 @@ check_location_expression (dwarf_version const *ver,
                           uint64_t init_off,
                           struct relocation_data *reloc,
                           size_t length,
-                          struct where *wh)
+                          locus const &loc)
 {
   struct read_ctx ctx;
   if (!read_ctx_init_sub (&ctx, parent_ctx, parent_ctx->ptr,
                          parent_ctx->ptr + length))
     {
-      wr_error (wh, PRI_NOT_ENOUGH, "location expression");
+      wr_error (&loc, PRI_NOT_ENOUGH, "location expression");
       return false;
     }
 
@@ -881,7 +881,7 @@ check_location_expression (dwarf_version const *ver,
   while (!read_ctx_eof (&ctx))
     {
       uint64_t opcode_off = read_ctx_get_offset (&ctx) + init_off;
-      locexpr_locus where (opcode_off, wh);
+      locexpr_locus where (opcode_off, &loc);
       opaddrs.add (opcode_off);
 
       uint8_t opcode;
@@ -1004,8 +1004,8 @@ found_hole (uint64_t start, uint64_t length, void *data)
 }
 
 void
-check_range_relocations (enum message_category cat,
-                        struct where *where,
+check_range_relocations (locus const &loc,
+                        enum message_category cat,
                         struct elf_file const *file,
                         GElf_Sym *begin_symbol,
                         GElf_Sym *end_symbol,
@@ -1014,7 +1014,7 @@ check_range_relocations (enum message_category cat,
   if (begin_symbol != NULL
       && end_symbol != NULL
       && begin_symbol->st_shndx != end_symbol->st_shndx)
-    wr_message (cat | mc_impact_2 | mc_reloc, where,
+    wr_message (cat | mc_impact_2 | mc_reloc, &loc,
                ": %s relocated against different sections (%s and %s).\n",
                description,
                file->sec[begin_symbol->st_shndx].name,
index 442191e63dd6f049338a1ec86d245449cd845b0d..9e552a5affc706e858e519b56fd7fedc8d09f56b 100644 (file)
@@ -93,10 +93,10 @@ bool check_location_expression (dwarf_version const *ver,
                                uint64_t init_off,
                                struct relocation_data *reloc,
                                size_t length,
-                               struct where *wh);
+                               locus const &loc);
 
-void check_range_relocations (enum message_category cat,
-                             struct where *where,
+void check_range_relocations (locus const &loc,
+                             enum message_category cat,
                              struct elf_file const *file,
                              GElf_Sym *begin_symbol,
                              GElf_Sym *end_symbol,
index 4890a7cb551e1e20277a186cfc51d4e4a38f7371..4ce6999d4725752e9ebda205585a2e9894fefb75 100644 (file)
    Network licensing program, please visit www.openinventionnetwork.com
    <http://www.openinventionnetwork.com>.  */
 
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 #include "check_debug_pub.hh"
 #include "check_debug_info.hh"
 #include "sections.hh"
@@ -108,7 +112,7 @@ check_debug_pub<sec_id>::check_pub_structural ()
          wr_error (&where, ": can't read table length.\n");
          return false;
        }
-      if (!read_size_extra (&ctx, size32, &size, &offset_size, &where))
+      if (!read_size_extra (&ctx, size32, &size, &offset_size, where))
        return false;
 
       {
index 7bddad0d7ea6b9c6a893dc5d3d35a4b8ca6c2a51..05f4b726f54e572464fda1ef3350d78c8ba6d7cc 100644 (file)
@@ -64,19 +64,19 @@ namespace
        decl_file = attrs.find (DW_AT_decl_file);
 
       if (decl_column != attrs.end () && decl_line == attrs.end ())
-       wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+       wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
          .id (descriptor ())
          << elfutils::dwarf::tags::name (entry.tag ())
          << " has decl_column, but NOT decl_line" << std::endl;
 
       if (decl_line != attrs.end () && decl_file == attrs.end ())
-       wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+       wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
          .id (descriptor ())
          << elfutils::dwarf::tags::name (entry.tag ())
          << " has decl_line, but NOT decl_file" << std::endl;
 
       if (decl_file != attrs.end () && decl_line == attrs.end ())
-       wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+       wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
          .id (descriptor ())
          << elfutils::dwarf::tags::name (entry.tag ())
          << " has decl_file, but NOT decl_line" << std::endl;
@@ -90,19 +90,19 @@ namespace
        call_file = attrs.find (DW_AT_call_file);
 
       if (call_column != attrs.end () && call_line == attrs.end ())
-       wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+       wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
          .id (descriptor ())
          << elfutils::dwarf::tags::name (entry.tag ())
          << " has call_column, but NOT call_line" << std::endl;
 
       if (call_line != attrs.end () && call_file == attrs.end ())
-       wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+       wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
          .id (descriptor ())
          << elfutils::dwarf::tags::name (entry.tag ())
          << " has call_line, but NOT call_file" << std::endl;
 
       if (call_file != attrs.end () && call_line == attrs.end ())
-       wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+       wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
          .id (descriptor ())
          << elfutils::dwarf::tags::name (entry.tag ())
          << " has call_file, but NOT call_line" << std::endl;
index d30453216f85507de0463253c618c3c38b42a60d..4f19113a723354f70638c6600652a52f959202ff 100644 (file)
@@ -98,7 +98,7 @@ namespace
        }
 
       if (! found)
-       wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+       wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
          .id (descriptor ())
          << elfutils::dwarf::tags::name (entry.tag ())
          << " " << dwarf::attributes::name (pc.first) << "=0x"
index 0e0b38d499a57cd23fa472f346ad61d9e8584959..5aeea9eb53bb66eef67fbee9011a7094f65515d6 100644 (file)
@@ -97,7 +97,7 @@ public:
        r += reason;
       }
 
-    wr_error (to_where (*a_d_it))
+    wr_error (die_locus (*a_d_it))
       << "A check failed: " << (_m_cd->name () ?: "(nil)")
       << r << std::endl;
   }
index 838e3f69340e0a6ea247d1bcd119bbf66dc4a774..f916ac0377dbdda5b5f4577b03360f27e2706e22 100644 (file)
@@ -108,14 +108,14 @@ namespace
                  varinfo &i = old->second;
                  if ((declaration && i.decl != children.end ())
                      || (!declaration && i.def != children.end ()))
-                   wr_message (to_where (*jt), mc_impact_3 | mc_die_other)
+                   wr_message (die_locus (*jt), mc_impact_3 | mc_die_other)
                      .id (descriptor ())
                      << "Re" << (declaration ? "declaration" : "definition")
                      << " of variable '" << name << "', originally seen at "
                      << pri::ref (declaration ? *i.decl : *i.def)
                      << '.' << std::endl;
                  else
-                   wr_message (to_where (*jt), mc_impact_3 | mc_die_other)
+                   wr_message (die_locus (*jt), mc_impact_3 | mc_die_other)
                      .id (descriptor ())
                      << "Found "
                      << (declaration ? "declaration" : "definition")
index acb4274f8fac3f0486ab34e15a77f442d0a47aab..47297ea7a672126dfcb52cb18d3900be3a15a2b9 100644 (file)
@@ -122,7 +122,7 @@ namespace
        if ((at2 = m.find ((*at).first)) != m.end ()
            && ! duplicate_ok (entry.tag (), at2->first, attr.first,
                               referree.tag (), at2->second == (*at).second))
-         wr_message (to_where (entry), mc_impact_3 | mc_acc_bloat | mc_die_rel)
+         wr_message (die_locus (entry), mc_impact_3 | mc_acc_bloat | mc_die_rel)
            .id (descriptor ())
            << dwarf::tags::name (entry.tag ())
            << " attribute " << dwarf::attributes::name (at2->first)
index a758c7c3f27aa643d1358fff78388e095d0b9ce7..1b8cb4e970d5a5e48b667ee8d41472eb32c08667 100644 (file)
@@ -104,9 +104,7 @@ check_expected_trees::check_expected_trees (checkstack &stack, dwarflint &lint)
        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 ());
+         die_locus where (parent);
 
          int parent_tag = parent.tag ();
 
@@ -204,7 +202,7 @@ check_expected_trees::check_expected_trees (checkstack &stack, dwarflint &lint)
   // XXX more specific class when <dwarf> has it
   catch (std::runtime_error &exc)
     {
-      wr_error (WHERE (sec_info, NULL))
+      wr_error (section_locus (sec_info))
        << "Exception while checking expected trees: " << exc.what ()
        << std::endl;
       throw check_base::failed ();
index d615afaefafda64aa2d08b01c9a61b00a4b68ed0..74d2ad4be6c69cdf17d43b6c5e6d3f0f93f75d2c 100644 (file)
@@ -133,7 +133,7 @@ namespace
                      && entry.tag () != DW_TAG_union_type)
                      || attrs.find (DW_AT_name) != attrs.end ()))
                {
-                 wr_message (to_where (entry),
+                 wr_message (die_locus (entry),
                              mc_impact_3 | mc_acc_suboptimal | mc_die_other)
                    .id (descriptor ())
                    << elfutils::dwarf::tags::name (entry.tag ())
@@ -152,7 +152,7 @@ namespace
              if (attrs.find (DW_AT_declaration) == attrs.end ()
                  && is_external (it))
                {
-                 wr_message (to_where (entry),
+                 wr_message (die_locus (entry),
                              mc_impact_3 | mc_acc_suboptimal | mc_die_other)
                    .id (descriptor ())
                    << elfutils::dwarf::tags::name (entry.tag ())
@@ -165,7 +165,7 @@ namespace
            {
              // Global symbol in symbol table, not marked external.
              // Always bad.
-             wr_message (to_where (entry),
+             wr_message (die_locus (entry),
                          mc_impact_3 | mc_acc_suboptimal | mc_die_other)
                .id (descriptor ())
                << elfutils::dwarf::tags::name (entry.tag ())
index 6f2f4eb67f3bdd274f451385c00474b00ba2c41a..9a006342e7051f319836265d8e38956612438512 100644 (file)
@@ -63,11 +63,8 @@ check_matching_ranges::check_matching_ranges (checkstack &stack,
 
   try
     {
-      struct where where_ref = WHERE (sec_info, NULL);
       struct where where_ar = WHERE (sec_aranges, NULL);
-      where_ar.ref = &where_ref;
       struct where where_r = WHERE (sec_ranges, NULL);
-      where_r.ref = &where_ref;
       char buf[128];
 
       const dwarf::aranges_map &aranges = dw.aranges ();
@@ -75,8 +72,9 @@ check_matching_ranges::check_matching_ranges (checkstack &stack,
           i != aranges.end (); ++i)
        {
          const dwarf::compile_unit &cu = i->first;
-         where_reset_1 (&where_ref, 0);
-         where_reset_2 (&where_ref, cu.offset ());
+         die_locus where_ref (cu);
+         where_ar.ref = &where_ref;
+         where_r.ref = &where_ref;
 
          std::set<dwarf::ranges::key_type>
            cu_aranges = i->second,
@@ -114,7 +112,7 @@ check_matching_ranges::check_matching_ranges (checkstack &stack,
   // XXX more specific class when <dwarf> has it
   catch (std::runtime_error &exc)
     {
-      wr_error (WHERE (sec_info, NULL))
+      wr_error (section_locus (sec_info))
        << "Exception while checking matching ranges: " << exc.what ()
        << std::endl;
       throw check_base::failed ();
index 57b96baf54b55c5993c546afecf378e6d20e4171..cae7c84436d36b679c1126739d2ce7b5d7d18820 100644 (file)
@@ -45,7 +45,7 @@ namespace
     static void recursively_validate (dwarf::compile_unit const &cu,
                                      dwarf::debug_info_entry const &die,
                                      ranges_t const &ranges,
-                                     where const &wh_parent);
+                                     locus const &wh_parent);
 
   public:
     static checkdescriptor const *descriptor () {
@@ -72,7 +72,7 @@ check_range_out_of_scope::check_range_out_of_scope (checkstack &stack, dwarflint
       class dwarf::compile_units_type const &cus = dw.compile_units ();
       ranges_t r;
       r.push_back (std::make_pair (0, -1));
-      where wh = WHERE (sec_info, NULL);
+      section_locus wh (sec_info);
       for (dwarf::compile_units_type::const_iterator it = cus.begin ();
           it != cus.end (); ++it)
        recursively_validate (*it, *it, r, wh);
@@ -80,7 +80,7 @@ check_range_out_of_scope::check_range_out_of_scope (checkstack &stack, dwarflint
   // XXX more specific class when <dwarf> has it
   catch (std::runtime_error &exc)
     {
-      wr_error (WHERE (sec_info, NULL))
+      wr_error (section_locus (sec_info))
        << "Exception while checking ranges out of scope: " << exc.what ()
        << std::endl;
       throw check_base::failed ();
@@ -92,11 +92,9 @@ check_range_out_of_scope::recursively_validate
   (dwarf::compile_unit const &cu,
    dwarf::debug_info_entry const &die,
    ranges_t const &ranges,
-   where const &wh_parent)
+   locus const &wh_parent)
 {
-  where wh = WHERE (sec_info, NULL);
-  where_reset_1 (&wh, cu.offset ());
-  where_reset_2 (&wh, die.offset ());
+  die_locus wh (die);
 
   ::Dwarf_Addr low_pc = 0;
   ::Dwarf_Addr high_pc = ::noaddr;
index e81560aa62348ef69633a52d9ed15689d2ac7769..752fdfbb2e5cd42a710b36a2178be73ef7a89c1b 100644 (file)
@@ -65,7 +65,7 @@ namespace
            {
              dwarf::debug_info_entry ref = *val.reference ();
              if (ref.identity () == entry.identity ())
-               wr_message (to_where (entry),
+               wr_message (die_locus (entry),
                            mc_impact_3 | mc_acc_suboptimal | mc_die_rel)
                  .id (descriptor ())
                  << dwarf::tags::name (entry.tag ())
index a4df0222a403eeadf14a3357787678f7f2429d8e..b2b14682ceb0c8cbac25b74240b707f5db9c1509 100644 (file)
 
 bool
 read_size_extra (struct read_ctx *ctx, uint32_t size32, uint64_t *sizep,
-                int *offset_sizep, struct where *where)
+                int *offset_sizep, locus const &loc)
 {
   if (size32 == DWARF3_LENGTH_64_BIT)
     {
       if (!read_ctx_read_8ubyte (ctx, sizep))
        {
-         wr_error (*where) << "can't read 64bit CU length.\n";
+         wr_error (loc) << "can't read 64bit CU length.\n";
          return false;
        }
 
@@ -53,7 +53,7 @@ read_size_extra (struct read_ctx *ctx, uint32_t size32, uint64_t *sizep,
     }
   else if (size32 >= DWARF3_LENGTH_MIN_ESCAPE_CODE)
     {
-      wr_error (*where)
+      wr_error (loc)
        << "unrecognized CU length escape value: " << size32 << ".\n";
       return false;
     }
@@ -67,15 +67,13 @@ read_size_extra (struct read_ctx *ctx, uint32_t size32, uint64_t *sizep,
 }
 
 error_code
-read_address_size (struct read_ctx *ctx,
-                  bool addr_64,
-                  int *address_sizep,
-                  struct where const *where)
+read_address_size (struct read_ctx *ctx, bool addr_64,
+                  int *address_sizep, locus const &loc)
 {
   uint8_t address_size;
   if (!read_ctx_read_ubyte (ctx, &address_size))
     {
-      wr_error (*where) << "can't read address size.\n";
+      wr_error (loc) << "can't read address size.\n";
       return err_fatal;
     }
 
@@ -84,16 +82,16 @@ read_address_size (struct read_ctx *ctx,
     {
       /* Keep going.  Deduce the address size from ELF header, and try
         to parse it anyway.  */
-      wr_error (*where) << "invalid address size: " << (int)address_size
-                       << " (only 4 or 8 allowed).\n";
+      wr_error (loc) << "invalid address size: " << (int)address_size
+                    << " (only 4 or 8 allowed).\n";
       address_size = addr_64 ? 8 : 4;
       ret = err_nohl;
     }
   else if ((address_size == 8) != addr_64)
     {
       /* Keep going, we may still be able to parse it.  */
-      wr_error (*where) << "CU reports address size of " << address_size
-                       << " in " << (addr_64 ? 64 : 32) << "-bit ELF.\n";
+      wr_error (loc) << "CU reports address size of " << address_size
+                    << " in " << (addr_64 ? 64 : 32) << "-bit ELF.\n";
       ret = err_nohl;
     }
 
index 3f4f5984bcee156e1955c925bfef3a2e635702cc..8cdecfeaf0e5676bc8d78b8343f082d016814ed0 100644 (file)
@@ -38,15 +38,13 @@ enum error_code
   };
 
 bool read_size_extra (read_ctx *ctx, uint32_t size32, uint64_t *sizep,
-                     int *offset_sizep, where *where);
+                     int *offset_sizep, locus const &loc);
 
 /// Read address size and return it via address_sizep and return 0.
 /// Address size may be 4 or 8; for other values it's set depending or
 /// addr_64, and err_nohl is returned.
-error_code read_address_size (read_ctx *ctx,
-                             bool addr_64,
-                             int *address_sizep,
-                             where const *where);
+error_code read_address_size (read_ctx *ctx, bool addr_64,
+                             int *address_sizep, locus const &loc);
 
 bool checked_read_uleb128 (read_ctx *ctx, uint64_t *ret,
                           locus const &loc, const char *what);
index c09ecabda651832040e9d7442aecb9bbaa42b1b4..4f87e0c4f9819217fed947fab79c2e34ef17dcf1 100644 (file)
    Network licensing program, please visit www.openinventionnetwork.com
    <http://www.openinventionnetwork.com>.  */
 
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 #include "cu_coverage.hh"
 #include "check_debug_info.hh"
 #include "check_debug_loc_range.hh"
diff --git a/dwarflint/die_locus.cc b/dwarflint/die_locus.cc
new file mode 100644 (file)
index 0000000..1d22564
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+   Copyright (C) 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
+   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 "die_locus.hh"
+#include "pri.hh"
+
+std::string
+cu_locus::format (bool brief) const
+{
+  std::stringstream ss;
+  if (!brief)
+    ss << section_name[sec_info] << ": ";
+  ss << "CU " << _m_offset;
+  return ss.str ();
+}
+
+std::string
+die_locus::format (bool brief) const
+{
+  std::stringstream ss;
+  if (!brief)
+    ss << section_name[sec_info] << ": ";
+
+  ss << "DIE 0x" << std::hex << _m_offset;
+
+  if (_m_attrib_name != -1)
+    ss << ", attr. " << pri::attr_name (_m_attrib_name);
+
+  return ss.str ();
+}
+
diff --git a/dwarflint/die_locus.hh b/dwarflint/die_locus.hh
new file mode 100644 (file)
index 0000000..87f0a0b
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+   Copyright (C) 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
+   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>.  */
+
+#ifndef _DWARFLINT_DIE_LOCUS_H_
+#define _DWARFLINT_DIE_LOCUS_H_
+
+#include "where.h"
+#include "../libdw/c++/dwarf"
+
+class cu_locus
+  : public clonable_locus<cu_locus>
+{
+  Dwarf_Off _m_offset;
+public:
+  explicit cu_locus (Dwarf_Off offset)
+    : _m_offset (offset)
+  {}
+
+  std::string format (bool brief = false) const;
+};
+
+class die_locus
+  : public clonable_locus<die_locus>
+{
+  Dwarf_Off _m_offset;
+  int _m_attrib_name;
+
+public:
+  explicit die_locus (Dwarf_Off offset, int attrib_name = -1)
+    : _m_offset (offset)
+    , _m_attrib_name (attrib_name)
+  {}
+
+  template <class T>
+  explicit die_locus (T const &die, int attrib_name = -1)
+    : _m_offset (die.offset ())
+    , _m_attrib_name (attrib_name)
+  {}
+
+  void
+  set_attrib_name (int attrib_name)
+  {
+    _m_attrib_name = attrib_name;
+  }
+
+  std::string format (bool brief = false) const;
+};
+
+#endif /* _DWARFLINT_DIE_LOCUS_H_ */
index 007756a41f9e5aca13ea25287e1cf2ba450f5c39..66d6e38c25d71e4992069c80bb6bf955e220638b 100644 (file)
@@ -31,6 +31,8 @@
 #endif
 
 #include "checks.hh"
+#include "check_debug_info.hh"
+
 #include "../libdw/c++/dwarf"
 #include "../libdwfl/libdwfl.h"
 
@@ -82,14 +84,4 @@ public:
   {}
 };
 
-template <class T>
-inline where
-to_where (T const &die)
-{
-  where ret = WHERE (sec_info, NULL);
-  where_reset_1 (&ret, 0);
-  where_reset_2 (&ret, die.offset ());
-  return ret;
-}
-
 #endif//DWARFLINT_CHECKS_HIGH_HH
index 614563eb4f480f550fb417c320b9cfbf0587c475..8a8a05284eaac4571746d97b3a2613b382bf07f7 100644 (file)
@@ -513,10 +513,7 @@ process(Dwarf *c_dw, dwarf const &dw)
            }
          catch (::error const &e)
            {
-             struct where where = WHERE (sec_info, NULL);
-             where_reset_1 (&where, it.cu ().offset ());
-             where_reset_2 (&where, die.offset ());
-             std::cerr << "error: " << where << ": "
+             std::cerr << "error: " << die_locus (die) << ": "
                        << e.what () << '.' << std::endl;
              continue;
            }
index 987c56dfb253db9480cf891f9a69ed343ada3c80..bbfe6764a5ef66e47ea24a57e56097434b3d8057 100644 (file)
    Network licensing program, please visit www.openinventionnetwork.com
    <http://www.openinventionnetwork.com>.  */
 
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 #include "lowlevel_checks.hh"
 #include "sections.hh"
 #include "check_debug_info.hh"
index de01463f9b26b2d496634417ca5f6c2fd5b0484a..6f289ab8dfec6c38df249c7e7b27be089cc5e5c3 100644 (file)
@@ -64,3 +64,10 @@ pri::operator << (std::ostream &os, pri::range const &obj)
   return os << "[" << pri::addr (obj.start)
            << ", " << pri::addr (obj.end) << ")";
 }
+
+std::string
+pri::attr_name (int name)
+{
+  assert (name != -1);
+  return elfutils::dwarf::attributes::name (name);
+}
index 67705f40c658dc2c00dfd6e83e41f0c3333bd7f3..cef1ba9a6805c4ce2f42912809fa38ad632c4f2c 100644 (file)
@@ -114,6 +114,8 @@ namespace pri
     friend std::ostream &operator << (std::ostream &os, range const &obj);
   };
   std::ostream &operator << (std::ostream &os, range const &obj);
+
+  std::string attr_name (int name);
 }
 
 #endif//DWARFLINT_PRI_H
index f89cd67114803d7b200c5e82c5c876854a9a5b19..8cf23998b5426b7a03100180cd28a5d4cf5f772e 100644 (file)
@@ -414,7 +414,7 @@ read_rel (struct elf_file *file,
     : (is_rela ? sizeof (Elf32_Rela) : sizeof (Elf32_Rel));
   size_t count = reldata->d_size / entrysize;
 
-  struct where parent = WHERE (sec->id, NULL);
+  section_locus parent (sec->id);
 
   for (unsigned i = 0; i < count; ++i)
     {
index 54b10f6a9e056591f830d6c4d792d2232e84b9c9..fa06499da2307eef48b08296d47833805b617b45 100755 (executable)
@@ -49,7 +49,7 @@ EOF
 testrun_compare ./dwarflint empty-1 <<EOF
 warning: .debug_info: DIE 0xb: DW_AT_low_pc value not below DW_AT_high_pc.
 warning: .debug_line: table 0: no CU uses this line table.
-error: .debug_info: DIE 0x29 (abbr. 0x11, attr. decl_file): references .debug_line table, but CU DIE lacks DW_AT_stmt_list.
+error: .debug_info: DIE 0x29, attr. decl_file: references .debug_line table, but CU DIE lacks DW_AT_stmt_list.
 EOF
 
 testrun_compare ./dwarflint garbage-1 <<EOF
@@ -60,7 +60,7 @@ EOF
 
 testrun_compare ./dwarflint garbage-2 <<EOF
 error: .debug_info: CU 0: toplevel DIE must be either compile_unit or partial_unit.
-error: .debug_info: DIE 0xab (abbr. offset 113): DIE chain not terminated with null entry.
+error: .debug_info: DIE 0xab: DIE chain not terminated with null entry.
 EOF
 
 testrun_compare ./dwarflint --check=@low garbage-3 <<EOF
@@ -69,13 +69,13 @@ EOF
 
 testrun_compare ./dwarflint garbage-4 <<EOF
 error: .debug_info: DIE 0x6c: this DIE claims that its sibling is 0x80000085 but it's actually 0x85.
-error: .debug_info: DIE 0xab (abbr. offset 113): DIE chain not terminated with null entry.
+error: .debug_info: DIE 0xab: DIE chain not terminated with null entry.
 EOF
 
 testrun_compare ./dwarflint garbage-5 <<EOF
-error: .debug_info: DIE 0xab (abbr. offset 113): DIE chain not terminated with null entry.
+error: .debug_info: DIE 0xab: DIE chain not terminated with null entry.
 error: .debug_line: offset 0x3e: not enough data to read an opcode of length 5.
-error: .debug_info: DIE 0xb (abbr. 0x0, attr. stmt_list): unresolved reference to .debug_line table 0x0.
+error: .debug_info: DIE 0xb, attr. stmt_list: unresolved reference to .debug_line table 0x0.
 EOF
 
 testrun_compare ./dwarflint garbage-6 <<EOF
@@ -93,20 +93,20 @@ error: .debug_abbrev: missing zero to mark end-of-table.
 EOF
 
 testrun_compare ./dwarflint garbage-8 <<EOF
-error: .debug_info: DIE 0x6c (abbr. 0x3b, attr. sibling): has a value of 0.
+error: .debug_info: DIE 0x6c, attr. sibling: has a value of 0.
 error: .debug_info: DIE 0x6c: This DIE had children, but no DW_AT_sibling attribute.
-error: .debug_info: DIE 0xab (abbr. offset 113): DIE chain not terminated with null entry.
+error: .debug_info: DIE 0xab: DIE chain not terminated with null entry.
 EOF
 
 testrun_compare ./dwarflint garbage-9 <<EOF
-error: .debug_info: DIE 0x84 (abbr. 0x59, attr. type): invalid reference outside the CU: 0xef00ab.
+error: .debug_info: DIE 0x84, attr. type: invalid reference outside the CU: 0xef00ab.
 error: .debug_info: DIE 0x6c: is the last sibling in chain, but has a DW_AT_sibling attribute.
-error: .debug_info: DIE 0xab (abbr. offset 113): DIE chain not terminated with null entry.
+error: .debug_info: DIE 0xab: DIE chain not terminated with null entry.
 EOF
 
 testrun_compare ./dwarflint garbage-10 <<EOF
-warning: .rela 0xc of .debug_info: DIE 0xb (abbr. 0x0, attr. producer): relocation formed using STT_SECTION symbol with non-zero value.
-error: .rela 0x11 of .debug_info: DIE 0xb (abbr. 0x0, attr. comp_dir): couldn't obtain symbol #7208969: invalid section index.
+warning: .rela 0xc of .debug_info: DIE 0xb, attr. producer: relocation formed using STT_SECTION symbol with non-zero value.
+error: .rela 0x11 of .debug_info: DIE 0xb, attr. comp_dir: couldn't obtain symbol #7208969: invalid section index.
 warning: .debug_info: DIE 0xb: DW_AT_low_pc value not below DW_AT_high_pc.
 EOF
 
@@ -119,12 +119,12 @@ error: .rela 0x1d00 of .debug_info: invalid relocation 256 (<INVALID RELOC>).
 error: .rela 0x2500 of .debug_info: invalid relocation 2560 (<INVALID RELOC>).
 error: .rela 0x3600 of .debug_info: invalid relocation 256 (<INVALID RELOC>).
 warning: .debug_info: CU 0: abbrev table offset seems to lack a relocation
-warning: .debug_info: DIE 0xb (abbr. 0x0, attr. producer): strp seems to lack a relocation
-warning: .debug_info: DIE 0xb (abbr. 0x0, attr. comp_dir): strp seems to lack a relocation
-warning: .debug_info: DIE 0xb (abbr. 0x0, attr. stmt_list): data4 seems to lack a relocation
+warning: .debug_info: DIE 0xb, attr. producer: strp seems to lack a relocation
+warning: .debug_info: DIE 0xb, attr. comp_dir: strp seems to lack a relocation
+warning: .debug_info: DIE 0xb, attr. stmt_list: data4 seems to lack a relocation
 warning: .debug_info: DIE 0xb: DW_AT_low_pc value not below DW_AT_high_pc.
 error: .debug_line: table 0: header claims that it has a size of 542, but in fact it has a size of 30.
-error: .debug_info: DIE 0xb (abbr. 0x0, attr. stmt_list): unresolved reference to .debug_line table 0x0.
+error: .debug_info: DIE 0xb, attr. stmt_list: unresolved reference to .debug_line table 0x0.
 EOF
 
 testrun_compare ./dwarflint garbage-12 <<EOF
index ef5aef6b13e0f4548be6611dc40045da0e5dc2b4..d9510f9583003ad1e15e82fe59e1a30d15d22cd3 100644 (file)
@@ -127,8 +127,6 @@ namespace
   public:
     section_formatters ()
     {
-      add (sec_info, ".debug_info", "CU %"PRId64, "DIE %#"PRIx64);
-
       add (sec_aranges, ".debug_aranges",
           "table %"PRId64, "arange %#"PRIx64);
 
@@ -173,6 +171,7 @@ WHERE (section_id sec, locus const *next)
 {
   assert (sec != sec_abbrev);
   assert (sec != sec_str);
+  assert (sec != sec_info);
   where::formatter const *fmt = wf_for_section (sec);
   return where (fmt, next);
 }