]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Extract .debug_pub checks into check_debug_pub.cc
authorPetr Machata <pmachata@redhat.com>
Mon, 30 Nov 2009 17:06:53 +0000 (18:06 +0100)
committerPetr Machata <pmachata@redhat.com>
Wed, 18 Aug 2010 12:55:17 +0000 (14:55 +0200)
src/Makefile.am
src/dwarflint/check_debug_info.cc
src/dwarflint/check_debug_info.hh
src/dwarflint/check_debug_pub.cc [new file with mode: 0644]
src/dwarflint/checks-low.cc
src/dwarflint/low.c
src/dwarflint/low.h
src/dwarflint/pri.hh

index 2a9aef337bffb2c310990c02c2cd54f242538f96..086e5c0e8ca1299dceaf8c06ebac40d9205251ee 100644 (file)
@@ -99,6 +99,7 @@ dwarflint_SOURCES = dwarfstrings.c \
                    dwarflint/check_debug_abbrev.cc dwarflint/check_debug_abbrev.hh dwarflint/check_debug_abbrev.ii \
                    dwarflint/check_debug_info.cc dwarflint/check_debug_info.hh dwarflint/check_debug_info.ii \
                    dwarflint/check_debug_line.cc \
+                   dwarflint/check_debug_pub.cc \
                    dwarflint/check_debug_loc_range.cc dwarflint/check_debug_loc_range.hh \
                    dwarflint/check_matching_ranges.cc \
                    dwarflint/check_range_out_of_scope.cc \
index d4642b2d27e353f54794012eb8b63314278a0805..2f1ff8f357a2fada764aaae1527bc6721ded97de 100644 (file)
@@ -1180,3 +1180,14 @@ check_debug_info::~check_debug_info ()
     }
   coverage_free (&cu_cov.cov);
 }
+
+cu *
+check_debug_info::find_cu (::Dwarf_Off offset)
+{
+  for (std::vector<cu>::iterator it = cus.begin ();
+       it != cus.end (); ++it)
+    if (it->head->offset == offset)
+      return &*it;
+
+  return NULL;
+}
index 844bc5381e311e64053688e4dacd57cb09f4261d..1f8b7bf86ff255f464338263a79bba60dc5a06d3 100644 (file)
@@ -72,6 +72,8 @@ public:
 
   explicit check_debug_info (dwarflint &lint);
   ~check_debug_info ();
+
+  cu *find_cu (::Dwarf_Off offset);
 };
 static reg<check_debug_info> reg_debug_info;
 
