diff options
Diffstat (limited to 'lib/bug.c')
| -rw-r--r-- | lib/bug.c | 19 |
1 files changed, 17 insertions, 2 deletions
| @@ -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; |
