Commit-ID:  1bcb58a099938c33acda78b212ed67b06b3359ef
Gitweb:     http://git.kernel.org/tip/1bcb58a099938c33acda78b212ed67b06b3359ef
Author:     Josh Poimboeuf <jpoim...@redhat.com>
AuthorDate: Wed, 9 Mar 2016 00:07:01 -0600
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Wed, 9 Mar 2016 10:48:10 +0100

objtool: Only print one warning per function

When objtool discovers an issue, it's very common for it to flood the
terminal with a lot of duplicate warnings.  For example:

  warning: objtool: rtlwifi_rate_mapping()+0x2e7: frame pointer state mismatch
  warning: objtool: rtlwifi_rate_mapping()+0x2f3: frame pointer state mismatch
  warning: objtool: rtlwifi_rate_mapping()+0x2ff: frame pointer state mismatch
  warning: objtool: rtlwifi_rate_mapping()+0x30b: frame pointer state mismatch
  ...

The first warning is usually all you need.  Change it to only warn once
per function.

Suggested-by: Ingo Molnar <mi...@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoim...@redhat.com>
Cc: Andrew Morton <a...@linux-foundation.org>
Cc: Andy Lutomirski <l...@kernel.org>
Cc: Arnaldo Carvalho de Melo <a...@infradead.org>
Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
Cc: Bernd Petrovitsch <be...@petrovitsch.priv.at>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Chris J Arges <chris.j.ar...@canonical.com>
Cc: Jiri Slaby <jsl...@suse.cz>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Michal Marek <mma...@suse.cz>
Cc: Namhyung Kim <namhy...@gmail.com>
Cc: Pedro Alves <pal...@redhat.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: live-patch...@vger.kernel.org
Link: 
http://lkml.kernel.org/r/c47f3ca38aa01e2a9b6601f9e38efd414c3f3c18.1457502970.git.jpoim...@redhat.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 tools/objtool/builtin-check.c | 48 ++++++++++++++++++++++---------------------
 1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index bfeee22..7515cb2 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -800,7 +800,7 @@ static int validate_branch(struct objtool_file *file,
        struct instruction *insn;
        struct section *sec;
        unsigned char state;
-       int ret, warnings = 0;
+       int ret;
 
        insn = first;
        sec = insn->sec;
@@ -809,7 +809,7 @@ static int validate_branch(struct objtool_file *file,
        if (insn->alt_group && list_empty(&insn->alts)) {
                WARN_FUNC("don't know how to handle branch to middle of 
alternative instruction group",
                          sec, insn->offset);
-               warnings++;
+               return 1;
        }
 
        while (1) {
@@ -817,10 +817,10 @@ static int validate_branch(struct objtool_file *file,
                        if (frame_state(insn->state) != frame_state(state)) {
                                WARN_FUNC("frame pointer state mismatch",
                                          sec, insn->offset);
-                               warnings++;
+                               return 1;
                        }
 
-                       return warnings;
+                       return 0;
                }
 
                /*
@@ -828,14 +828,15 @@ static int validate_branch(struct objtool_file *file,
                 * the next function.
                 */
                if (is_fentry_call(insn) && (state & STATE_FENTRY))
-                       return warnings;
+                       return 0;
 
                insn->visited = true;
                insn->state = state;
 
                list_for_each_entry(alt, &insn->alts, list) {
                        ret = validate_branch(file, alt->insn, state);
-                       warnings += ret;
+                       if (ret)
+                               return 1;
                }
 
                switch (insn->type) {
@@ -845,7 +846,7 @@ static int validate_branch(struct objtool_file *file,
                                if (state & STATE_FP_SAVED) {
                                        WARN_FUNC("duplicate frame pointer 
save",
                                                  sec, insn->offset);
-                                       warnings++;
+                                       return 1;
                                }
                                state |= STATE_FP_SAVED;
                        }
@@ -856,7 +857,7 @@ static int validate_branch(struct objtool_file *file,
                                if (state & STATE_FP_SETUP) {
                                        WARN_FUNC("duplicate frame pointer 
setup",
                                                  sec, insn->offset);
-                                       warnings++;
+                                       return 1;
                                }
                                state |= STATE_FP_SETUP;
                        }
@@ -875,9 +876,9 @@ static int validate_branch(struct objtool_file *file,
                        if (!nofp && has_modified_stack_frame(insn)) {
                                WARN_FUNC("return without frame pointer 
restore",
                                          sec, insn->offset);
-                               warnings++;
+                               return 1;
                        }
-                       return warnings;
+                       return 0;
 
                case INSN_CALL:
                        if (is_fentry_call(insn)) {
@@ -887,16 +888,16 @@ static int validate_branch(struct objtool_file *file,
 
                        ret = dead_end_function(file, insn->call_dest);
                        if (ret == 1)
-                               return warnings;
+                               return 0;
                        if (ret == -1)
-                               warnings++;
+                               return 1;
 
                        /* fallthrough */
                case INSN_CALL_DYNAMIC:
                        if (!nofp && !has_valid_stack_frame(insn)) {
                                WARN_FUNC("call without frame pointer 
save/setup",
                                          sec, insn->offset);
-                               warnings++;
+                               return 1;
                        }
                        break;
 
@@ -905,15 +906,16 @@ static int validate_branch(struct objtool_file *file,
                        if (insn->jump_dest) {
                                ret = validate_branch(file, insn->jump_dest,
                                                      state);
-                               warnings += ret;
+                               if (ret)
+                                       return 1;
                        } else if (has_modified_stack_frame(insn)) {
                                WARN_FUNC("sibling call from callable 
instruction with changed frame pointer",
                                          sec, insn->offset);
-                               warnings++;
+                               return 1;
                        } /* else it's a sibling call */
 
                        if (insn->type == INSN_JUMP_UNCONDITIONAL)
-                               return warnings;
+                               return 0;
 
                        break;
 
@@ -922,13 +924,13 @@ static int validate_branch(struct objtool_file *file,
                            has_modified_stack_frame(insn)) {
                                WARN_FUNC("sibling call from callable 
instruction with changed frame pointer",
                                          sec, insn->offset);
-                               warnings++;
+                               return 1;
                        }
 
-                       return warnings;
+                       return 0;
 
                case INSN_BUG:
-                       return warnings;
+                       return 0;
 
                default:
                        break;
@@ -937,12 +939,11 @@ static int validate_branch(struct objtool_file *file,
                insn = next_insn_same_sec(file, insn);
                if (!insn) {
                        WARN("%s: unexpected end of section", sec->name);
-                       warnings++;
-                       return warnings;
+                       return 1;
                }
        }
 
-       return warnings;
+       return 0;
 }
 
 static bool is_gcov_insn(struct instruction *insn)
@@ -1055,7 +1056,8 @@ static int validate_functions(struct objtool_file *file)
                                if (insn->visited)
                                        continue;
 
-                               if (!ignore_unreachable_insn(func, insn)) {
+                               if (!ignore_unreachable_insn(func, insn) &&
+                                   !warnings) {
                                        WARN_FUNC("function has unreachable 
instruction", insn->sec, insn->offset);
                                        warnings++;
                                }

Reply via email to