[PATCH 21/27] objtool: Fix noreturn detection for non-sibling jumps to SYM_CODE
Josh Poimboeuf <[email protected]>
| Newsgroups | gmane.linux.kernel,gmane.linux.kernel.rust,gmane.linux.kbuild.devel |
|---|---|
| Message-ID | <d8a6c30639aca44db48dacd979049d2b90d15f34.1787890035.git.jpoimboe@kernel.org> |
Objtool doesn't consider a jump to be a sibling call if the destination isn't a function, so srso_alias_untrain_ret()'s jump to srso_alias_return_thunk() is ignored by objtool and the former is falsely classified as noreturn. Change the noreturn detection to consider such cases as effectively sibling calls, except for one known exception: jumping to .altinstr_aux. Currently the misclassification is harmless: dead ends aren't marked when calling a noreturn from an alternative replacement (CALL_UNTRAIN_RET), they're ignored by rethunk validation, and ORC generation relies on unwind hints in the SRSO code regardless. Fix it in the name of robustness and in preparation for a subsequent patch which generates a list of exported noreturns. Signed-off-by: Josh Poimboeuf <[email protected]> --- tools/objtool/check.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index c55851ec389cd..d27303220c29d 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -264,8 +264,22 @@ static bool might_return(struct objtool_file *file, struct symbol *func) if (insn->type == INSN_RETURN) return true; - if (!is_sibling_call(insn)) + if (!is_sibling_call(insn)) { + /* + * Assume a jump into a non-function eventually returns + * to the original caller one way or another, e.g., the + * jump in srso_alias_untrain_ret(). + * + * .altinstr_aux is an exception, cpu_feature_enabled() + * jumps there and then right back. + */ + if (is_static_jump(insn) && insn->jump_dest && + !insn_func(insn->jump_dest) && + strcmp(insn->jump_dest->sec->name, ".altinstr_aux")) + return true; + continue; + } dest = insn_call_dest(insn); if (!dest || !is_noreturn(dest)) -- 2.55.0