]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Fix message filtering
authorPetr Machata <pmachata@redhat.com>
Thu, 17 Mar 2011 16:06:53 +0000 (17:06 +0100)
committerPetr Machata <pmachata@redhat.com>
Thu, 17 Mar 2011 16:06:53 +0000 (17:06 +0100)
dwarflint/main.cc
dwarflint/messages.cc
dwarflint/messages.hh
dwarflint/sections.cc
dwarflint/tests/run-bad.sh
dwarflint/tests/run-check_debug_info_refs.sh
dwarflint/tests/run-check_duplicate_DW_tag_variable.sh
dwarflint/tests/run-libdl-2.12.so.debug.sh
dwarflint/tests/run-location-leaks.sh
dwarflint/tests/run-nodebug.sh

index 818d30f698c792155b1b01bcdde1ec808821bc88..eb0252e0aa665581a96fb74d38768503da87ed40 100644 (file)
@@ -183,8 +183,7 @@ main (int argc, char *argv[])
   if (!be_strict)
     {
       warning_criteria &= message_term (mc_none, mc_strings);
-      warning_criteria
-       &= message_term (cat (mc_line, mc_header, mc_acc_bloat), mc_none);
+      warning_criteria.and_not (mc_line | mc_acc_bloat);
       warning_criteria &= message_term (mc_none, mc_pubtypes);
     }
 
@@ -196,8 +195,8 @@ main (int argc, char *argv[])
 
   if (false) // for debugging
     {
-      std::cout << "warning criteria: " << warning_criteria.str () << std::endl;
-      std::cout << "error criteria:   " << error_criteria.str () << std::endl;
+      std::cout << "warning criteria: " << warning_criteria << std::endl;
+      std::cout << "error criteria:   " << error_criteria << std::endl;
     }
 
   /* Before we start tell the ELF library which version we are using.  */
index 1c2f974bc6d9c985b55bfce11a6e035cbcd3dd7c..28b8d20c5b524b735bdff92cbefa083a42f7f12a 100644 (file)
@@ -1,5 +1,5 @@
 /* Pedantic checking of DWARF files
-   Copyright (C) 2009, 2010 Red Hat, Inc.
+   Copyright (C) 2009-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
@@ -39,13 +39,14 @@ bool
 message_accept (struct message_criteria const *cri,
                unsigned long cat)
 {
-  for (size_t i = 0; i < cri->size; ++i)
+  for (size_t i = 0; i < cri->size (); ++i)
     {
-      struct message_term *t = cri->terms + i;
-      if ((t->positive & cat) == t->positive
-         && (t->negative & cat) == 0)
+      message_term const &t = cri->at (i);
+      if ((t.positive & cat) == t.positive
+         && (t.negative & cat) == 0)
        return true;
     }
+
   return false;
 }
 
@@ -66,20 +67,32 @@ namespace
       MESSAGE_CATEGORIES
 #undef MC
     }
-  };
+  } cat_names;
+  size_t cat_max = cat_names.size ();
+}
+
+
+message_category
+operator | (message_category a, message_category b)
+{
+  return static_cast<message_category> ((unsigned long)a | b);
+}
+
+message_category &
+operator |= (message_category &a, message_category b)
+{
+  a = a | b;
+  return a;
 }
 
 std::string
 message_term::str () const
 {
-  static cat_to_str names;
-  static size_t max = names.size ();
-
   std::ostringstream os;
   os << '(';
 
   bool got = false;
-  for (size_t i = 0; i <= max; ++i)
+  for (size_t i = 0; i <= cat_max; ++i)
     {
       size_t mask = 1u << i;
       if ((positive & mask) != 0
@@ -89,7 +102,7 @@ message_term::str () const
            os << " & ";
          if ((negative & (1u << i)) != 0)
            os << '~';
-         os << names[i];
+         os << cat_names[i];
          got = true;
        }
     }
@@ -106,9 +119,9 @@ message_criteria::str () const
 {
   std::ostringstream os;
 
-  for (size_t i = 0; i < size; ++i)
+  for (size_t i = 0; i < size (); ++i)
     {
-      message_term const &t = terms[i];
+      message_term const &t = at (i);
       if (i > 0)
        os << " | ";
       os << t.str ();
@@ -121,14 +134,14 @@ void
 message_criteria::operator &= (message_term const &term)
 {
   assert ((term.positive & term.negative) == 0);
-  for (size_t i = 0; i < size; )
+  for (size_t i = 0; i < size (); )
     {
-      message_term &t = terms[i];
-      t.positive |= term.positive;
-      t.negative |= term.negative;
+      message_term &t = at (i);
+      t.positive = cat (t.positive, term.positive);
+      t.negative = cat (t.negative, term.negative);
       if ((t.positive & t.negative) != 0)
        /* A ^ ~A -> drop the term.  */
