diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 316 |
1 files changed, 154 insertions, 162 deletions
diff --git a/kernel/module.c b/kernel/module.c index e6bc4b28aa62..12afc5a3ddd3 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -370,8 +370,6 @@ EXPORT_SYMBOL_GPL(find_module); | |||
370 | 370 | ||
371 | #ifdef CONFIG_SMP | 371 | #ifdef CONFIG_SMP |
372 | 372 | ||
373 | #ifndef CONFIG_HAVE_LEGACY_PER_CPU_AREA | ||
374 | |||
375 | static void *percpu_modalloc(unsigned long size, unsigned long align, | 373 | static void *percpu_modalloc(unsigned long size, unsigned long align, |
376 | const char *name) | 374 | const char *name) |
377 | { | 375 | { |
@@ -395,154 +393,6 @@ static void percpu_modfree(void *freeme) | |||
395 | free_percpu(freeme); | 393 | free_percpu(freeme); |
396 | } | 394 | } |
397 | 395 | ||
398 | #else /* ... CONFIG_HAVE_LEGACY_PER_CPU_AREA */ | ||
399 | |||
400 | /* Number of blocks used and allocated. */ | ||
401 | static unsigned int pcpu_num_used, pcpu_num_allocated; | ||
402 | /* Size of each block. -ve means used. */ | ||
403 | static int *pcpu_size; | ||
404 | |||
405 | static int split_block(unsigned int i, unsigned short size) | ||
406 | { | ||
407 | /* Reallocation required? */ | ||
408 | if (pcpu_num_used + 1 > pcpu_num_allocated) { | ||
409 | int *new; | ||
410 | |||
411 | new = krealloc(pcpu_size, sizeof(new[0])*pcpu_num_allocated*2, | ||
412 | GFP_KERNEL); | ||
413 | if (!new) | ||
414 | return 0; | ||
415 | |||
416 | pcpu_num_allocated *= 2; | ||
417 | pcpu_size = new; | ||
418 | } | ||
419 | |||
420 | /* Insert a new subblock */ | ||
421 | memmove(&pcpu_size[i+1], &pcpu_size[i], | ||
422 | sizeof(pcpu_size[0]) * (pcpu_num_used - i)); | ||
423 | pcpu_num_used++; | ||
424 | |||
425 | pcpu_size[i+1] -= size; | ||
426 | pcpu_size[i] = size; | ||
427 | return 1; | ||
428 | } | ||
429 | |||
430 | static inline unsigned int block_size(int val) | ||
431 | { | ||
432 | if (val < 0) | ||
433 | return -val; | ||
434 | return val; | ||
435 | } | ||
436 | |||
437 | static void *percpu_modalloc(unsigned long size, unsigned long align, | ||
438 | const char *name) | ||
439 | { | ||
440 | unsigned long extra; | ||
441 | unsigned int i; | ||
442 | void *ptr; | ||
443 | int cpu; | ||
444 | |||
445 | if (align > PAGE_SIZE) { | ||
446 | printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n", | ||
447 | name, align, PAGE_SIZE); | ||
448 | align = PAGE_SIZE; | ||
449 | } | ||
450 | |||
451 | ptr = __per_cpu_start; | ||
452 | for (i = 0; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) { | ||
453 | /* Extra for alignment requirement. */ | ||
454 | extra = ALIGN((unsigned long)ptr, align) - (unsigned long)ptr; | ||
455 | BUG_ON(i == 0 && extra != 0); | ||
456 | |||
457 | if (pcpu_size[i] < 0 || pcpu_size[i] < extra + size) | ||
458 | continue; | ||
459 | |||
460 | /* Transfer extra to previous block. */ | ||
461 | if (pcpu_size[i-1] < 0) | ||
462 | pcpu_size[i-1] -= extra; | ||
463 | else | ||
464 | pcpu_size[i-1] += extra; | ||
465 | pcpu_size[i] -= extra; | ||
466 | ptr += extra; | ||
467 | |||
468 | /* Split block if warranted */ | ||
469 | if (pcpu_size[i] - size > sizeof(unsigned long)) | ||
470 | if (!split_block(i, size)) | ||
471 | return NULL; | ||
472 | |||
473 | /* add the per-cpu scanning areas */ | ||
474 | for_each_possible_cpu(cpu) | ||
475 | kmemleak_alloc(ptr + per_cpu_offset(cpu), size, 0, | ||
476 | GFP_KERNEL); | ||
477 | |||
478 | /* Mark allocated */ | ||
479 | pcpu_size[i] = -pcpu_size[i]; | ||
480 | return ptr; | ||
481 | } | ||
482 | |||
483 | printk(KERN_WARNING "Could not allocate %lu bytes percpu data\n", | ||
484 | size); | ||
485 | return NULL; | ||
486 | } | ||
487 | |||
488 | static void percpu_modfree(void *freeme) | ||
489 | { | ||
490 | unsigned int i; | ||
491 | void *ptr = __per_cpu_start + block_size(pcpu_size[0]); | ||
492 | int cpu; | ||
493 | |||
494 | /* First entry is core kernel percpu data. */ | ||
495 | for (i = 1; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) { | ||
496 | if (ptr == freeme) { | ||
497 | pcpu_size[i] = -pcpu_size[i]; | ||
498 | goto free; | ||
499 | } | ||
500 | } | ||
501 | BUG(); | ||
502 | |||
503 | free: | ||
504 | /* remove the per-cpu scanning areas */ | ||
505 | for_each_possible_cpu(cpu) | ||
506 | kmemleak_free(freeme + per_cpu_offset(cpu)); | ||
507 | |||
508 | /* Merge with previous? */ | ||
509 | if (pcpu_size[i-1] >= 0) { | ||
510 | pcpu_size[i-1] += pcpu_size[i]; | ||
511 | pcpu_num_used--; | ||
512 | memmove(&pcpu_size[i], &pcpu_size[i+1], | ||
513 | (pcpu_num_used - i) * sizeof(pcpu_size[0])); | ||
514 | i--; | ||
515 | } | ||
516 | /* Merge with next? */ | ||
517 | if (i+1 < pcpu_num_used && pcpu_size[i+1] >= 0) { | ||
518 | pcpu_size[i] += pcpu_size[i+1]; | ||
519 | pcpu_num_used--; | ||
520 | memmove(&pcpu_size[i+1], &pcpu_size[i+2], | ||
521 | (pcpu_num_used - (i+1)) * sizeof(pcpu_size[0])); | ||
522 | } | ||
523 | } | ||
524 | |||
525 | static int percpu_modinit(void) | ||
526 | { | ||
527 | pcpu_num_used = 2; | ||
528 | pcpu_num_allocated = 2; | ||
529 | pcpu_size = kmalloc(sizeof(pcpu_size[0]) * pcpu_num_allocated, | ||
530 | GFP_KERNEL); | ||
531 | /* Static in-kernel percpu data (used). */ | ||
532 | pcpu_size[0] = -(__per_cpu_end-__per_cpu_start); | ||
533 | /* Free room. */ | ||
534 | pcpu_size[1] = PERCPU_ENOUGH_ROOM + pcpu_size[0]; | ||
535 | if (pcpu_size[1] < 0) { | ||
536 | printk(KERN_ERR "No per-cpu room for modules.\n"); | ||
537 | pcpu_num_used = 1; | ||
538 | } | ||
539 | |||
540 | return 0; | ||
541 | } | ||
542 | __initcall(percpu_modinit); | ||
543 | |||
544 | #endif /* CONFIG_HAVE_LEGACY_PER_CPU_AREA */ | ||
545 | |||
546 | static unsigned int find_pcpusec(Elf_Ehdr *hdr, | 396 | static unsigned int find_pcpusec(Elf_Ehdr *hdr, |
547 | Elf_Shdr *sechdrs, | 397 | Elf_Shdr *sechdrs, |
548 | const char *secstrings) | 398 | const char *secstrings) |
@@ -1187,7 +1037,8 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, | |||
1187 | 1037 | ||
1188 | /* Count loaded sections and allocate structures */ | 1038 | /* Count loaded sections and allocate structures */ |
1189 | for (i = 0; i < nsect; i++) | 1039 | for (i = 0; i < nsect; i++) |
1190 | if (sechdrs[i].sh_flags & SHF_ALLOC) | 1040 | if (sechdrs[i].sh_flags & SHF_ALLOC |
1041 | && sechdrs[i].sh_size) | ||
1191 | nloaded++; | 1042 | nloaded++; |
1192 | size[0] = ALIGN(sizeof(*sect_attrs) | 1043 | size[0] = ALIGN(sizeof(*sect_attrs) |
1193 | + nloaded * sizeof(sect_attrs->attrs[0]), | 1044 | + nloaded * sizeof(sect_attrs->attrs[0]), |
@@ -1207,6 +1058,8 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, | |||
1207 | for (i = 0; i < nsect; i++) { | 1058 | for (i = 0; i < nsect; i++) { |
1208 | if (! (sechdrs[i].sh_flags & SHF_ALLOC)) | 1059 | if (! (sechdrs[i].sh_flags & SHF_ALLOC)) |
1209 | continue; | 1060 | continue; |
1061 | if (!sechdrs[i].sh_size) | ||
1062 | continue; | ||
1210 | sattr->address = sechdrs[i].sh_addr; | 1063 | sattr->address = sechdrs[i].sh_addr; |
1211 | sattr->name = kstrdup(secstrings + sechdrs[i].sh_name, | 1064 | sattr->name = kstrdup(secstrings + sechdrs[i].sh_name, |
1212 | GFP_KERNEL); | 1065 | GFP_KERNEL); |
@@ -1797,6 +1650,17 @@ static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs, | |||
1797 | } | 1650 | } |
1798 | } | 1651 | } |
1799 | 1652 | ||
1653 | static void free_modinfo(struct module *mod) | ||
1654 | { | ||
1655 | struct module_attribute *attr; | ||
1656 | int i; | ||
1657 | |||
1658 | for (i = 0; (attr = modinfo_attrs[i]); i++) { | ||
1659 | if (attr->free) | ||
1660 | attr->free(mod); | ||
1661 | } | ||
1662 | } | ||
1663 | |||
1800 | #ifdef CONFIG_KALLSYMS | 1664 | #ifdef CONFIG_KALLSYMS |
1801 | 1665 | ||
1802 | /* lookup symbol in given range of kernel_symbols */ | 1666 | /* lookup symbol in given range of kernel_symbols */ |
@@ -1862,13 +1726,93 @@ static char elf_type(const Elf_Sym *sym, | |||
1862 | return '?'; | 1726 | return '?'; |
1863 | } | 1727 | } |
1864 | 1728 | ||
1729 | static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs, | ||
1730 | unsigned int shnum) | ||
1731 | { | ||
1732 | const Elf_Shdr *sec; | ||
1733 | |||
1734 | if (src->st_shndx == SHN_UNDEF | ||
1735 | || src->st_shndx >= shnum | ||
1736 | || !src->st_name) | ||
1737 | return false; | ||
1738 | |||
1739 | sec = sechdrs + src->st_shndx; | ||
1740 | if (!(sec->sh_flags & SHF_ALLOC) | ||
1741 | #ifndef CONFIG_KALLSYMS_ALL | ||
1742 | || !(sec->sh_flags & SHF_EXECINSTR) | ||
1743 | #endif | ||
1744 | || (sec->sh_entsize & INIT_OFFSET_MASK)) | ||
1745 | return false; | ||
1746 | |||
1747 | return true; | ||
1748 | } | ||
1749 | |||
1750 | static unsigned long layout_symtab(struct module *mod, | ||
1751 | Elf_Shdr *sechdrs, | ||
1752 | unsigned int symindex, | ||
1753 | unsigned int strindex, | ||
1754 | const Elf_Ehdr *hdr, | ||
1755 | const char *secstrings, | ||
1756 | unsigned long *pstroffs, | ||
1757 | unsigned long *strmap) | ||
1758 | { | ||
1759 | unsigned long symoffs; | ||
1760 | Elf_Shdr *symsect = sechdrs + symindex; | ||
1761 | Elf_Shdr *strsect = sechdrs + strindex; | ||
1762 | const Elf_Sym *src; | ||
1763 | const char *strtab; | ||
1764 | unsigned int i, nsrc, ndst; | ||
1765 | |||
1766 | /* Put symbol section at end of init part of module. */ | ||
1767 | symsect->sh_flags |= SHF_ALLOC; | ||
1768 | symsect->sh_entsize = get_offset(mod, &mod->init_size, symsect, | ||
1769 | symindex) | INIT_OFFSET_MASK; | ||
1770 | DEBUGP("\t%s\n", secstrings + symsect->sh_name); | ||
1771 | |||
1772 | src = (void *)hdr + symsect->sh_offset; | ||
1773 | nsrc = symsect->sh_size / sizeof(*src); | ||
1774 | strtab = (void *)hdr + strsect->sh_offset; | ||
1775 | for (ndst = i = 1; i < nsrc; ++i, ++src) | ||
1776 | if (is_core_symbol(src, sechdrs, hdr->e_shnum)) { | ||
1777 | unsigned int j = src->st_name; | ||
1778 | |||
1779 | while(!__test_and_set_bit(j, strmap) && strtab[j]) | ||
1780 | ++j; | ||
1781 | ++ndst; | ||
1782 | } | ||
1783 | |||
1784 | /* Append room for core symbols at end of core part. */ | ||
1785 | symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); | ||
1786 | mod->core_size = symoffs + ndst * sizeof(Elf_Sym); | ||
1787 | |||
1788 | /* Put string table section at end of init part of module. */ | ||
1789 | strsect->sh_flags |= SHF_ALLOC; | ||
1790 | strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect, | ||
1791 | strindex) | INIT_OFFSET_MASK; | ||
1792 | DEBUGP("\t%s\n", secstrings + strsect->sh_name); | ||
1793 | |||
1794 | /* Append room for core symbols' strings at end of core part. */ | ||
1795 | *pstroffs = mod->core_size; | ||
1796 | __set_bit(0, strmap); | ||
1797 | mod->core_size += bitmap_weight(strmap, strsect->sh_size); | ||
1798 | |||
1799 | return symoffs; | ||
1800 | } | ||
1801 | |||
1865 | static void add_kallsyms(struct module *mod, | 1802 | static void add_kallsyms(struct module *mod, |
1866 | Elf_Shdr *sechdrs, | 1803 | Elf_Shdr *sechdrs, |
1804 | unsigned int shnum, | ||
1867 | unsigned int symindex, | 1805 | unsigned int symindex, |
1868 | unsigned int strindex, | 1806 | unsigned int strindex, |
1869 | const char *secstrings) | 1807 | unsigned long symoffs, |
1808 | unsigned long stroffs, | ||
1809 | const char *secstrings, | ||
1810 | unsigned long *strmap) | ||
1870 | { | 1811 | { |
1871 | unsigned int i; | 1812 | unsigned int i, ndst; |
1813 | const Elf_Sym *src; | ||
1814 | Elf_Sym *dst; | ||
1815 | char *s; | ||
1872 | 1816 | ||
1873 | mod->symtab = (void *)sechdrs[symindex].sh_addr; | 1817 | mod->symtab = (void *)sechdrs[symindex].sh_addr; |
1874 | mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym); | 1818 | mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym); |
@@ -1878,13 +1822,46 @@ static void add_kallsyms(struct module *mod, | |||
1878 | for (i = 0; i < mod->num_symtab; i++) | 1822 | for (i = 0; i < mod->num_symtab; i++) |
1879 | mod->symtab[i].st_info | 1823 | mod->symtab[i].st_info |
1880 | = elf_type(&mod->symtab[i], sechdrs, secstrings, mod); | 1824 | = elf_type(&mod->symtab[i], sechdrs, secstrings, mod); |
1825 | |||
1826 | mod->core_symtab = dst = mod->module_core + symoffs; | ||
1827 | src = mod->symtab; | ||
1828 | *dst = *src; | ||
1829 | for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) { | ||
1830 | if (!is_core_symbol(src, sechdrs, shnum)) | ||
1831 | continue; | ||
1832 | dst[ndst] = *src; | ||
1833 | dst[ndst].st_name = bitmap_weight(strmap, dst[ndst].st_name); | ||
1834 | ++ndst; | ||
1835 | } | ||
1836 | mod->core_num_syms = ndst; | ||
1837 | |||
1838 | mod->core_strtab = s = mod->module_core + stroffs; | ||
1839 | for (*s = 0, i = 1; i < sechdrs[strindex].sh_size; ++i) | ||
1840 | if (test_bit(i, strmap)) | ||
1841 | *++s = mod->strtab[i]; | ||
1881 | } | 1842 | } |
1882 | #else | 1843 | #else |
1844 | static inline unsigned long layout_symtab(struct module *mod, | ||
1845 | Elf_Shdr *sechdrs, | ||
1846 | unsigned int symindex, | ||
1847 | unsigned int strindex, | ||
1848 | const Elf_Ehdr *hdr, | ||
1849 | const char *secstrings, | ||
1850 | unsigned long *pstroffs, | ||
1851 | unsigned long *strmap) | ||
1852 | { | ||
1853 | return 0; | ||
1854 | } | ||
1855 | |||
1883 | static inline void add_kallsyms(struct module *mod, | 1856 | static inline void add_kallsyms(struct module *mod, |
1884 | Elf_Shdr *sechdrs, | 1857 | Elf_Shdr *sechdrs, |
1858 | unsigned int shnum, | ||
1885 | unsigned int symindex, | 1859 | unsigned int symindex, |
1886 | unsigned int strindex, | 1860 | unsigned int strindex, |
1887 | const char *secstrings) | 1861 | unsigned long symoffs, |
1862 | unsigned long stroffs, | ||
1863 | const char *secstrings, | ||
1864 | const unsigned long *strmap) | ||
1888 | { | 1865 | { |
1889 | } | 1866 | } |
1890 | #endif /* CONFIG_KALLSYMS */ | 1867 | #endif /* CONFIG_KALLSYMS */ |
@@ -1959,6 +1936,8 @@ static noinline struct module *load_module(void __user *umod, | |||
1959 | struct module *mod; | 1936 | struct module *mod; |
1960 | long err = 0; | 1937 | long err = 0; |
1961 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 1938 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ |
1939 | unsigned long symoffs, stroffs, *strmap; | ||
1940 | |||
1962 | mm_segment_t old_fs; | 1941 | mm_segment_t old_fs; |
1963 | 1942 | ||
1964 | DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", | 1943 | DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", |
@@ -2040,11 +2019,6 @@ static noinline struct module *load_module(void __user *umod, | |||
2040 | /* Don't keep modinfo and version sections. */ | 2019 | /* Don't keep modinfo and version sections. */ |
2041 | sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; | 2020 | sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; |
2042 | sechdrs[versindex].sh_flags &= ~(unsigned long)SHF_ALLOC; | 2021 | sechdrs[versindex].sh_flags &= ~(unsigned long)SHF_ALLOC; |
2043 | #ifdef CONFIG_KALLSYMS | ||
2044 | /* Keep symbol and string tables for decoding later. */ | ||
2045 | sechdrs[symindex].sh_flags |= SHF_ALLOC; | ||
2046 | sechdrs[strindex].sh_flags |= SHF_ALLOC; | ||
2047 | #endif | ||
2048 | 2022 | ||
2049 | /* Check module struct version now, before we try to use module. */ | 2023 | /* Check module struct version now, before we try to use module. */ |
2050 | if (!check_modstruct_version(sechdrs, versindex, mod)) { | 2024 | if (!check_modstruct_version(sechdrs, versindex, mod)) { |
@@ -2080,6 +2054,13 @@ static noinline struct module *load_module(void __user *umod, | |||
2080 | goto free_hdr; | 2054 | goto free_hdr; |
2081 | } | 2055 | } |
2082 | 2056 | ||
2057 | strmap = kzalloc(BITS_TO_LONGS(sechdrs[strindex].sh_size) | ||
2058 | * sizeof(long), GFP_KERNEL); | ||
2059 | if (!strmap) { | ||
2060 | err = -ENOMEM; | ||
2061 | goto free_mod; | ||
2062 | } | ||
2063 | |||
2083 | if (find_module(mod->name)) { | 2064 | if (find_module(mod->name)) { |
2084 | err = -EEXIST; | 2065 | err = -EEXIST; |
2085 | goto free_mod; | 2066 | goto free_mod; |
@@ -2109,6 +2090,8 @@ static noinline struct module *load_module(void __user *umod, | |||
2109 | this is done generically; there doesn't appear to be any | 2090 | this is done generically; there doesn't appear to be any |
2110 | special cases for the architectures. */ | 2091 | special cases for the architectures. */ |
2111 | layout_sections(mod, hdr, sechdrs, secstrings); | 2092 | layout_sections(mod, hdr, sechdrs, secstrings); |
2093 | symoffs = layout_symtab(mod, sechdrs, symindex, strindex, hdr, | ||
2094 | secstrings, &stroffs, strmap); | ||
2112 | 2095 | ||
2113 | /* Do the allocs. */ | 2096 | /* Do the allocs. */ |
2114 | ptr = module_alloc_update_bounds(mod->core_size); | 2097 | ptr = module_alloc_update_bounds(mod->core_size); |
@@ -2313,7 +2296,10 @@ static noinline struct module *load_module(void __user *umod, | |||
2313 | percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr, | 2296 | percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr, |
2314 | sechdrs[pcpuindex].sh_size); | 2297 | sechdrs[pcpuindex].sh_size); |
2315 | 2298 | ||
2316 | add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); | 2299 | add_kallsyms(mod, sechdrs, hdr->e_shnum, symindex, strindex, |
2300 | symoffs, stroffs, secstrings, strmap); | ||
2301 | kfree(strmap); | ||
2302 | strmap = NULL; | ||
2317 | 2303 | ||
2318 | if (!mod->taints) { | 2304 | if (!mod->taints) { |
2319 | struct _ddebug *debug; | 2305 | struct _ddebug *debug; |
@@ -2385,13 +2371,14 @@ static noinline struct module *load_module(void __user *umod, | |||
2385 | synchronize_sched(); | 2371 | synchronize_sched(); |
2386 | module_arch_cleanup(mod); | 2372 | module_arch_cleanup(mod); |
2387 | cleanup: | 2373 | cleanup: |
2374 | free_modinfo(mod); | ||
2388 | kobject_del(&mod->mkobj.kobj); | 2375 | kobject_del(&mod->mkobj.kobj); |
2389 | kobject_put(&mod->mkobj.kobj); | 2376 | kobject_put(&mod->mkobj.kobj); |
2390 | free_unload: | 2377 | free_unload: |
2391 | module_unload_free(mod); | 2378 | module_unload_free(mod); |
2392 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | 2379 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) |
2393 | free_init: | ||
2394 | percpu_modfree(mod->refptr); | 2380 | percpu_modfree(mod->refptr); |
2381 | free_init: | ||
2395 | #endif | 2382 | #endif |
2396 | module_free(mod, mod->module_init); | 2383 | module_free(mod, mod->module_init); |
2397 | free_core: | 2384 | free_core: |
@@ -2402,6 +2389,7 @@ static noinline struct module *load_module(void __user *umod, | |||
2402 | percpu_modfree(percpu); | 2389 | percpu_modfree(percpu); |
2403 | free_mod: | 2390 | free_mod: |
2404 | kfree(args); | 2391 | kfree(args); |
2392 | kfree(strmap); | ||
2405 | free_hdr: | 2393 | free_hdr: |
2406 | vfree(hdr); | 2394 | vfree(hdr); |
2407 | return ERR_PTR(err); | 2395 | return ERR_PTR(err); |
@@ -2491,6 +2479,11 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, | |||
2491 | /* Drop initial reference. */ | 2479 | /* Drop initial reference. */ |
2492 | module_put(mod); | 2480 | module_put(mod); |
2493 | trim_init_extable(mod); | 2481 | trim_init_extable(mod); |
2482 | #ifdef CONFIG_KALLSYMS | ||
2483 | mod->num_symtab = mod->core_num_syms; | ||
2484 | mod->symtab = mod->core_symtab; | ||
2485 | mod->strtab = mod->core_strtab; | ||
2486 | #endif | ||
2494 | module_free(mod, mod->module_init); | 2487 | module_free(mod, mod->module_init); |
2495 | mod->module_init = NULL; | 2488 | mod->module_init = NULL; |
2496 | mod->init_size = 0; | 2489 | mod->init_size = 0; |
@@ -2952,7 +2945,6 @@ void module_layout(struct module *mod, | |||
2952 | struct modversion_info *ver, | 2945 | struct modversion_info *ver, |
2953 | struct kernel_param *kp, | 2946 | struct kernel_param *kp, |
2954 | struct kernel_symbol *ks, | 2947 | struct kernel_symbol *ks, |
2955 | struct marker *marker, | ||
2956 | struct tracepoint *tp) | 2948 | struct tracepoint *tp) |
2957 | { | 2949 | { |
2958 | } | 2950 | } |