Commit 08ef8c40 authored by Peter Zijlstra's avatar Peter Zijlstra

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: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220915111146.434642471@infradead.org
parent 5da6aea3
...@@ -128,7 +128,6 @@ SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL) ...@@ -128,7 +128,6 @@ SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL)
popfq popfq
jmp .Lsysenter_flags_fixed jmp .Lsysenter_flags_fixed
SYM_INNER_LABEL(__end_entry_SYSENTER_compat, SYM_L_GLOBAL) SYM_INNER_LABEL(__end_entry_SYSENTER_compat, SYM_L_GLOBAL)
ANNOTATE_NOENDBR // is_sysenter_singlestep
SYM_CODE_END(entry_SYSENTER_compat) SYM_CODE_END(entry_SYSENTER_compat)
/* /*
......
...@@ -4033,6 +4033,24 @@ static void mark_endbr_used(struct instruction *insn) ...@@ -4033,6 +4033,24 @@ static void mark_endbr_used(struct instruction *insn)
list_del_init(&insn->call_node); 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) static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn)
{ {
struct instruction *dest; struct instruction *dest;
...@@ -4105,9 +4123,19 @@ static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn ...@@ -4105,9 +4123,19 @@ static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn
continue; continue;
} }
/*
* Accept anything ANNOTATE_NOENDBR.
*/
if (dest->noendbr) if (dest->noendbr)
continue; 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", WARN_FUNC("relocation to !ENDBR: %s",
insn->sec, insn->offset, insn->sec, insn->offset,
offstr(dest->sec, dest->offset)); offstr(dest->sec, dest->offset));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment