diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-05 14:59:02 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-08-04 23:29:02 -0400 |
commit | f91a13bb99b73961d4e2743a6ff296ac553abc4f (patch) | |
tree | eb922cfbd4af965491200d307baf3b60b8b0319e /kernel/module.c | |
parent | 2409e74278b7fb917d39ef6d3c16223c04a386f2 (diff) |
module: refactor load_module
I'd start from the trivial stuff. There's a fair amount of straight-line
code that just makes the function hard to read just because you have to
page up and down so far. Some of it is trivial to just create a helper
function for.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 130 |
1 files changed, 69 insertions, 61 deletions
diff --git a/kernel/module.c b/kernel/module.c index 404e722930fc..12905ed44393 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -2107,6 +2107,71 @@ static inline void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr, | |||
2107 | } | 2107 | } |
2108 | #endif | 2108 | #endif |
2109 | 2109 | ||
2110 | static void find_module_sections(struct module *mod, Elf_Ehdr *hdr, | ||
2111 | Elf_Shdr *sechdrs, const char *secstrings) | ||
2112 | { | ||
2113 | mod->kp = section_objs(hdr, sechdrs, secstrings, "__param", | ||
2114 | sizeof(*mod->kp), &mod->num_kp); | ||
2115 | mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab", | ||
2116 | sizeof(*mod->syms), &mod->num_syms); | ||
2117 | mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab"); | ||
2118 | mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl", | ||
2119 | sizeof(*mod->gpl_syms), | ||
2120 | &mod->num_gpl_syms); | ||
2121 | mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl"); | ||
2122 | mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings, | ||
2123 | "__ksymtab_gpl_future", | ||
2124 | sizeof(*mod->gpl_future_syms), | ||
2125 | &mod->num_gpl_future_syms); | ||
2126 | mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings, | ||
2127 | "__kcrctab_gpl_future"); | ||
2128 | |||
2129 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
2130 | mod->unused_syms = section_objs(hdr, sechdrs, secstrings, | ||
2131 | "__ksymtab_unused", | ||
2132 | sizeof(*mod->unused_syms), | ||
2133 | &mod->num_unused_syms); | ||
2134 | mod->unused_crcs = section_addr(hdr, sechdrs, secstrings, | ||
2135 | "__kcrctab_unused"); | ||
2136 | mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings, | ||
2137 | "__ksymtab_unused_gpl", | ||
2138 | sizeof(*mod->unused_gpl_syms), | ||
2139 | &mod->num_unused_gpl_syms); | ||
2140 | mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings, | ||
2141 | "__kcrctab_unused_gpl"); | ||
2142 | #endif | ||
2143 | #ifdef CONFIG_CONSTRUCTORS | ||
2144 | mod->ctors = section_objs(hdr, sechdrs, secstrings, ".ctors", | ||
2145 | sizeof(*mod->ctors), &mod->num_ctors); | ||
2146 | #endif | ||
2147 | |||
2148 | #ifdef CONFIG_TRACEPOINTS | ||
2149 | mod->tracepoints = section_objs(hdr, sechdrs, secstrings, | ||
2150 | "__tracepoints", | ||
2151 | sizeof(*mod->tracepoints), | ||
2152 | &mod->num_tracepoints); | ||
2153 | #endif | ||
2154 | #ifdef CONFIG_EVENT_TRACING | ||
2155 | mod->trace_events = section_objs(hdr, sechdrs, secstrings, | ||
2156 | "_ftrace_events", | ||
2157 | sizeof(*mod->trace_events), | ||
2158 | &mod->num_trace_events); | ||
2159 | /* | ||
2160 | * This section contains pointers to allocated objects in the trace | ||
2161 | * code and not scanning it leads to false positives. | ||
2162 | */ | ||
2163 | kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) * | ||
2164 | mod->num_trace_events, GFP_KERNEL); | ||
2165 | #endif | ||
2166 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | ||
2167 | /* sechdrs[0].sh_size is always zero */ | ||
2168 | mod->ftrace_callsites = section_objs(hdr, sechdrs, secstrings, | ||
2169 | "__mcount_loc", | ||
2170 | sizeof(*mod->ftrace_callsites), | ||
2171 | &mod->num_ftrace_callsites); | ||
2172 | #endif | ||
2173 | } | ||
2174 | |||
2110 | /* Allocate and load the module: note that size of section 0 is always | 2175 | /* Allocate and load the module: note that size of section 0 is always |
2111 | zero, and we rely on this for optional sections. */ | 2176 | zero, and we rely on this for optional sections. */ |
2112 | static noinline struct module *load_module(void __user *umod, | 2177 | static noinline struct module *load_module(void __user *umod, |
@@ -2147,7 +2212,7 @@ static noinline struct module *load_module(void __user *umod, | |||
2147 | } | 2212 | } |
2148 | 2213 | ||
2149 | /* Sanity checks against insmoding binaries or wrong arch, | 2214 | /* Sanity checks against insmoding binaries or wrong arch, |
2150 | weird elf version */ | 2215 | weird elf version */ |
2151 | if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0 | 2216 | if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0 |
2152 | || hdr->e_type != ET_REL | 2217 | || hdr->e_type != ET_REL |
2153 | || !elf_check_arch(hdr) | 2218 | || !elf_check_arch(hdr) |
@@ -2326,7 +2391,8 @@ static noinline struct module *load_module(void __user *umod, | |||
2326 | sechdrs[i].sh_size); | 2391 | sechdrs[i].sh_size); |
2327 | /* Update sh_addr to point to copy in image. */ | 2392 | /* Update sh_addr to point to copy in image. */ |
2328 | sechdrs[i].sh_addr = (unsigned long)dest; | 2393 | sechdrs[i].sh_addr = (unsigned long)dest; |
2329 | DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name); | 2394 | DEBUGP("\t0x%lx %s\n", |
2395 | sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name); | ||
2330 | } | 2396 | } |
2331 | /* Module has been moved. */ | 2397 | /* Module has been moved. */ |
2332 | mod = (void *)sechdrs[modindex].sh_addr; | 2398 | mod = (void *)sechdrs[modindex].sh_addr; |
@@ -2368,66 +2434,8 @@ static noinline struct module *load_module(void __user *umod, | |||
2368 | 2434 | ||
2369 | /* Now we've got everything in the final locations, we can | 2435 | /* Now we've got everything in the final locations, we can |
2370 | * find optional sections. */ | 2436 | * find optional sections. */ |
2371 | mod->kp = section_objs(hdr, sechdrs, secstrings, "__param", | 2437 | find_module_sections(mod, hdr, sechdrs, secstrings); |
2372 | sizeof(*mod->kp), &mod->num_kp); | ||
2373 | mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab", | ||
2374 | sizeof(*mod->syms), &mod->num_syms); | ||
2375 | mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab"); | ||
2376 | mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl", | ||
2377 | sizeof(*mod->gpl_syms), | ||
2378 | &mod->num_gpl_syms); | ||
2379 | mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl"); | ||
2380 | mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings, | ||
2381 | "__ksymtab_gpl_future", | ||
2382 | sizeof(*mod->gpl_future_syms), | ||
2383 | &mod->num_gpl_future_syms); | ||
2384 | mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings, | ||
2385 | "__kcrctab_gpl_future"); | ||
2386 | 2438 | ||
2387 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
2388 | mod->unused_syms = section_objs(hdr, sechdrs, secstrings, | ||
2389 | "__ksymtab_unused", | ||
2390 | sizeof(*mod->unused_syms), | ||
2391 | &mod->num_unused_syms); | ||
2392 | mod->unused_crcs = section_addr(hdr, sechdrs, secstrings, | ||
2393 | "__kcrctab_unused"); | ||
2394 | mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings, | ||
2395 | "__ksymtab_unused_gpl", | ||
2396 | sizeof(*mod->unused_gpl_syms), | ||
2397 | &mod->num_unused_gpl_syms); | ||
2398 | mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings, | ||
2399 | "__kcrctab_unused_gpl"); | ||
2400 | #endif | ||
2401 | #ifdef CONFIG_CONSTRUCTORS | ||
2402 | mod->ctors = section_objs(hdr, sechdrs, secstrings, ".ctors", | ||
2403 | sizeof(*mod->ctors), &mod->num_ctors); | ||
2404 | #endif | ||
2405 | |||
2406 | #ifdef CONFIG_TRACEPOINTS | ||
2407 | mod->tracepoints = section_objs(hdr, sechdrs, secstrings, | ||
2408 | "__tracepoints", | ||
2409 | sizeof(*mod->tracepoints), | ||
2410 | &mod->num_tracepoints); | ||
2411 | #endif | ||
2412 | #ifdef CONFIG_EVENT_TRACING | ||
2413 | mod->trace_events = section_objs(hdr, sechdrs, secstrings, | ||
2414 | "_ftrace_events", | ||
2415 | sizeof(*mod->trace_events), | ||
2416 | &mod->num_trace_events); | ||
2417 | /* | ||
2418 | * This section contains pointers to allocated objects in the trace | ||
2419 | * code and not scanning it leads to false positives. | ||
2420 | */ | ||
2421 | kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) * | ||
2422 | mod->num_trace_events, GFP_KERNEL); | ||
2423 | #endif | ||
2424 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | ||
2425 | /* sechdrs[0].sh_size is always zero */ | ||
2426 | mod->ftrace_callsites = section_objs(hdr, sechdrs, secstrings, | ||
2427 | "__mcount_loc", | ||
2428 | sizeof(*mod->ftrace_callsites), | ||
2429 | &mod->num_ftrace_callsites); | ||
2430 | #endif | ||
2431 | #ifdef CONFIG_MODVERSIONS | 2439 | #ifdef CONFIG_MODVERSIONS |
2432 | if ((mod->num_syms && !mod->crcs) | 2440 | if ((mod->num_syms && !mod->crcs) |
2433 | || (mod->num_gpl_syms && !mod->gpl_crcs) | 2441 | || (mod->num_gpl_syms && !mod->gpl_crcs) |