diff options
| -rw-r--r-- | arch/x86/Kconfig | 4 | ||||
| -rw-r--r-- | arch/x86/include/asm/bug.h | 2 | ||||
| -rw-r--r-- | include/asm-generic/bug.h | 8 | ||||
| -rw-r--r-- | lib/bug.c | 19 |
4 files changed, 30 insertions, 3 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ac22bb7719f7..ab98cca84e1b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -87,6 +87,10 @@ config GENERIC_IOMAP | |||
| 87 | config GENERIC_BUG | 87 | config GENERIC_BUG |
| 88 | def_bool y | 88 | def_bool y |
| 89 | depends on BUG | 89 | depends on BUG |
| 90 | select GENERIC_BUG_RELATIVE_POINTERS if X86_64 | ||
| 91 | |||
| 92 | config GENERIC_BUG_RELATIVE_POINTERS | ||
| 93 | bool | ||
| 90 | 94 | ||
| 91 | config GENERIC_HWEIGHT | 95 | config GENERIC_HWEIGHT |
| 92 | def_bool y | 96 | def_bool y |
diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h index 3def2065fcea..d9cf1cd156d2 100644 --- a/arch/x86/include/asm/bug.h +++ b/arch/x86/include/asm/bug.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #ifdef CONFIG_X86_32 | 9 | #ifdef CONFIG_X86_32 |
| 10 | # define __BUG_C0 "2:\t.long 1b, %c0\n" | 10 | # define __BUG_C0 "2:\t.long 1b, %c0\n" |
| 11 | #else | 11 | #else |
| 12 | # define __BUG_C0 "2:\t.quad 1b, %c0\n" | 12 | # define __BUG_C0 "2:\t.long 1b - 2b, %c0 - 2b\n" |
| 13 | #endif | 13 | #endif |
| 14 | 14 | ||
| 15 | #define BUG() \ | 15 | #define BUG() \ |
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 12c07c1866b2..4c794d73fb84 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h | |||
| @@ -8,9 +8,17 @@ | |||
| 8 | #ifdef CONFIG_GENERIC_BUG | 8 | #ifdef CONFIG_GENERIC_BUG |
| 9 | #ifndef __ASSEMBLY__ | 9 | #ifndef __ASSEMBLY__ |
| 10 | struct bug_entry { | 10 | struct bug_entry { |
| 11 | #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS | ||
| 11 | unsigned long bug_addr; | 12 | unsigned long bug_addr; |
| 13 | #else | ||
| 14 | signed int bug_addr_disp; | ||
| 15 | #endif | ||
| 12 | #ifdef CONFIG_DEBUG_BUGVERBOSE | 16 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
| 17 | #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS | ||
| 13 | const char *file; | 18 | const char *file; |
| 19 | #else | ||
| 20 | signed int file_disp; | ||
| 21 | #endif | ||
| 14 | unsigned short line; | 22 | unsigned short line; |
| 15 | #endif | 23 | #endif |
| 16 | unsigned short flags; | 24 | unsigned short flags; |
| @@ -5,6 +5,8 @@ | |||
| 5 | 5 | ||
| 6 | CONFIG_BUG - emit BUG traps. Nothing happens without this. | 6 | CONFIG_BUG - emit BUG traps. Nothing happens without this. |
| 7 | CONFIG_GENERIC_BUG - enable this code. | 7 | CONFIG_GENERIC_BUG - enable this code. |
| 8 | CONFIG_GENERIC_BUG_RELATIVE_POINTERS - use 32-bit pointers relative to | ||
| 9 | the containing struct bug_entry for bug_addr and file. | ||
| 8 | CONFIG_DEBUG_BUGVERBOSE - emit full file+line information for each BUG | 10 | CONFIG_DEBUG_BUGVERBOSE - emit full file+line information for each BUG |
| 9 | 11 | ||
| 10 | CONFIG_BUG and CONFIG_DEBUG_BUGVERBOSE are potentially user-settable | 12 | CONFIG_BUG and CONFIG_DEBUG_BUGVERBOSE are potentially user-settable |
| @@ -43,6 +45,15 @@ | |||
| 43 | 45 | ||
| 44 | extern const struct bug_entry __start___bug_table[], __stop___bug_table[]; | 46 | extern const struct bug_entry __start___bug_table[], __stop___bug_table[]; |
| 45 | 47 | ||
| 48 | static inline unsigned long bug_addr(const struct bug_entry *bug) | ||
| 49 | { | ||
| 50 | #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS | ||
| 51 | return bug->bug_addr; | ||
| 52 | #else | ||
| 53 | return (unsigned long)bug + bug->bug_addr_disp; | ||
| 54 | #endif | ||
| 55 | } | ||
| 56 | |||
| 46 | #ifdef CONFIG_MODULES | 57 | #ifdef CONFIG_MODULES |
| 47 | static LIST_HEAD(module_bug_list); | 58 | static LIST_HEAD(module_bug_list); |
| 48 | 59 | ||
| @@ -55,7 +66,7 @@ static const struct bug_entry *module_find_bug(unsigned long bugaddr) | |||
| 55 | unsigned i; | 66 | unsigned i; |
| 56 | 67 | ||
| 57 | for (i = 0; i < mod->num_bugs; ++i, ++bug) | 68 | for (i = 0; i < mod->num_bugs; ++i, ++bug) |
| 58 | if (bugaddr == bug->bug_addr) | 69 | if (bugaddr == bug_addr(bug)) |
| 59 | return bug; | 70 | return bug; |
| 60 | } | 71 | } |
| 61 | return NULL; | 72 | return NULL; |
| @@ -108,7 +119,7 @@ const struct bug_entry *find_bug(unsigned long bugaddr) | |||
| 108 | const struct bug_entry *bug; | 119 | const struct bug_entry *bug; |
| 109 | 120 | ||
| 110 | for (bug = __start___bug_table; bug < __stop___bug_table; ++bug) | 121 | for (bug = __start___bug_table; bug < __stop___bug_table; ++bug) |
| 111 | if (bugaddr == bug->bug_addr) | 122 | if (bugaddr == bug_addr(bug)) |
| 112 | return bug; | 123 | return bug; |
| 113 | 124 | ||
| 114 | return module_find_bug(bugaddr); | 125 | return module_find_bug(bugaddr); |
| @@ -133,7 +144,11 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) | |||
| 133 | 144 | ||
| 134 | if (bug) { | 145 | if (bug) { |
| 135 | #ifdef CONFIG_DEBUG_BUGVERBOSE | 146 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
| 147 | #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS | ||
| 136 | file = bug->file; | 148 | file = bug->file; |
| 149 | #else | ||
| 150 | file = (const char *)bug + bug->file_disp; | ||
| 151 | #endif | ||
| 137 | line = bug->line; | 152 | line = bug->line; |
| 138 | #endif | 153 | #endif |
| 139 | warning = (bug->flags & BUGFLAG_WARNING) != 0; | 154 | warning = (bug->flags & BUGFLAG_WARNING) != 0; |
