diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-generic/bug.h | 16 | ||||
-rw-r--r-- | include/asm-generic/vmlinux.lds.h | 8 | ||||
-rw-r--r-- | include/linux/bug.h | 47 | ||||
-rw-r--r-- | include/linux/module.h | 7 |
4 files changed, 78 insertions, 0 deletions
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index c92ae0f166ff..47e3561638b1 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -4,6 +4,22 @@ #include <linux/compiler.h> #ifdef CONFIG_BUG + +#ifdef CONFIG_GENERIC_BUG +#ifndef __ASSEMBLY__ +struct bug_entry { + unsigned long bug_addr; +#ifdef CONFIG_DEBUG_BUGVERBOSE + const char *file; + unsigned short line; +#endif + unsigned short flags; +}; +#endif /* __ASSEMBLY__ */ + +#define BUGFLAG_WARNING (1<<0) +#endif /* CONFIG_GENERIC_BUG */ + #ifndef HAVE_ARCH_BUG #define BUG() do { \ printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \ diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 4d4c62d11059..6e9fcebbf89f 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -218,6 +218,14 @@ .stab.indexstr 0 : { *(.stab.indexstr) } \ .comment 0 : { *(.comment) } +#define BUG_TABLE \ + . = ALIGN(8); \ + __bug_table : AT(ADDR(__bug_table) - LOAD_OFFSET) { \ + __start___bug_table = .; \ + *(__bug_table) \ + __stop___bug_table = .; \ + } + #define NOTES \ .notes : { *(.note.*) } :note diff --git a/include/linux/bug.h b/include/linux/bug.h new file mode 100644 index 000000000000..42aa0a54b6f4 --- /dev/null +++ b/include/linux/bug.h @@ -0,0 +1,47 @@ +#ifndef _LINUX_BUG_H +#define _LINUX_BUG_H + +#include <linux/module.h> +#include <asm/bug.h> + +enum bug_trap_type { + BUG_TRAP_TYPE_NONE = 0, + BUG_TRAP_TYPE_WARN = 1, + BUG_TRAP_TYPE_BUG = 2, +}; + +#ifdef CONFIG_GENERIC_BUG +#include <asm-generic/bug.h> + +static inline int is_warning_bug(const struct bug_entry *bug) +{ + return bug->flags & BUGFLAG_WARNING; +} + +const struct bug_entry *find_bug(unsigned long bugaddr); + +enum bug_trap_type report_bug(unsigned long bug_addr); + +int module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, + struct module *); +void module_bug_cleanup(struct module *); + +/* These are defined by the architecture */ +int is_valid_bugaddr(unsigned long addr); + +#else /* !CONFIG_GENERIC_BUG */ + +static inline enum bug_trap_type report_bug(unsigned long bug_addr) +{ + return BUG_TRAP_TYPE_BUG; +} +static inline int module_bug_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + struct module *mod) +{ + return 0; +} +static inline void module_bug_cleanup(struct module *mod) {} + +#endif /* CONFIG_GENERIC_BUG */ +#endif /* _LINUX_BUG_H */ diff --git a/include/linux/module.h b/include/linux/module.h index d33df2408e05..10f771a49997 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -319,6 +319,13 @@ struct module unsigned int taints; /* same bits as kernel:tainted */ +#ifdef CONFIG_GENERIC_BUG + /* Support for BUG */ + struct list_head bug_list; + struct bug_entry *bug_table; + unsigned num_bugs; +#endif + #ifdef CONFIG_MODULE_UNLOAD /* Reference counts */ struct module_ref ref[NR_CPUS]; |