aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/compiler-gcc.h
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@redhat.com>2017-02-21 16:35:32 -0500
committerIngo Molnar <mingo@kernel.org>2017-02-24 03:10:52 -0500
commitd1091c7fa3d52ebce4dd3f15d04155b3469b2f90 (patch)
treea56b8cc4e12f90c21c26bde0d49996c00c2341ef /include/linux/compiler-gcc.h
parent9f0c18aec620bc9d82268b3cb937568dd07b43ff (diff)
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/linux/compiler-gcc.h')
-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 @@
195#endif 195#endif
196#endif 196#endif
197 197
198#ifdef CONFIG_STACK_VALIDATION
199#define annotate_unreachable() ({ \
200 asm("1:\t\n" \
201 ".pushsection __unreachable, \"a\"\t\n" \
202 ".long 1b\t\n" \
203 ".popsection\t\n"); \
204})
205#else
206#define annotate_unreachable()
207#endif
208
198/* 209/*
199 * Mark a position in code as unreachable. This can be used to 210 * Mark a position in code as unreachable. This can be used to
200 * suppress control flow warnings after asm blocks that transfer 211 * suppress control flow warnings after asm blocks that transfer
@@ -204,7 +215,7 @@
204 * this in the preprocessor, but we can live with this because they're 215 * this in the preprocessor, but we can live with this because they're
205 * unreleased. Really, we need to have autoconf for the kernel. 216 * unreleased. Really, we need to have autoconf for the kernel.
206 */ 217 */
207#define unreachable() __builtin_unreachable() 218#define unreachable() annotate_unreachable(); __builtin_unreachable()
208 219
209/* Mark a function definition as prohibited from being cloned. */ 220/* Mark a function definition as prohibited from being cloned. */
210#define __noclone __attribute__((__noclone__, __optimize__("no-tracer"))) 221#define __noclone __attribute__((__noclone__, __optimize__("no-tracer")))