summaryrefslogtreecommitdiff
path: root/include/asm-ppc
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2003-06-06 23:14:11 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2003-06-06 23:14:11 -0700
commitf822f1510915fd6cc8906556e23d2e28defba7cd (patch)
treed66bfaa6dcd85e000e058be67ab6b86715a6b0bb /include/asm-ppc
parent1eb83e09834fe260003242be9aeb0cee7d0e5dc4 (diff)
[PATCH] Move BUG/BUG_ON/WARN_ON to asm headers
This patch moves the definitions of BUG, BUG_ON and WARN_ON from <linux/kernel.h> to <asm/bug.h> (which <linux/kernel.h> includes), and supplies a new implementation for PPC which uses a conditional trap instruction for BUG_ON and WARN_ON, thus avoiding a conditional branch. This patch trims over 50kB from the size of the kernel that I use on powermacs. With this patch, on PPC we have a __bug_table section in the vmlinux binary, and also in modules if they use BUG, BUG_ON or WARN_ON. The __bug_table section has one entry for each BUG/BUG_ON/WARN_ON, giving the address of the trap instruction and the corresponding line number, filename and function name. This information is used in the exception handler for the exception that the trap instruction produces. The arch-specific module code handles the __bug_table section so that BUG/BUG_ON/WARN_ON work correctly in modules. Several architecture maintainers have acked this change. It should be completely benign for all of the other architectures (though they may decide to do something similar if they have a conditional trap instruction available).
Diffstat (limited to 'include/asm-ppc')
-rw-r--r--include/asm-ppc/bug.h43
-rw-r--r--include/asm-ppc/module.h10
2 files changed, 50 insertions, 3 deletions
diff --git a/include/asm-ppc/bug.h b/include/asm-ppc/bug.h
index bfc896f2daa1..ff3be2d387bf 100644
--- a/include/asm-ppc/bug.h
+++ b/include/asm-ppc/bug.h
@@ -1,11 +1,48 @@
#ifndef _PPC_BUG_H
#define _PPC_BUG_H
-#define BUG() do { \
- printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
- __asm__ __volatile__(".long 0x0"); \
+struct bug_entry {
+ unsigned long bug_addr;
+ int line;
+ const char *file;
+ const char *function;
+};
+
+/*
+ * If this bit is set in the line number it means that the trap
+ * is for WARN_ON rather than BUG or BUG_ON.
+ */
+#define BUG_WARNING_TRAP 0x1000000
+
+#define BUG() do { \
+ __asm__ __volatile__( \
+ "1: twi 31,0,0\n" \
+ ".section __bug_table,\"a\"\n\t" \
+ " .long 1b,%0,%1,%2\n" \
+ ".previous" \
+ : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
+} while (0)
+
+#define BUG_ON(x) do { \
+ __asm__ __volatile__( \
+ "1: twnei %0,0\n" \
+ ".section __bug_table,\"a\"\n\t" \
+ " .long 1b,%1,%2,%3\n" \
+ ".previous" \
+ : : "r" (x), "i" (__LINE__), "i" (__FILE__), \
+ "i" (__FUNCTION__)); \
} while (0)
#define PAGE_BUG(page) do { BUG(); } while (0)
+#define WARN_ON(x) do { \
+ __asm__ __volatile__( \
+ "1: twnei %0,0\n" \
+ ".section __bug_table,\"a\"\n\t" \
+ " .long 1b,%1,%2,%3\n" \
+ ".previous" \
+ : : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP), \
+ "i" (__FILE__), "i" (__FUNCTION__)); \
+} while (0)
+
#endif
diff --git a/include/asm-ppc/module.h b/include/asm-ppc/module.h
index 01ed28a9f30e..fb63492562b0 100644
--- a/include/asm-ppc/module.h
+++ b/include/asm-ppc/module.h
@@ -2,6 +2,9 @@
#define _ASM_PPC_MODULE_H
/* Module stuff for PPC. (C) 2001 Rusty Russell */
+#include <linux/list.h>
+#include <asm/bug.h>
+
/* Thanks to Paul M for explaining this.
PPC can only do rel jumps += 32MB, and often the kernel and other
@@ -20,8 +23,15 @@ struct mod_arch_specific
{
/* Indices of PLT sections within module. */
unsigned int core_plt_section, init_plt_section;
+
+ /* List of BUG addresses, source line numbers and filenames */
+ struct list_head bug_list;
+ struct bug_entry *bug_table;
+ unsigned int num_bugs;
};
+extern struct bug_entry *module_find_bug(unsigned long bugaddr);
+
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr