Skip to content

Commit

Permalink
objtool: Only print one warning per function
Browse files Browse the repository at this point in the history
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 <mingo@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Bernd Petrovitsch <bernd@petrovitsch.priv.at>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Chris J Arges <chris.j.arges@canonical.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Pedro Alves <palves@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: live-patching@vger.kernel.org
Link: http://lkml.kernel.org/r/c47f3ca38aa01e2a9b6601f9e38efd414c3f3c18.1457502970.git.jpoimboe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Josh Poimboeuf authored and Ingo Molnar committed Mar 9, 2016
1 parent 042ba73 commit 1bcb58a
Showing 1 changed file with 25 additions and 23 deletions.
48 changes: 25 additions & 23 deletions tools/objtool/builtin-check.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -809,33 +809,34 @@ 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) {
if (insn->visited) {
if (frame_state(insn->state) != frame_state(state)) {
WARN_FUNC("frame pointer state mismatch",
sec, insn->offset);
warnings++;
return 1;
}

return warnings;
return 0;
}

/*
* Catch a rare case where a noreturn function falls through to
* 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) {
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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)) {
Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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++;
}
Expand Down

0 comments on commit 1bcb58a

Please sign in to comment.