aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/module.c68
1 files changed, 56 insertions, 12 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 97f4d5e15535..39827c3d9484 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1886,12 +1886,17 @@ static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
1886static unsigned long layout_symtab(struct module *mod, 1886static unsigned long layout_symtab(struct module *mod,
1887 Elf_Shdr *sechdrs, 1887 Elf_Shdr *sechdrs,
1888 unsigned int symindex, 1888 unsigned int symindex,
1889 unsigned int strindex,
1889 const Elf_Ehdr *hdr, 1890 const Elf_Ehdr *hdr,
1890 const char *secstrings) 1891 const char *secstrings,
1892 unsigned long *pstroffs,
1893 unsigned long *strmap)
1891{ 1894{
1892 unsigned long symoffs; 1895 unsigned long symoffs;
1893 Elf_Shdr *symsect = sechdrs + symindex; 1896 Elf_Shdr *symsect = sechdrs + symindex;
1897 Elf_Shdr *strsect = sechdrs + strindex;
1894 const Elf_Sym *src; 1898 const Elf_Sym *src;
1899 const char *strtab;
1895 unsigned int i, nsrc, ndst; 1900 unsigned int i, nsrc, ndst;
1896 1901
1897 /* Put symbol section at end of init part of module. */ 1902 /* Put symbol section at end of init part of module. */
@@ -1902,14 +1907,31 @@ static unsigned long layout_symtab(struct module *mod,
1902 1907
1903 src = (void *)hdr + symsect->sh_offset; 1908 src = (void *)hdr + symsect->sh_offset;
1904 nsrc = symsect->sh_size / sizeof(*src); 1909 nsrc = symsect->sh_size / sizeof(*src);
1910 strtab = (void *)hdr + strsect->sh_offset;
1905 for (ndst = i = 1; i < nsrc; ++i, ++src) 1911 for (ndst = i = 1; i < nsrc; ++i, ++src)
1906 if (is_core_symbol(src, sechdrs, hdr->e_shnum)) 1912 if (is_core_symbol(src, sechdrs, hdr->e_shnum)) {
1913 unsigned int j = src->st_name;
1914
1915 while(!__test_and_set_bit(j, strmap) && strtab[j])
1916 ++j;
1907 ++ndst; 1917 ++ndst;
1918 }
1908 1919
1909 /* Append room for core symbols at end of core part. */ 1920 /* Append room for core symbols at end of core part. */
1910 symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); 1921 symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
1911 mod->core_size = symoffs + ndst * sizeof(Elf_Sym); 1922 mod->core_size = symoffs + ndst * sizeof(Elf_Sym);
1912 1923
1924 /* Put string table section at end of init part of module. */
1925 strsect->sh_flags |= SHF_ALLOC;
1926 strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect,
1927 strindex) | INIT_OFFSET_MASK;
1928 DEBUGP("\t%s\n", secstrings + strsect->sh_name);
1929
1930 /* Append room for core symbols' strings at end of core part. */
1931 *pstroffs = mod->core_size;
1932 __set_bit(0, strmap);
1933 mod->core_size += bitmap_weight(strmap, strsect->sh_size);
1934
1913 return symoffs; 1935 return symoffs;
1914} 1936}
1915 1937
@@ -1919,11 +1941,14 @@ static void add_kallsyms(struct module *mod,
1919 unsigned int symindex, 1941 unsigned int symindex,
1920 unsigned int strindex, 1942 unsigned int strindex,
1921 unsigned long symoffs, 1943 unsigned long symoffs,
1922 const char *secstrings) 1944 unsigned long stroffs,
1945 const char *secstrings,
1946 unsigned long *strmap)
1923{ 1947{
1924 unsigned int i, ndst; 1948 unsigned int i, ndst;
1925 const Elf_Sym *src; 1949 const Elf_Sym *src;
1926 Elf_Sym *dst; 1950 Elf_Sym *dst;
1951 char *s;
1927 1952
1928 mod->symtab = (void *)sechdrs[symindex].sh_addr; 1953 mod->symtab = (void *)sechdrs[symindex].sh_addr;
1929 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym); 1954 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
@@ -1941,16 +1966,25 @@ static void add_kallsyms(struct module *mod,
1941 if (!is_core_symbol(src, sechdrs, shnum)) 1966 if (!is_core_symbol(src, sechdrs, shnum))
1942 continue; 1967 continue;
1943 dst[ndst] = *src; 1968 dst[ndst] = *src;
1969 dst[ndst].st_name = bitmap_weight(strmap, dst[ndst].st_name);
1944 ++ndst; 1970 ++ndst;
1945 } 1971 }
1946 mod->core_num_syms = ndst; 1972 mod->core_num_syms = ndst;
1973
1974 mod->core_strtab = s = mod->module_core + stroffs;
1975 for (*s = 0, i = 1; i < sechdrs[strindex].sh_size; ++i)
1976 if (test_bit(i, strmap))
1977 *++s = mod->strtab[i];
1947} 1978}
1948#else 1979#else
1949static inline unsigned long layout_symtab(struct module *mod, 1980static inline unsigned long layout_symtab(struct module *mod,
1950 Elf_Shdr *sechdrs, 1981 Elf_Shdr *sechdrs,
1951 unsigned int symindex, 1982 unsigned int symindex,
1983 unsigned int strindex,
1952 const Elf_Hdr *hdr, 1984 const Elf_Hdr *hdr,
1953 const char *secstrings) 1985 const char *secstrings,
1986 unsigned long *pstroffs,
1987 unsigned long *strmap)
1954{ 1988{
1955} 1989}
1956static inline void add_kallsyms(struct module *mod, 1990static inline void add_kallsyms(struct module *mod,
@@ -1959,7 +1993,9 @@ static inline void add_kallsyms(struct module *mod,
1959 unsigned int symindex, 1993 unsigned int symindex,
1960 unsigned int strindex, 1994 unsigned int strindex,
1961 unsigned long symoffs, 1995 unsigned long symoffs,
1962 const char *secstrings) 1996 unsigned long stroffs,
1997 const char *secstrings,
1998 const unsigned long *strmap)
1963{ 1999{
1964} 2000}
1965#endif /* CONFIG_KALLSYMS */ 2001#endif /* CONFIG_KALLSYMS */
@@ -2035,7 +2071,7 @@ static noinline struct module *load_module(void __user *umod,
2035 long err = 0; 2071 long err = 0;
2036 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ 2072 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
2037#ifdef CONFIG_KALLSYMS 2073#ifdef CONFIG_KALLSYMS
2038 unsigned long symoffs; 2074 unsigned long symoffs, stroffs, *strmap;
2039#endif 2075#endif
2040 mm_segment_t old_fs; 2076 mm_segment_t old_fs;
2041 2077
@@ -2118,10 +2154,6 @@ static noinline struct module *load_module(void __user *umod,
2118 /* Don't keep modinfo and version sections. */ 2154 /* Don't keep modinfo and version sections. */
2119 sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; 2155 sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
2120 sechdrs[versindex].sh_flags &= ~(unsigned long)SHF_ALLOC; 2156 sechdrs[versindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
2121#ifdef CONFIG_KALLSYMS
2122 /* Keep string table for decoding later. */
2123 sechdrs[strindex].sh_flags |= SHF_ALLOC;
2124#endif
2125 2157
2126 /* Check module struct version now, before we try to use module. */ 2158 /* Check module struct version now, before we try to use module. */
2127 if (!check_modstruct_version(sechdrs, versindex, mod)) { 2159 if (!check_modstruct_version(sechdrs, versindex, mod)) {
@@ -2157,6 +2189,13 @@ static noinline struct module *load_module(void __user *umod,
2157 goto free_hdr; 2189 goto free_hdr;
2158 } 2190 }
2159 2191
2192 strmap = kzalloc(BITS_TO_LONGS(sechdrs[strindex].sh_size)
2193 * sizeof(long), GFP_KERNEL);
2194 if (!strmap) {
2195 err = -ENOMEM;
2196 goto free_mod;
2197 }
2198
2160 if (find_module(mod->name)) { 2199 if (find_module(mod->name)) {
2161 err = -EEXIST; 2200 err = -EEXIST;
2162 goto free_mod; 2201 goto free_mod;
@@ -2186,7 +2225,8 @@ static noinline struct module *load_module(void __user *umod,
2186 this is done generically; there doesn't appear to be any 2225 this is done generically; there doesn't appear to be any
2187 special cases for the architectures. */ 2226 special cases for the architectures. */
2188 layout_sections(mod, hdr, sechdrs, secstrings); 2227 layout_sections(mod, hdr, sechdrs, secstrings);
2189 symoffs = layout_symtab(mod, sechdrs, symindex, hdr, secstrings); 2228 symoffs = layout_symtab(mod, sechdrs, symindex, strindex, hdr,
2229 secstrings, &stroffs, strmap);
2190 2230
2191 /* Do the allocs. */ 2231 /* Do the allocs. */
2192 ptr = module_alloc_update_bounds(mod->core_size); 2232 ptr = module_alloc_update_bounds(mod->core_size);
@@ -2392,7 +2432,9 @@ static noinline struct module *load_module(void __user *umod,
2392 sechdrs[pcpuindex].sh_size); 2432 sechdrs[pcpuindex].sh_size);
2393 2433
2394 add_kallsyms(mod, sechdrs, hdr->e_shnum, symindex, strindex, 2434 add_kallsyms(mod, sechdrs, hdr->e_shnum, symindex, strindex,
2395 symoffs, secstrings); 2435 symoffs, stroffs, secstrings, strmap);
2436 kfree(strmap);
2437 strmap = NULL;
2396 2438
2397 if (!mod->taints) { 2439 if (!mod->taints) {
2398 struct _ddebug *debug; 2440 struct _ddebug *debug;
@@ -2481,6 +2523,7 @@ static noinline struct module *load_module(void __user *umod,
2481 percpu_modfree(percpu); 2523 percpu_modfree(percpu);
2482 free_mod: 2524 free_mod:
2483 kfree(args); 2525 kfree(args);
2526 kfree(strmap);
2484 free_hdr: 2527 free_hdr:
2485 vfree(hdr); 2528 vfree(hdr);
2486 return ERR_PTR(err); 2529 return ERR_PTR(err);
@@ -2573,6 +2616,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
2573#ifdef CONFIG_KALLSYMS 2616#ifdef CONFIG_KALLSYMS
2574 mod->num_symtab = mod->core_num_syms; 2617 mod->num_symtab = mod->core_num_syms;
2575 mod->symtab = mod->core_symtab; 2618 mod->symtab = mod->core_symtab;
2619 mod->strtab = mod->core_strtab;
2576#endif 2620#endif
2577 module_free(mod, mod->module_init); 2621 module_free(mod, mod->module_init);
2578 mod->module_init = NULL; 2622 mod->module_init = NULL;