-       terms[i] = terms[--size];
+       erase (begin () + i);
       else
        ++i;
     }
@@ -138,8 +151,7 @@ void
 message_criteria::operator |= (message_term const &term)
 {
   assert ((term.positive & term.negative) == 0);
-  REALLOC (this, terms);
-  terms[size++] = term;
+  push_back (term);
 }
 
 // xxx this one is inaccessible from the outside.  Make it like &=, |=
@@ -150,57 +162,86 @@ operator ! (message_term const &term)
 {
   assert ((term.positive & term.negative) == 0);
 
-  unsigned max = 0;
-#define MC(CAT, ID) max = ID;
-  MESSAGE_CATEGORIES
-#undef MC
-
   message_criteria ret;
-  for (size_t i = 0; i < max; ++i)
+  for (size_t i = 0; i < cat_max; ++i)
     {
       unsigned mask = 1u << i;
       if ((term.positive & mask) != 0)
-       ret |= message_term (1u << i, mc_none);
+       ret |= message_term ((message_category)(1u << i), mc_none);
       else if ((term.negative & mask) != 0)
-       ret |= message_term (mc_none, 1u << i);
+       ret |= message_term (mc_none, (message_category)(1u << i));
     }
 
   return ret;
 }
 
-// xxx this one is inaccessible from the outside.  Make it like &=, |=
-// above
+std::ostream &
+operator<< (std::ostream &o, message_category cat)
+{
+  o << '(';
+
+  bool got = false;
+  for (size_t i = 0; i <= cat_max; ++i)
+    {
+      size_t mask = 1u << i;
+      if ((cat & mask) != 0)
+       {
+         if (got)
+           o << ",";
+         o << cat_names[i];
+         got = true;
+       }
+    }
+
+  if (!got)
+    o << "none";
+
+  return o << ')';
+}
+
+std::ostream &
+operator<< (std::ostream &o, message_term const &term)
+{
+  return o << term.str ();
+}
+
+std::ostream &
+operator<< (std::ostream &o, __attribute__ ((unused)) message_criteria const &criteria)
+{
+  return o << criteria.str ();
+}
+
 /* MUL((a&b + c&d), (e&f + g&h)) -> (a&b&e&f + a&b&g&h + c&d&e&f + c&d&g&h) */
 void
-message_cri_mul (struct message_criteria *cri, struct message_criteria *rhs)
+message_criteria::operator *= (message_criteria const &rhs)
 {
   struct message_criteria ret;
   WIPE (ret);
 
-  for (size_t i = 0; i < cri->size; ++i)
-    for (size_t j = 0; j < rhs->size; ++j)
+  for (size_t i = 0; i < size (); ++i)
+    for (size_t j = 0; j < rhs.size (); ++j)
       {
-       struct message_term t1 = cri->terms[i];
-       struct message_term *t2 = rhs->terms + j;
-       t1.positive |= t2->positive;
-       t1.negative |= t2->negative;
+       message_term t1 = at (i);
+       message_term const &t2 = rhs.at (j);
+       t1.positive |= t2.positive;
+       t1.negative |= t2.negative;
        if (t1.positive & t1.negative)
          /* A ^ ~A -> drop the term.  */
          continue;
        ret |= t1;
       }
 
-  free (cri->terms);
-  *cri = ret;
+  *this = ret;
 }
 
 // xxx this one is inaccessible from the outside.  Bind it properly
 /* Reject message if TERM passes.  */
 void
-message_cri_and_not (message_criteria &cri, message_term const &term)
+message_criteria::and_not (message_term const &term)
 {
+  // xxxxx really??  "!"??
   message_criteria tmp = !message_term (term.negative, term.positive);
-  message_cri_mul (&cri, &tmp);
+  *this *= tmp;
 }
 
 static void
