diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig.debug | 32 | ||||
-rw-r--r-- | lib/find_next_bit.c | 43 |
2 files changed, 75 insertions, 0 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 14fb355e3caa..c4ecb2994ba3 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -79,6 +79,38 @@ config HEADERS_CHECK | |||
79 | exported to $(INSTALL_HDR_PATH) (usually 'usr/include' in | 79 | exported to $(INSTALL_HDR_PATH) (usually 'usr/include' in |
80 | your build tree), to make sure they're suitable. | 80 | your build tree), to make sure they're suitable. |
81 | 81 | ||
82 | config DEBUG_SECTION_MISMATCH | ||
83 | bool "Enable full Section mismatch analysis" | ||
84 | default n | ||
85 | help | ||
86 | The section mismatch analysis checks if there are illegal | ||
87 | references from one section to another section. | ||
88 | Linux will during link or during runtime drop some sections | ||
89 | and any use of code/data previously in these sections will | ||
90 | most likely result in an oops. | ||
91 | In the code functions and variables are annotated with | ||
92 | __init, __devinit etc. (see full list in include/linux/init.h) | ||
93 | which result in the code/data being placed in specific sections. | ||
94 | The section mismatch anaylsis are always done after a full | ||
95 | kernel build but enabling this options will in addition | ||
96 | do the following: | ||
97 | - Add the option -fno-inline-functions-called-once to gcc | ||
98 | When inlining a function annotated __init in a non-init | ||
99 | function we would loose the section information and thus | ||
100 | the analysis would not catch the illegal reference. | ||
101 | This options tell gcc to inline less but will also | ||
102 | result in a larger kernel. | ||
103 | - Run the section mismatch analysis for each module/built-in.o | ||
104 | When we run the section mismatch analysis on vmlinux.o we | ||
105 | looses valueable information about where the mismatch was | ||
106 | introduced. | ||
107 | Running the analysis for each module/built-in.o file | ||
108 | will tell where the mismatch happens much closer to the | ||
109 | source. The drawback is that we will report the same | ||
110 | mismatch at least twice. | ||
111 | - Enable verbose reporting from modpost to help solving | ||
112 | the section mismatches reported. | ||
113 | |||
82 | config DEBUG_KERNEL | 114 | config DEBUG_KERNEL |
83 | bool "Kernel debugging" | 115 | bool "Kernel debugging" |
84 | help | 116 | help |
diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c index bda0d71a2514..78ccd73a8841 100644 --- a/lib/find_next_bit.c +++ b/lib/find_next_bit.c | |||
@@ -178,4 +178,47 @@ found_middle_swap: | |||
178 | 178 | ||
179 | EXPORT_SYMBOL(generic_find_next_zero_le_bit); | 179 | EXPORT_SYMBOL(generic_find_next_zero_le_bit); |
180 | 180 | ||
181 | unsigned long generic_find_next_le_bit(const unsigned long *addr, unsigned | ||
182 | long size, unsigned long offset) | ||
183 | { | ||
184 | const unsigned long *p = addr + BITOP_WORD(offset); | ||
185 | unsigned long result = offset & ~(BITS_PER_LONG - 1); | ||
186 | unsigned long tmp; | ||
187 | |||
188 | if (offset >= size) | ||
189 | return size; | ||
190 | size -= result; | ||
191 | offset &= (BITS_PER_LONG - 1UL); | ||
192 | if (offset) { | ||
193 | tmp = ext2_swabp(p++); | ||
194 | tmp &= (~0UL << offset); | ||
195 | if (size < BITS_PER_LONG) | ||
196 | goto found_first; | ||
197 | if (tmp) | ||
198 | goto found_middle; | ||
199 | size -= BITS_PER_LONG; | ||
200 | result += BITS_PER_LONG; | ||
201 | } | ||
202 | |||
203 | while (size & ~(BITS_PER_LONG - 1)) { | ||
204 | tmp = *(p++); | ||
205 | if (tmp) | ||
206 | goto found_middle_swap; | ||
207 | result += BITS_PER_LONG; | ||
208 | size -= BITS_PER_LONG; | ||
209 | } | ||
210 | if (!size) | ||
211 | return result; | ||
212 | tmp = ext2_swabp(p); | ||
213 | found_first: | ||
214 | tmp &= (~0UL >> (BITS_PER_LONG - size)); | ||
215 | if (tmp == 0UL) /* Are any bits set? */ | ||
216 | return result + size; /* Nope. */ | ||
217 | found_middle: | ||
218 | return result + __ffs(tmp); | ||
219 | |||
220 | found_middle_swap: | ||
221 | return result + __ffs(ext2_swab(tmp)); | ||
222 | } | ||
223 | EXPORT_SYMBOL(generic_find_next_le_bit); | ||
181 | #endif /* __BIG_ENDIAN */ | 224 | #endif /* __BIG_ENDIAN */ |