diff --git a/src/dwarflint/check_debug_pub.cc b/src/dwarflint/check_debug_pub.cc
new file mode 100644 (file)
index 0000000..29d2b95
--- /dev/null
@@ -0,0 +1,201 @@
+#include "checks-low.hh"
+#include "check_debug_info.hh"
+#include "pri.hh"
+
+namespace
+{
+  template<section_id sec_id>
+  class check_debug_pub
+    : public check<check_debug_pub<sec_id> >
+  {
+    section<sec_id> *_m_sec;
+    elf_file const &_m_file;
+
+    bool check_pub_structural (check_debug_info *cus);
+
+  public:
+    explicit check_debug_pub (dwarflint &lint)
+      : _m_sec (lint.check (_m_sec))
+      , _m_file (_m_sec->file)
+    {
+      check_pub_structural (lint.toplev_check<check_debug_info> ());
+    }
+  };
+
+  template <class A, class B>
+  struct where xwhere (A a, B b)
+  {
+    return WHERE (a, b);
+  }
+}
+
+template <section_id sec_id>
+bool
+check_debug_pub<sec_id>::check_pub_structural (check_debug_info *cus)
+{
+  struct read_ctx ctx;
+  read_ctx_init (&ctx, _m_sec->sect.data, _m_file.other_byte_order);
+  bool retval = true;
+
+  while (!read_ctx_eof (&ctx))
+    {
+      struct where where = WHERE (_m_sec->sect.id, NULL);
+      where_reset_1 (&where, read_ctx_get_offset (&ctx));
+      const unsigned char *set_begin = ctx.ptr;
+
+      /* Size.  */
+      uint32_t size32;
+      uint64_t size;
+      int offset_size;
+      if (!read_ctx_read_4ubyte (&ctx, &size32))
+       {
+         wr_error (&where, ": can't read table length.\n");
+         return false;
+       }
+      if (!read_size_extra (&ctx, size32, &size, &offset_size, &where))
+       return false;
+
+      {
+      struct read_ctx sub_ctx;
+      const unsigned char *set_end = ctx.ptr + size;
+      if (!read_ctx_init_sub (&sub_ctx, &ctx, set_begin, set_end))
+       goto not_enough;
+      sub_ctx.ptr = ctx.ptr;
+
+      /* Version.  */
+      uint16_t version;
+      if (!read_ctx_read_2ubyte (&sub_ctx, &version))
+       {
+         wr_error (&where, ": can't read set version.\n");
+         retval = false;
+         goto next;
+       }
+      if (!supported_version (version, 1, &where, 2))
+       {
+         retval = false;
+         goto next;
+       }
+
+      /* CU offset.  */
+      uint64_t cu_offset;  /* Offset of related CU.  */
+      uint64_t ctx_offset = sub_ctx.ptr - ctx.begin;
+      if (!read_ctx_read_offset (&sub_ctx, offset_size == 8, &cu_offset))
+       {
+         wr_error (&where, ": can't read debug info offset.\n");
+         retval = false;
+         goto next;
+       }
+
+      struct relocation *rel;
+      if ((rel = relocation_next (&_m_sec->sect.rel, ctx_offset,
+                                 &where, skip_mismatched)))
+       relocate_one (&_m_file, &_m_sec->sect.rel, rel, offset_size,
+                     &cu_offset, &where, sec_info, NULL);
+      else if (_m_file.ehdr.e_type == ET_REL)
+       wr_message (mc_impact_2 | mc_pubtables | mc_reloc | mc_header, &where,
+                   PRI_LACK_RELOCATION, "debug info offset");
+
+      struct cu *cu = NULL;
+      if (cus != NULL && (cu = cus->find_cu (cu_offset)) == NULL)
+       wr_error (where)
+         << "unresolved reference to " << pri::CU (cu_offset)
+         << '.' << std::endl;
+      if (cu != NULL)
+       {
+         where.ref = &cu->head->where;
+         bool *has = _m_sec->sect.id == sec_pubnames
+           ? &cu->has_pubnames : &cu->has_pubtypes;
+         if (*has)
+           wr_message (mc_impact_2 | mc_pubtables | mc_header, &where,
+                       ": there has already been section for this CU.\n");
+         else
+           *has = true;
+       }
+
+      /* Covered length.  */
+      uint64_t cu_len;
+      if (!read_ctx_read_offset (&sub_ctx, offset_size == 8, &cu_len))
+       {
+         wr_error (&where, ": can't read covered length.\n");
+         retval = false;
+         goto next;
+       }
+      if (cu != NULL && cu_len != cu->head->total_size)
+       {
+         wr_error (where)
+           << "the table covers length " << cu_len << " but CU has length "
+           << cu->head->total_size << '.' << std::endl;
+         retval = false;
+         goto next;
+       }
+
+      /* Records... */
+      while (!read_ctx_eof (&sub_ctx))
+       {
+         ctx_offset = sub_ctx.ptr - ctx.begin;
+         where_reset_2 (&where, ctx_offset);
+
+         uint64_t offset;
+         if (!read_ctx_read_offset (&sub_ctx, offset_size == 8, &offset))
+           {
+             wr_error (&where, ": can't read offset field.\n");
+             retval = false;
+             goto next;
+           }
+         if (offset == 0)
+           break;
+
+         if (cu != NULL
+             && !addr_record_has_addr (&cu->die_addrs,
+                                       offset + cu->head->offset))
+           {
+             wr_error (where)
+               << "unresolved reference to " << pri::DIE (offset)
+               << '.' << std::endl;
+             retval = false;
+             goto next;
+           }
+
+         uint8_t c;
+         do
+           if (!read_ctx_read_ubyte (&sub_ctx, &c))
+             {
+               wr_error (&where, ": can't read symbol name.\n");
+               retval = false;
+               goto next;
+             }
+         while (c);
+       }
+
+       struct where wh = WHERE (_m_sec->sect.id, NULL);
+       if (sub_ctx.ptr != sub_ctx.end
+           && !check_zero_padding (&sub_ctx, mc_pubtables, &wh))
+         {
+           wh = WHERE (_m_sec->sect.id, NULL);
+           wr_message_padding_n0 (mc_pubtables | mc_error, &wh,
+                                  read_ctx_get_offset (&sub_ctx),
+                                  read_ctx_get_offset (&sub_ctx) + size);
+           retval = false;
+         }
+      }
+
+    next:
+      if (read_ctx_skip (&ctx, size))
+       continue;
+
+    not_enough:
+      wr_error (&where, PRI_NOT_ENOUGH, "next set");
+      return false;
+    }
+
+  if (retval)
+    relocation_skip_rest (&_m_sec->sect.rel, _m_sec->sect.id);
+
+  return retval;
+}
+
+namespace
+{
+  reg<check_debug_pub<sec_pubnames> > reg_debug_pubnames;
+  reg<check_debug_pub<sec_pubtypes> > reg_debug_pubtypes;
+}
index 16f377becd8584c6553346ca9a8f5aab17178294..4e07beb7fd0a9677fe9f5e97d69b6f9fe0ee3b2b 100644 (file)
@@ -487,28 +487,3 @@ check_debug_aranges::check_debug_aranges (dwarflint &lint)
                                 cov))
     throw check_base::failed ();
 }
