aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/objtool/builtin-check.c57
1 files changed, 26 insertions, 31 deletions
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index a00a05d287e7..4490601a9235 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -97,6 +97,19 @@ static struct instruction *next_insn_same_sec(struct objtool_file *file,
97 return next; 97 return next;
98} 98}
99 99
100static bool gcov_enabled(struct objtool_file *file)
101{
102 struct section *sec;
103 struct symbol *sym;
104
105 list_for_each_entry(sec, &file->elf->sections, list)
106 list_for_each_entry(sym, &sec->symbol_list, list)
107 if (!strncmp(sym->name, "__gcov_.", 8))
108 return true;
109
110 return false;
111}
112
100#define for_each_insn(file, insn) \ 113#define for_each_insn(file, insn) \
101 list_for_each_entry(insn, &file->insn_list, list) 114 list_for_each_entry(insn, &file->insn_list, list)
102 115
@@ -1041,34 +1054,6 @@ static int validate_branch(struct objtool_file *file,
1041 return 0; 1054 return 0;
1042} 1055}
1043 1056
1044static bool is_gcov_insn(struct instruction *insn)
1045{
1046 struct rela *rela;
1047 struct section *sec;
1048 struct symbol *sym;
1049 unsigned long offset;
1050
1051 rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
1052 if (!rela)
1053 return false;
1054
1055 if (rela->sym->type != STT_SECTION)
1056 return false;
1057
1058 sec = rela->sym->sec;
1059 offset = rela->addend + insn->offset + insn->len - rela->offset;
1060
1061 list_for_each_entry(sym, &sec->symbol_list, list) {
1062 if (sym->type != STT_OBJECT)
1063 continue;
1064
1065 if (offset >= sym->offset && offset < sym->offset + sym->len)
1066 return (!memcmp(sym->name, "__gcov0.", 8));
1067 }
1068
1069 return false;
1070}
1071
1072static bool is_kasan_insn(struct instruction *insn) 1057static bool is_kasan_insn(struct instruction *insn)
1073{ 1058{
1074 return (insn->type == INSN_CALL && 1059 return (insn->type == INSN_CALL &&
@@ -1090,9 +1075,6 @@ static bool ignore_unreachable_insn(struct symbol *func,
1090 if (insn->type == INSN_NOP) 1075 if (insn->type == INSN_NOP)
1091 return true; 1076 return true;
1092 1077
1093 if (is_gcov_insn(insn))
1094 return true;
1095
1096 /* 1078 /*
1097 * Check if this (or a subsequent) instruction is related to 1079 * Check if this (or a subsequent) instruction is related to
1098 * CONFIG_UBSAN or CONFIG_KASAN. 1080 * CONFIG_UBSAN or CONFIG_KASAN.
@@ -1153,6 +1135,19 @@ static int validate_functions(struct objtool_file *file)
1153 ignore_unreachable_insn(func, insn)) 1135 ignore_unreachable_insn(func, insn))
1154 continue; 1136 continue;
1155 1137
1138 /*
1139 * gcov produces a lot of unreachable
1140 * instructions. If we get an unreachable
1141 * warning and the file has gcov enabled, just
1142 * ignore it, and all other such warnings for
1143 * the file.
1144 */
1145 if (!file->ignore_unreachables &&
1146 gcov_enabled(file)) {
1147 file->ignore_unreachables = true;
1148 continue;
1149 }
1150
1156 WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset); 1151 WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset);
1157 warnings++; 1152 warnings++;
1158 } 1153 }