summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@redhat.com>2017-02-21 15:35:32 -0600
committerIngo Molnar <mingo@kernel.org>2017-02-24 09:10:52 +0100
commitd1091c7fa3d52ebce4dd3f15d04155b3469b2f90 (patch)
treea56b8cc4e12f90c21c26bde0d49996c00c2341ef /include
parent9f0c18aec620bc9d82268b3cb937568dd07b43ff (diff)
downloadlinux-d1091c7fa3d52ebce4dd3f15d04155b3469b2f90.tar.gz
linux-d1091c7fa3d52ebce4dd3f15d04155b3469b2f90.tar.xz
objtool: Improve detection of BUG() and other dead ends
The BUG() macro's use of __builtin_unreachable() via the unreachable() macro tells gcc that the instruction is a dead end, and that it's safe to assume the current code path will not execute past the previous instruction. On x86, the BUG() macro is implemented with the 'ud2' instruction. When objtool's branch analysis sees that instruction, it knows the current code path has come to a dead end. Peter Zijlstra has been working on a patch to change the WARN macros to use 'ud2'. That patch will break objtool's assumption that 'ud2' is always a dead end. Generally it's best for objtool to avoid making those kinds of assumptions anyway. The more ignorant it is of kernel code internals, the better. So create a more generic way for objtool to detect dead ends by adding an annotation to the unreachable() macro. The annotation stores a pointer to the end of the unreachable code path in an '__unreachable' section. Objtool can read that section to find the dead ends. Tested-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/41a6d33971462ebd944a1c60ad4bf5be86c17b77.1487712920.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/compiler-gcc.h13
1 files changed, 12 insertions, 1 deletions
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 0444b1336268..8ea159fc489d 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -195,6 +195,17 @@
#endif
#endif
+#ifdef CONFIG_STACK_VALIDATION
+#define annotate_unreachable() ({ \
+ asm("1:\t\n" \
+ ".pushsection __unreachable, \"a\"\t\n" \
+ ".long 1b\t\n" \
+ ".popsection\t\n"); \
+})
+#else
+#define annotate_unreachable()
+#endif
+
/*
* Mark a position in code as unreachable. This can be used to
* suppress control flow warnings after asm blocks that transfer
@@ -204,7 +215,7 @@
* this in the preprocessor, but we can live with this because they're
* unreleased. Really, we need to have autoconf for the kernel.
*/
-#define unreachable() __builtin_unreachable()
+#define unreachable() annotate_unreachable(); __builtin_unreachable()
/* Mark a function definition as prohibited from being cloned. */
#define __noclone __attribute__((__noclone__, __optimize__("no-tracer")))