summaryrefslogtreecommitdiff
path: root/tools/objtool
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2022-09-15 14:11:13 +0300
committerPeter Zijlstra <peterz@infradead.org>2022-10-17 17:41:08 +0300
commit08ef8c40112b8cd157515cd532f65cb82c934a76 (patch)
tree08ef77d8801a888a385cf97dcfd61f49599607b4 /tools/objtool
parent5da6aea375cde499fdfac3cde4f26df4a840eb9f (diff)
downloadlinux-08ef8c40112b8cd157515cd532f65cb82c934a76.tar.xz
objtool: Allow symbol range comparisons for IBT/ENDBR
A semi common pattern is where code checks if a code address is within a specific range. All text addresses require either ENDBR or ANNOTATE_ENDBR, however the ANNOTATE_NOENDBR past the range is unnatural. Instead, suppress this warning when this is exactly at the end of a symbol that itself starts with either ENDBR/ANNOTATE_ENDBR. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111146.434642471@infradead.org
Diffstat (limited to 'tools/objtool')
-rw-r--r--tools/objtool/check.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 1461c8894fb7..3f46f46ab85c 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -4033,6 +4033,24 @@ static void mark_endbr_used(struct instruction *insn)
list_del_init(&insn->call_node);
}
+static bool noendbr_range(struct objtool_file *file, struct instruction *insn)
+{
+ struct symbol *sym = find_symbol_containing(insn->sec, insn->offset-1);
+ struct instruction *first;
+
+ if (!sym)
+ return false;
+
+ first = find_insn(file, sym->sec, sym->offset);
+ if (!first)
+ return false;
+
+ if (first->type != INSN_ENDBR && !first->noendbr)
+ return false;
+
+ return insn->offset == sym->offset + sym->len;
+}
+
static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn)
{
struct instruction *dest;
@@ -4105,9 +4123,19 @@ static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn
continue;
}
+ /*
+ * Accept anything ANNOTATE_NOENDBR.
+ */
if (dest->noendbr)
continue;
+ /*
+ * Accept if this is the instruction after a symbol
+ * that is (no)endbr -- typical code-range usage.
+ */
+ if (noendbr_range(file, dest))
+ continue;
+
WARN_FUNC("relocation to !ENDBR: %s",
insn->sec, insn->offset,
offstr(dest->sec, dest->offset));