index d14230b0a008f3a4ee66f27bdda341f8ecc1f4fb..7809fb9cb43db7b0893ea38de250797411f00298 100644 (file)
@@ -1,5 +1,5 @@
 /* Pedantic checking of DWARF files
-   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
@@ -29,6 +29,8 @@
 #include "where.h"
 #include "libdw.h"
 #include <string>
+#include <iosfwd>
+#include <vector>
 
 #define MESSAGE_CATEGORIES                                             \
   /* Severity: */                                                      \
@@ -60,7 +62,7 @@
   MC (line,      19) /* messages related to .debug_line */             \
   MC (reloc,     20) /* messages related to relocation handling */     \
   MC (header,    21) /* messages related to header portions in general */ \
-  MC (mac,       22) /* messages related to .debug_mac */ \
+  MC (mac,       22) /* messages related to .debug_mac */              \
   MC (other,     31) /* messages unrelated to any of the above */
 
 enum message_category
@@ -73,38 +75,41 @@ enum message_category
 #undef MC
   };
 
+message_category operator | (message_category a, message_category b);
+message_category &operator |= (message_category &a, message_category b);
+std::ostream &operator<< (std::ostream &o, message_category cat);
+
 struct message_term
 {
   /* Given a term like A && !B && C && !D, we decompose it thus: */
-  unsigned long positive; /* non-zero bits for plain predicates */
-  unsigned long negative; /* non-zero bits for negated predicates */
+  message_category positive; /* non-zero bits for plain predicates */
+  message_category negative; /* non-zero bits for negated predicates */
 
-  message_term (unsigned long pos, unsigned long neg)
+  message_term (message_category pos, message_category neg = mc_none)
     : positive (pos), negative (neg)
   {}
+
   std::string str () const;
 };
 
+std::ostream &operator<< (std::ostream &o, message_term const &term);
+
 struct message_criteria
+  : protected std::vector<message_term>
 {
-  struct message_term *terms;
-  size_t size;
-  size_t alloc;
-
-  message_criteria ()
-    : terms (NULL), size (0), alloc (0)
-  {}
-
-  ~message_criteria ()
-  {
-    free (terms);
-  }
+  using std::vector<message_term>::at;
+  using std::vector<message_term>::size;
 
   void operator |= (message_term const &term);
   void operator &= (message_term const &term);
+  void operator *= (message_criteria const &term);
+  void and_not (message_term const &term);
+
   std::string str () const;
 };
 
+std::ostream &operator<< (std::ostream &o, message_criteria const &criteria);
+
 message_criteria operator ! (message_term const &);
 
 extern void wr_error (const struct where *wh, const char *format, ...)
@@ -154,7 +159,7 @@ cat (message_category c1,
      message_category c3 = mc_none,
      message_category c4 = mc_none)
 {
-  return static_cast<message_category> (c1 | c2 | c3 | c4);
+  return c1 | c2 | c3 | c4;
 }
 
 std::ostream &wr_warning (where const &wh);
index d5736c4bedb154e5001c13e377b3c5e7bb6483dd..4a8f6401efd530b6129aa0163a9d39d78d1c0afb 100644 (file)
@@ -250,12 +250,7 @@ namespace
     REALLOC (file, sec);
     file->sec[file->size++].id = sec_invalid;
 
-    bool check_rel = true;
-
-    /* Try to obtain .shstrtab, which we will need in following.  If
-       we fail, elf is broken.  */
-    Elf_Scn *shstrscn = elf_getscn (elf, file->ehdr.e_shstrndx);
-    if (shstrscn == NULL || elf_rawdata (shstrscn, NULL) == NULL)
+    if (false)
       {
       invalid_elf:
        wr_error () << "Broken ELF: " << elf_errmsg (-1) << "."
@@ -263,6 +258,11 @@ namespace
        goto close_and_out;
       }
 
