[PATCH 10/27] objtool: Add ANNOTATE_IGNORE_NORETURN()
Josh Poimboeuf <[email protected]>
| Newsgroups | gmane.linux.kernel.rust,gmane.linux.kernel,gmane.linux.kbuild.devel |
|---|---|
| Message-ID | <49da10e66e03e9acdbb66677afe5b4a89500ba79.1787890035.git.jpoimboe@kernel.org> |
A generic interface may be noreturn in one arch and returnable in another, in which case its common declaration can't say __noreturn. Rust has a similar issue where a few core library calls to returnable functions are replaced after compilation with calls to a noreturn panic function. Add an annotation which tells objtool to ignore the noreturn status of a given function. Signed-off-by: Josh Poimboeuf <[email protected]> --- include/linux/annotate.h | 7 +++++++ include/linux/objtool_types.h | 1 + tools/include/linux/objtool_types.h | 1 + tools/objtool/check.c | 19 +++++++++++++++++++ tools/objtool/include/objtool/elf.h | 1 + 5 files changed, 29 insertions(+) diff --git a/include/linux/annotate.h b/include/linux/annotate.h index 2f1599c9e5732..a81ca04b4c501 100644 --- a/include/linux/annotate.h +++ b/include/linux/annotate.h @@ -3,6 +3,7 @@ #define _LINUX_ANNOTATE_H #include <linux/objtool_types.h> +#include <linux/stringify.h> #ifdef CONFIG_OBJTOOL @@ -105,6 +106,12 @@ */ #define ANNOTATE_NOCFI_SYM(sym) asm(ASM_ANNOTATE_LABEL(sym, ANNOTYPE_NOCFI)) +/* + * Treat a function as returnable by its callers despite objtool classifying it + * as noreturn. + */ +#define ANNOTATE_IGNORE_NORETURN(sym) asm(ASM_ANNOTATE_LABEL(sym, ANNOTYPE_IGNORE_NORETURN)) + /* * Annotate a special section entry. This emables livepatch module generation * to find and extract individual special section entries as needed. diff --git a/include/linux/objtool_types.h b/include/linux/objtool_types.h index c24e9ea392696..ce08ecc808c67 100644 --- a/include/linux/objtool_types.h +++ b/include/linux/objtool_types.h @@ -66,6 +66,7 @@ struct unwind_hint { #define ANNOTYPE_INTRA_FUNCTION_CALL 7 #define ANNOTYPE_REACHABLE 8 #define ANNOTYPE_NOCFI 9 +#define ANNOTYPE_IGNORE_NORETURN 10 #define ANNOTYPE_DATA_SPECIAL 1 diff --git a/tools/include/linux/objtool_types.h b/tools/include/linux/objtool_types.h index c24e9ea392696..ce08ecc808c67 100644 --- a/tools/include/linux/objtool_types.h +++ b/tools/include/linux/objtool_types.h @@ -66,6 +66,7 @@ struct unwind_hint { #define ANNOTYPE_INTRA_FUNCTION_CALL 7 #define ANNOTYPE_REACHABLE 8 #define ANNOTYPE_NOCFI 9 +#define ANNOTYPE_IGNORE_NORETURN 10 #define ANNOTYPE_DATA_SPECIAL 1 diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 7333b0ed86818..ddb8dbe7f71d9 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -246,6 +246,9 @@ static bool is_noreturn(struct symbol *func) { func = func->alias->pfunc; + if (func->ignore_noreturn) + return false; + if (is_listed_noreturn(func)) return true; @@ -2389,6 +2392,18 @@ static int __annotate_early(struct objtool_file *file, int type, struct instruct insn->noendbr = 1; break; + /* Must be before detect_noreturns() */ + case ANNOTYPE_IGNORE_NORETURN: { + struct symbol *sym = insn_sym(insn); + + if (!sym) { + ERROR_INSN(insn, "dodgy IGNORE_NORETURN annotation"); + return -1; + } + sym->ignore_noreturn = 1; + break; + } + default: break; } @@ -2435,6 +2450,10 @@ static int __annotate_late(struct objtool_file *file, int type, struct instructi /* early */ break; + case ANNOTYPE_IGNORE_NORETURN: + /* early */ + break; + case ANNOTYPE_RETPOLINE_SAFE: if (insn->type != INSN_JUMP_DYNAMIC && insn->type != INSN_CALL_DYNAMIC && diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h index 46fb2230ca743..0e3593d993ac8 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -99,6 +99,7 @@ struct symbol { u8 dont_correlate : 1; u8 fake : 1; u8 _noreturn : 1; + u8 ignore_noreturn : 1; struct list_head pv_target; struct reloc *relocs; struct section *group_sec; -- 2.55.0