summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@redhat.com>2018-05-09 22:39:14 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-06-05 11:46:09 +0200
commitb3ab9104f4b7ac41668602bff01a93c753ac5304 (patch)
tree3e9f804fc8a052eaaff986ff524c23dd69f9ee21
parentc3752344435b2657aebd54b1eb47612faf473229 (diff)
downloadlinux-stable-b3ab9104f4b7ac41668602bff01a93c753ac5304.tar.gz
linux-stable-b3ab9104f4b7ac41668602bff01a93c753ac5304.tar.bz2
linux-stable-b3ab9104f4b7ac41668602bff01a93c753ac5304.zip
objtool: Fix "noreturn" detection for recursive sibling calls
commit 0afd0d9e0e7879d666c1df2fa1bea4d8716909fe upstream. Objtool has some crude logic for detecting static "noreturn" functions (aka "dead ends"). This is necessary for being able to correctly follow GCC code flow when such functions are called. It's remotely possible for two functions to call each other via sibling calls. If they don't have RET instructions, objtool's noreturn detection logic goes into a recursive loop: drivers/char/ipmi/ipmi_ssif.o: warning: objtool: return_hosed_msg()+0x0: infinite recursion (objtool bug!) drivers/char/ipmi/ipmi_ssif.o: warning: objtool: deliver_recv_msg()+0x0: infinite recursion (objtool bug!) Instead of reporting an error in this case, consider the functions to be non-dead-ends. Reported-and-tested-by: Randy Dunlap <rdunlap@infradead.org> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: David Laight <David.Laight@ACULAB.COM> Cc: Greg KH <gregkh@linuxfoundation.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: damian <damian.tometzki@icloud.com> Link: http://lkml.kernel.org/r/7cc156408c5781a1f62085d352ced1fe39fe2f91.1525923412.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--tools/objtool/check.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index eced57bc6455..3a31b238f885 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -208,9 +208,13 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
/* local sibling call */
if (recursion == 5) {
- WARN_FUNC("infinite recursion (objtool bug!)",
- dest->sec, dest->offset);
- return -1;
+ /*
+ * Infinite recursion: two functions
+ * have sibling calls to each other.
+ * This is a very rare case. It means
+ * they aren't dead ends.
+ */
+ return 0;
}
return __dead_end_function(file, dest->func,