summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@redhat.com>2016-03-09 01:07:01 -0500
committerIngo Molnar <mingo@kernel.org>2016-03-09 04:48:10 -0500
commit1bcb58a099938c33acda78b212ed67b06b3359ef (patch)
tree24dfb31e7f6c4c953314afdf4cfdefc5147be5bc /tools
parent042ba73fe7eb63872ee2d6ac86410052210c1f16 (diff)
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 <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>
Diffstat (limited to 'tools')
-rw-r--r--tools/objtool/builtin-check.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index bfeee227aaab..7515cb2e879a 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,
800 struct instruction *insn; 800 struct instruction *insn;
801 struct section *sec; 801 struct section *sec;
802 unsigned char state; 802 unsigned char state;
803 int ret, warnings = 0; 803 int ret;
804 804
805 insn = first; 805 insn = first;
806 sec = insn->sec; 806 sec = insn->sec;
@@ -809,7 +809,7 @@ static int validate_branch(struct objtool_file *file,
809 if (insn->alt_group && list_empty(&insn->alts)) { 809 if (insn->alt_group && list_empty(&insn->alts)) {
810 WARN_FUNC("don't know how to handle branch to middle of alternative instruction group", 810 WARN_FUNC("don't know how to handle branch to middle of alternative instruction group",
811 sec, insn->offset); 811 sec, insn->offset);
812 warnings++; 812 return 1;
813 } 813 }
814 814
815 while (1) { 815 while (1) {
@@ -817,10 +817,10 @@ static int validate_branch(struct objtool_file *file,
817 if (frame_state(insn->state) != frame_state(state)) { 817 if (frame_state(insn->state) != frame_state(state)) {
818 WARN_FUNC("frame pointer state mismatch", 818 WARN_FUNC("frame pointer state mismatch",
819 sec, insn->offset); 819 sec, insn->offset);
820 warnings++; 820 return 1;
821 } 821 }
822 822
823 return warnings; 823 return 0;
824 } 824 }
825 825
826 /* 826 /*
@@ -828,14 +828,15 @@ static int validate_branch(struct objtool_file *file,
828 * the next function. 828 * the next function.
829 */ 829 */
830 if (is_fentry_call(insn) && (state & STATE_FENTRY)) 830 if (is_fentry_call(insn) && (state & STATE_FENTRY))
831 return warnings; 831 return 0;
832 832
833 insn->visited = true; 833 insn->visited = true;
834 insn->state = state; 834 insn->state = state;
835 835
836 list_for_each_entry(alt, &insn->alts, list) { 836 list_for_each_entry(alt, &insn->alts, list) {
837 ret = validate_branch(file, alt->insn, state); 837 ret = validate_branch(file, alt->insn, state);
838 warnings += ret; 838 if (ret)
839 return 1;
839 } 840 }
840 841
841 switch (insn->type) { 842 switch (insn->type) {
@@ -845,7 +846,7 @@ static int validate_branch(struct objtool_file *file,
845 if (state & STATE_FP_SAVED) { 846 if (state & STATE_FP_SAVED) {
846 WARN_FUNC("duplicate frame pointer save", 847 WARN_FUNC("duplicate frame pointer save",
847 sec, insn->offset); 848 sec, insn->offset);
848 warnings++; 849 return 1;
849 } 850 }
850 state |= STATE_FP_SAVED; 851 state |= STATE_FP_SAVED;
851 } 852 }
@@ -856,7 +857,7 @@ static int validate_branch(struct objtool_file *file,
856 if (state & STATE_FP_SETUP) { 857 if (state & STATE_FP_SETUP) {
857 WARN_FUNC("duplicate frame pointer setup", 858 WARN_FUNC("duplicate frame pointer setup",
858 sec, insn->offset); 859 sec, insn->offset);
859 warnings++; 860 return 1;
860 } 861 }
861 state |= STATE_FP_SETUP; 862 state |= STATE_FP_SETUP;
862 } 863 }
@@ -875,9 +876,9 @@ static int validate_branch(struct objtool_file *file,
875 if (!nofp && has_modified_stack_frame(insn)) { 876 if (!nofp && has_modified_stack_frame(insn)) {
876 WARN_FUNC("return without frame pointer restore", 877 WARN_FUNC("return without frame pointer restore",
877 sec, insn->offset); 878 sec, insn->offset);
878 warnings++; 879 return 1;
879 } 880 }
880 return warnings; 881 return 0;
881 882
882 case INSN_CALL: 883 case INSN_CALL:
883 if (is_fentry_call(insn)) { 884 if (is_fentry_call(insn)) {
@@ -887,16 +888,16 @@ static int validate_branch(struct objtool_file *file,
887 888
888 ret = dead_end_function(file, insn->call_dest); 889 ret = dead_end_function(file, insn->call_dest);
889 if (ret == 1) 890 if (ret == 1)
890 return warnings; 891 return 0;
891 if (ret == -1) 892 if (ret == -1)
892 warnings++; 893 return 1;
893 894
894 /* fallthrough */ 895 /* fallthrough */
895 case INSN_CALL_DYNAMIC: 896 case INSN_CALL_DYNAMIC:
896 if (!nofp && !has_valid_stack_frame(insn)) { 897 if (!nofp && !has_valid_stack_frame(insn)) {
897 WARN_FUNC("call without frame pointer save/setup", 898 WARN_FUNC("call without frame pointer save/setup",
898 sec, insn->offset); 899 sec, insn->offset);
899 warnings++; 900 return 1;
900 } 901 }
901 break; 902 break;
902 903
@@ -905,15 +906,16 @@ static int validate_branch(struct objtool_file *file,
905 if (insn->jump_dest) { 906 if (insn->jump_dest) {
906 ret = validate_branch(file, insn->jump_dest, 907 ret = validate_branch(file, insn->jump_dest,
907 state); 908 state);
908 warnings += ret; 909 if (ret)
910 return 1;
909 } else if (has_modified_stack_frame(insn)) { 911 } else if (has_modified_stack_frame(insn)) {
910 WARN_FUNC("sibling call from callable instruction with changed frame pointer", 912 WARN_FUNC("sibling call from callable instruction with changed frame pointer",
911 sec, insn->offset); 913 sec, insn->offset);
912 warnings++; 914 return 1;
913 } /* else it's a sibling call */ 915 } /* else it's a sibling call */
914 916
915 if (insn->type == INSN_JUMP_UNCONDITIONAL) 917 if (insn->type == INSN_JUMP_UNCONDITIONAL)
916 return warnings; 918 return 0;
917 919
918 break; 920 break;
919 921
@@ -922,13 +924,13 @@ static int validate_branch(struct objtool_file *file,
922 has_modified_stack_frame(insn)) { 924 has_modified_stack_frame(insn)) {
923 WARN_FUNC("sibling call from callable instruction with changed frame pointer", 925 WARN_FUNC("sibling call from callable instruction with changed frame pointer",
924 sec, insn->offset); 926 sec, insn->offset);
925 warnings++; 927 return 1;
926 } 928 }
927 929
928 return warnings; 930 return 0;
929 931
930 case INSN_BUG: 932 case INSN_BUG:
931 return warnings; 933 return 0;
932 934
933 default: 935 default:
934 break; 936 break;
@@ -937,12 +939,11 @@ static int validate_branch(struct objtool_file *file,
937 insn = next_insn_same_sec(file, insn); 939 insn = next_insn_same_sec(file, insn);
938 if (!insn) { 940 if (!insn) {
939 WARN("%s: unexpected end of section", sec->name); 941 WARN("%s: unexpected end of section", sec->name);
940 warnings++; 942 return 1;
941 return warnings;
942 } 943 }
943 } 944 }
944 945
945 return warnings; 946 return 0;
946} 947}
947 948
948static bool is_gcov_insn(struct instruction *insn) 949static bool is_gcov_insn(struct instruction *insn)
@@ -1055,7 +1056,8 @@ static int validate_functions(struct objtool_file *file)
1055 if (insn->visited) 1056 if (insn->visited)
1056 continue; 1057 continue;
1057 1058
1058 if (!ignore_unreachable_insn(func, insn)) { 1059 if (!ignore_unreachable_insn(func, insn) &&
1060 !warnings) {
1059 WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset); 1061 WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset);
1060 warnings++; 1062 warnings++;
1061 } 1063 }