-
-namespace
-{
-  template<section_id sec_id>
-  class check_debug_pub
-    : public check<check_debug_pub<sec_id> >
-  {
-    section<sec_id> *_m_sec;
-    check_debug_info *_m_cus;
-
-  public:
-    explicit check_debug_pub (dwarflint &lint)
-      : _m_sec (lint.check (_m_sec))
-      , _m_cus (lint.check (_m_cus))
-    {
-      if (!check_pub_structural (&_m_sec->file,
-                                &_m_sec->sect,
-                                &_m_cus->cus.front ()))
-       throw check_base::failed ();
-    }
-  };
-
-  reg<check_debug_pub<sec_pubnames> > reg_debug_pubnames;
-  reg<check_debug_pub<sec_pubtypes> > reg_debug_pubtypes;
-}
index a4b0fc59cc2ca6d9e45d5d466f85392d59a284fa..51ba46859e3fcbcc802b8d007e3e42c0944bd85d 100644 (file)
@@ -556,168 +556,6 @@ check_aranges_structural (struct elf_file *file,
   return retval;
 }
 
-bool
-check_pub_structural (struct elf_file *file,
-                     struct sec *sec,
-                     struct cu *cu_chain)
-{
-  struct read_ctx ctx;
-  read_ctx_init (&ctx, sec->data, file->other_byte_order);
-  bool retval = true;
-
-  while (!read_ctx_eof (&ctx))
-    {
-      struct where where = WHERE (sec->id, NULL);
-      where_reset_1 (&where, read_ctx_get_offset (&ctx));
-      const unsigned char *set_begin = ctx.ptr;
-
-      /* Size.  */
-      uint32_t size32;
-      uint64_t size;
-      int offset_size;
-      if (!read_ctx_read_4ubyte (&ctx, &size32))
-       {
-         wr_error (&where, ": can't read table length.\n");
-         return false;
-       }
-      if (!read_size_extra (&ctx, size32, &size, &offset_size, &where))
-       return false;
-
-      struct read_ctx sub_ctx;
-      const unsigned char *set_end = ctx.ptr + size;
-      if (!read_ctx_init_sub (&sub_ctx, &ctx, set_begin, set_end))
-       {
-       not_enough:
-         wr_error (&where, PRI_NOT_ENOUGH, "next set");
-         return false;
-       }
-      sub_ctx.ptr = ctx.ptr;
-
-      /* Version.  */
-      uint16_t version;
-      if (!read_ctx_read_2ubyte (&sub_ctx, &version))
-       {
-         wr_error (&where, ": can't read set version.\n");
-         retval = false;
-         goto next;
-       }
-      if (!supported_version (version, 1, &where, 2))
-       {
-         retval = false;
-         goto next;
-       }
-
-      /* CU offset.  */
-      uint64_t cu_offset;  /* Offset of related CU.  */
-      uint64_t ctx_offset = sub_ctx.ptr - ctx.begin;
-      if (!read_ctx_read_offset (&sub_ctx, offset_size == 8, &cu_offset))
-       {
-         wr_error (&where, ": can't read debug info offset.\n");
-         retval = false;
-         goto next;
-       }
-
-      struct relocation *rel;
-      if ((rel = relocation_next (&sec->rel, ctx_offset,
-                                 &where, skip_mismatched)))
-       relocate_one (file, &sec->rel, rel, offset_size,
-                     &cu_offset, &where, sec_info, NULL);
-      else if (file->ehdr.e_type == ET_REL)
-       wr_message (mc_impact_2 | mc_pubtables | mc_reloc | mc_header, &where,
-                   PRI_LACK_RELOCATION, "debug info offset");
-
-      struct cu *cu = NULL;
-      if (cu_chain != NULL && (cu = cu_find_cu (cu_chain, cu_offset)) == NULL)
-       wr_error (&where, ": unresolved reference to " PRI_CU ".\n", cu_offset);
-      if (cu != NULL)
-       {
-         where.ref = &cu->head->where;
-         bool *has = sec->id == sec_pubnames
-                       ? &cu->has_pubnames : &cu->has_pubtypes;
-         if (*has)
-           wr_message (mc_impact_2 | mc_pubtables | mc_header, &where,
-                       ": there has already been section for this CU.\n");
-         else
-           *has = true;
-       }
-
-      /* Covered length.  */
-      uint64_t cu_len;
-      if (!read_ctx_read_offset (&sub_ctx, offset_size == 8, &cu_len))
-       {
-         wr_error (&where, ": can't read covered length.\n");
-         retval = false;
-         goto next;
-       }
-      if (cu != NULL && cu_len != cu->head->total_size)
-       {
-         wr_error (&where,
-                   ": the table covers length %" PRId64
-                   " but CU has length %" PRId64 ".\n",
-                   cu_len, cu->head->total_size);
-         retval = false;
-         goto next;
-       }
-
-      /* Records... */
-      while (!read_ctx_eof (&sub_ctx))
-       {
-         ctx_offset = sub_ctx.ptr - ctx.begin;
-         where_reset_2 (&where, ctx_offset);
-
-         uint64_t offset;
-         if (!read_ctx_read_offset (&sub_ctx, offset_size == 8, &offset))
-           {
-             wr_error (&where, ": can't read offset field.\n");
-             retval = false;
-             goto next;
-           }
-         if (offset == 0)
-           break;
-
-         if (cu != NULL
-             && !addr_record_has_addr (&cu->die_addrs,
-                                       offset + cu->head->offset))
-           {
-             wr_error (&where,
-                       ": unresolved reference to " PRI_DIE ".\n", offset);
-             retval = false;
-             goto next;
-           }
-
-         uint8_t c;
-         do
-           if (!read_ctx_read_ubyte (&sub_ctx, &c))
-             {
-               wr_error (&where, ": can't read symbol name.\n");
-               retval = false;
-               goto next;
-             }
-         while (c);
-       }
-
-      if (sub_ctx.ptr != sub_ctx.end
-         && !check_zero_padding (&sub_ctx, mc_pubtables,
-                                 &WHERE (sec->id, NULL)))
-       {
-         wr_message_padding_n0 (mc_pubtables | mc_error,
-                                &WHERE (sec->id, NULL),
-                                read_ctx_get_offset (&sub_ctx),
-                                read_ctx_get_offset (&sub_ctx) + size);
-         retval = false;
-       }
-
-    next:
-      if (!read_ctx_skip (&ctx, size))
-       goto not_enough;
-    }
-
-  if (retval)
-    relocation_skip_rest (&sec->rel, sec->id);
-
-  return retval;
-}
-
 static GElf_Rela *
 get_rel_or_rela (Elf_Data *data, int ndx,
                 GElf_Rela *dst, size_t type)
index db46b98b81b0b33f2d051437c93ffc8f0fed896c..c415310f4ebd1100b5d7c3b29b32091e9012b491 100644 (file)
@@ -146,9 +146,6 @@ extern "C"
                                        struct sec *sec,
                                        struct cu *cu_chain,
                                        struct coverage *coverage);
-  extern bool check_pub_structural (struct elf_file *file,
-                                   struct sec *sec,
-                                   struct cu *cu_chain);
   extern bool check_line_structural (struct elf_file *file,
                                     struct sec *sec,
                                     struct addr_record *line_tables);
index 5ce28870dd9058b710c03e2d275333992b782f3d..eb4d6501525cbea281000c40f00366e3bf89a930 100644 (file)
@@ -96,6 +96,10 @@ namespace pri
     DIE (Dwarf_Off off) : hex (off, "DIE ") {}
   };
 
+  struct CU: public hex {
+    CU (Dwarf_Off off) : hex (off, "CU ") {}
+  };
+
   class range
   {
     Dwarf_Off start;