diff options
| author | Petr Machata <[email protected]> | 2011-03-17 17:06:53 +0100 |
|---|---|---|
| committer | Petr Machata <[email protected]> | 2011-03-17 17:06:53 +0100 |
| commit | 0e9ce477310be7ff193338a67ddf76023326ee0d (patch) | |
| tree | 28ba8ca5aae9bc7ee4cb97779b076a0d7dee4e21 /dwarflint | |
| parent | 66a96a2d8162601ed99dc04c6fa6ecd6ee14a7f4 (diff) | |
dwarflint: Fix message filtering
Diffstat (limited to 'dwarflint')
| -rw-r--r-- | dwarflint/main.cc | 7 | ||||
| -rw-r--r-- | dwarflint/messages.cc | 123 | ||||
| -rw-r--r-- | dwarflint/messages.hh | 41 | ||||
| -rw-r--r-- | dwarflint/sections.cc | 14 | ||||
| -rwxr-xr-x | dwarflint/tests/run-bad.sh | 11 | ||||
| -rwxr-xr-x | dwarflint/tests/run-check_debug_info_refs.sh | 5 | ||||
| -rwxr-xr-x | dwarflint/tests/run-check_duplicate_DW_tag_variable.sh | 5 | ||||
| -rwxr-xr-x | dwarflint/tests/run-libdl-2.12.so.debug.sh | 11 | ||||
| -rwxr-xr-x | dwarflint/tests/run-location-leaks.sh | 3 | ||||
| -rwxr-xr-x | dwarflint/tests/run-nodebug.sh | 4 |
10 files changed, 141 insertions, 83 deletions
diff --git a/dwarflint/main.cc b/dwarflint/main.cc index 818d30f6..eb0252e0 100644 --- a/dwarflint/main.cc +++ b/dwarflint/main.cc @@ -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. */ diff --git a/dwarflint/messages.cc b/dwarflint/messages.cc index 1c2f974b..28b8d20c 100644 --- a/dwarflint/messages.cc +++ b/dwarflint/messages.cc @@ -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 diff --git a/dwarflint/messages.hh b/dwarflint/messages.hh index d14230b0..7809fb9c 100644 --- a/dwarflint/messages.hh +++ b/dwarflint/messages.hh @@ -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); diff --git a/dwarflint/sections.cc b/dwarflint/sections.cc index d5736c4b..4a8f6401 100644 --- a/dwarflint/sections.cc +++ b/dwarflint/sections.cc @@ -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) diff --git a/dwarflint/tests/run-bad.sh b/dwarflint/tests/run-bad.sh index 41c56a5f..fc14f803 100755 --- a/dwarflint/tests/run-bad.sh +++ b/dwarflint/tests/run-bad.sh @@ -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 diff --git a/dwarflint/tests/run-check_debug_info_refs.sh b/dwarflint/tests/run-check_debug_info_refs.sh index 7b36243f..74288261 100755 --- a/dwarflint/tests/run-check_debug_info_refs.sh +++ b/dwarflint/tests/run-check_debug_info_refs.sh @@ -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 diff --git a/dwarflint/tests/run-check_duplicate_DW_tag_variable.sh b/dwarflint/tests/run-check_duplicate_DW_tag_variable.sh index 2134fc27..3687a18e 100755 --- a/dwarflint/tests/run-check_duplicate_DW_tag_variable.sh +++ b/dwarflint/tests/run-check_duplicate_DW_tag_variable.sh @@ -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. diff --git a/dwarflint/tests/run-libdl-2.12.so.debug.sh b/dwarflint/tests/run-libdl-2.12.so.debug.sh index 825162c6..9caf59f9 100755 --- a/dwarflint/tests/run-libdl-2.12.so.debug.sh +++ b/dwarflint/tests/run-libdl-2.12.so.debug.sh @@ -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 diff --git a/dwarflint/tests/run-location-leaks.sh b/dwarflint/tests/run-location-leaks.sh index d6897028..c3764f97 100755 --- a/dwarflint/tests/run-location-leaks.sh +++ b/dwarflint/tests/run-location-leaks.sh @@ -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 diff --git a/dwarflint/tests/run-nodebug.sh b/dwarflint/tests/run-nodebug.sh index 049bf570..999e1e17 100755 --- a/dwarflint/tests/run-nodebug.sh +++ b/dwarflint/tests/run-nodebug.sh @@ -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 |
