aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-05 14:59:02 -0400
committerRusty Russell <rusty@rustcorp.com.au>2010-08-04 23:29:02 -0400
commitf91a13bb99b73961d4e2743a6ff296ac553abc4f (patch)
treeeb922cfbd4af965491200d307baf3b60b8b0319e /kernel/module.c
parent2409e74278b7fb917d39ef6d3c16223c04a386f2 (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.c130
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
2110static 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. */
2112static noinline struct module *load_module(void __user *umod, 2177static 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)