[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.