+    /* Check that the ELF file is sound.  */
+    for (Elf_Scn *scn = NULL; (scn = elf_nextscn (elf, scn)); )
+      if (elf_rawdata (scn, NULL) == NULL)
+       goto invalid_elf;
+
     for (Elf_Scn *scn = NULL; (scn = elf_nextscn (elf, scn)); )
       {
        REALLOC (file, sec);
@@ -366,7 +366,7 @@ namespace
       if (it->second.secndx != 0)
        file->debugsec[it->second.id] = file->sec + it->second.secndx;
 
-    if (check_rel)
+    if (true)
       {
        Elf_Data *reloc_symdata = NULL;
        if (reloc_symtab != NULL)
index 41c56a5f14040306cd9c98a57cdb07e7e64c5cc9..fc14f80305ee97f906428b3c1b925332b61e3d7a 100755 (executable)
@@ -36,7 +36,9 @@ testrun_compare ./dwarflint hello.bad-1 <<EOF
 error: .debug_info: DIE 0x83: abbrev section at 0x0 doesn't contain code 83.
 EOF
 
-testrun_compare ./dwarflint hello.bad-3 <<EOF
+testrun_compare ./dwarflint --check=@low hello.bad-3 <<EOF
+error: .debug_info: DIE 0x2d: This DIE had children, but no DW_AT_sibling attribute.
+error: .debug_info: DIE 0xb: This DIE had children, but no DW_AT_sibling attribute.
 error: .debug_info: DIE 0x91: toplevel DIE chain contains more than one DIE.
 error: .debug_info: DIE 0x98: toplevel DIE chain contains more than one DIE.
 error: .debug_info: DIE 0x9e: toplevel DIE chain contains more than one DIE.
@@ -45,7 +47,7 @@ error: .debug_info: DIE 0xab: toplevel DIE chain contains more than one DIE.
 EOF
 
 testrun_compare ./dwarflint empty-1 <<EOF
-warning: .debug_line: table 0: the file #1 \`empty.c' is not used.
+warning: .debug_line: table 0: no CU uses this line table.
 error: .debug_info: DIE 0x29 (abbr. attribute 0x13): references .debug_line table, but CU DIE lacks DW_AT_stmt_list.
 EOF
 
@@ -91,6 +93,7 @@ EOF
 
 testrun_compare ./dwarflint garbage-8 <<EOF
 error: .debug_info: DIE 0x6c (abbr. attribute 0x43): DW_AT_sibling with a value of 0.
+error: .debug_info: DIE 0x6c: This DIE had children, but no DW_AT_sibling attribute.
 error: .debug_info: DIE 0xab (abbreviation 113): DIE chain not terminated with null entry.
 EOF
 
@@ -113,6 +116,10 @@ error: .rela.debug_info: offset 0x1500: invalid relocation 256 (<INVALID RELOC>)
 error: .rela.debug_info: offset 0x1d00: invalid relocation 256 (<INVALID RELOC>).
 error: .rela.debug_info: offset 0x2500: invalid relocation 2560 (<INVALID RELOC>).
 error: .rela.debug_info: offset 0x3600: invalid relocation 256 (<INVALID RELOC>).
+warning: .debug_info: CU 0: abbrev table offset seems to lack a relocation
+warning: .debug_info: DIE 0xb (abbr. attribute 0): strp seems to lack a relocation
+warning: .debug_info: DIE 0xb (abbr. attribute 0x4): strp seems to lack a relocation
+warning: .debug_info: DIE 0xb (abbr. attribute 0xa): data4 seems to lack a relocation
 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. attribute 0xa): unresolved reference to .debug_line table 0x0.
 EOF
index 7b36243fa70be3df4bf454c82838e053d82ab7d5..74288261ccfd5591cc2bec265533eeb98bf6041e 100755 (executable)
@@ -31,13 +31,14 @@ testfiles check_debug_info_refs-{1,2}
 
 testrun_compare ./dwarflint --check=check_debug_info_refs check_debug_info_refs-1 <<EOF
 error: .debug_aranges: table 48 (CU DIE 95): there has already been arange section for this CU.
+warning: .debug_info: CU 0: no aranges table is associated with this CU.
 EOF
 
-testrun_compare ./dwarflint --strict --check=check_debug_info_refs check_debug_info_refs-1 <<EOF
+testrun_compare ./dwarflint --check=check_debug_info_refs check_debug_info_refs-1 <<EOF
 error: .debug_aranges: table 48 (CU DIE 95): there has already been arange section for this CU.
 warning: .debug_info: CU 0: no aranges table is associated with this CU.
 EOF
 
-testrun_compare ./dwarflint --strict --check=check_debug_info_refs check_debug_info_refs-2 <<EOF
+testrun_compare ./dwarflint --check=check_debug_info_refs check_debug_info_refs-2 <<EOF
 warning: .debug_info: CU 0: no aranges table is associated with this CU.
 EOF
index 2134fc277ea95c4ae948432ab35211c3aaea76fc..3687a18eb8591ed818556f14844445b0fb53bf23 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# Copyright (C) 2010 Red Hat, Inc.
+# Copyright (C) 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
@@ -30,8 +30,7 @@ srcdir=$srcdir/tests
 testfiles crc7.ko.debug
 
 testrun_compare ./dwarflint --check check_duplicate_DW_tag_variable crc7.ko.debug <<EOF
-warning: .debug_line: offset 0x3c4: the include #6 \`XXXXXX' is not used.
-warning: .debug_line: table 967: the include #6 \`XXXXXX' is not used.
+warning: .debug_info: CU 16614: no aranges table is associated with this CU.
 error: .debug_info: DIE 0x3d21: Redeclaration of variable 'console_printk', originally seen at DIE 37f3.
 error: .debug_info: DIE 0x3d2e: Redeclaration of variable 'hex_asc', originally seen at DIE 380b.
 error: .debug_info: DIE 0x3d41: Redeclaration of variable '__per_cpu_offset', originally seen at DIE 382e.
index 825162c6870fc737d1c2f153008deb295aed19b4..9caf59f9f7f4f31fd1729baa805b2dbddcf2ca07 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# Copyright (C) 2010 Red Hat, Inc.
+# Copyright (C) 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
@@ -30,15 +30,18 @@ srcdir=$srcdir/tests
 testfiles libdl-2.12.so.debug
 
 # Here we test that dwarflint can tolerate invalid attribute name.
-testrun_compare ./dwarflint --check=@low --nognu libdl-2.12.so.debug <<EOF
+testrun_compare ./dwarflint --check=@low --nognu --ignore-bloat libdl-2.12.so.debug <<EOF
 error: .debug_abbrev: abbr. attribute 0xbe: invalid or unknown name 0x2107.
 error: .debug_abbrev: abbr. attribute 0x330: invalid or unknown name 0x2107.
 error: .debug_abbrev: abbr. attribute 0xa28: invalid or unknown name 0x2107.
 error: .debug_abbrev: abbr. attribute 0x108e: invalid or unknown name 0x2107.
 error: .debug_abbrev: abbr. attribute 0x1300: invalid or unknown name 0x2107.
+warning: .debug_info: CU 55709: no aranges table is associated with this CU.
+warning: .debug_info: CU 56524: no aranges table is associated with this CU.
 EOF
 
 # Here we test proper support for DW_AT_GNU_vector
-testrun_compare ./dwarflint --check=@low libdl-2.12.so.debug <<EOF
-No errors
+testrun_compare ./dwarflint --check=@low --ignore-bloat libdl-2.12.so.debug <<EOF
+warning: .debug_info: CU 55709: no aranges table is associated with this CU.
+warning: .debug_info: CU 56524: no aranges table is associated with this CU.
 EOF
index d689702845145a4f5c466729d4605881e3aa90b8..c3764f970ebedcd588c39821162368b9b8afb0e8 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# Copyright (C) 2010 Red Hat, Inc.
+# Copyright (C) 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
@@ -30,6 +30,7 @@ srcdir=$srcdir/tests
 testfiles location-leaks
 
 testrun_compare ./dwarflint location-leaks <<EOF
+warning: .debug_loc: loclist 0x38: entry covers no range.
 error: .debug_info: DIE 0x62: attribute \`location': PC range [0x400495, 0x40049a) outside containing scope.
 error: .debug_info: DIE 0x51: in this context: [0x400498, 0x4004b2).
 EOF
index 049bf5708be21cf0684f3c3a728c2795f76fc392..999e1e1758e10c57ff4123ffc2e3b603c3dccd00 100755 (executable)
@@ -71,9 +71,11 @@ warning: the rule \`oentuh' never matched.
 EOF
 
 testrun_compare ./dwarflint null.o <<EOF
+warning: .debug_abbrev: [0x0, 0x1): unnecessary padding with zero bytes.
+warning: .debug_abbrev: no abbreviations.
 error: .debug_info: data not found.
 EOF
 
-testrun_compare ./dwarflint --nodebug:ignore null.o <<EOF
+testrun_compare ./dwarflint --ignore-bloat --nodebug:ignore null.o <<EOF
 No errors
 EOF