Merge branch 'next/deletion' of git://git.linaro.org/people/arnd/arm-soc
[pandora-kernel.git] / arch / arm / include / asm / bug.h
index 4d88425..9abe7a0 100644 (file)
@@ -3,21 +3,58 @@
 
 
 #ifdef CONFIG_BUG
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-extern void __bug(const char *file, int line) __attribute__((noreturn));
-
-/* give file/line information */
-#define BUG()          __bug(__FILE__, __LINE__)
 
+/*
+ * Use a suitable undefined instruction to use for ARM/Thumb2 bug handling.
+ * We need to be careful not to conflict with those used by other modules and
+ * the register_undef_hook() system.
+ */
+#ifdef CONFIG_THUMB2_KERNEL
+#define BUG_INSTR_VALUE 0xde02
+#define BUG_INSTR_TYPE ".hword "
 #else
+#define BUG_INSTR_VALUE 0xe7f001f2
+#define BUG_INSTR_TYPE ".word "
+#endif
 
-/* this just causes an oops */
-#define BUG()          do { *(int *)0 = 0; } while (1)
 
-#endif
+#define BUG() _BUG(__FILE__, __LINE__, BUG_INSTR_VALUE)
+#define _BUG(file, line, value) __BUG(file, line, value)
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+
+/*
+ * The extra indirection is to ensure that the __FILE__ string comes through
+ * OK. Many version of gcc do not support the asm %c parameter which would be
+ * preferable to this unpleasantness. We use mergeable string sections to
+ * avoid multiple copies of the string appearing in the kernel image.
+ */
+
+#define __BUG(__file, __line, __value)                         \
+do {                                                           \
+       BUILD_BUG_ON(sizeof(struct bug_entry) != 12);           \
+       asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n"        \
+               ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
+               "2:\t.asciz " #__file "\n"                      \
+               ".popsection\n"                                 \
+               ".pushsection __bug_table,\"a\"\n"              \
+               "3:\t.word 1b, 2b\n"                            \
+               "\t.hword " #__line ", 0\n"                     \
+               ".popsection");                                 \
+       unreachable();                                          \
+} while (0)
+
+#else  /* not CONFIG_DEBUG_BUGVERBOSE */
+
+#define __BUG(__file, __line, __value)                         \
+do {                                                           \
+       asm volatile(BUG_INSTR_TYPE #__value);                  \
+       unreachable();                                          \
+} while (0)
+#endif  /* CONFIG_DEBUG_BUGVERBOSE */
 
 #define HAVE_ARCH_BUG
-#endif
+#endif  /* CONFIG_BUG */
 
 #include <asm-generic/bug.h>