aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2010-08-05 14:59:07 -0400
committerRusty Russell <rusty@rustcorp.com.au>2010-08-04 23:29:08 -0400
commiteded41c1c6466081e0eb00d38719c6e6ee81a5d4 (patch)
treed4c015b489b57503af437fe385c4fc07db232ad6 /kernel/module.c
parentd6df72a06e067139d491da4a9d14d92ad39e7a50 (diff)
module: kallsyms functions take struct load_info
Simple refactor causes us to lift struct definition to top of file. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c68
1 files changed, 29 insertions, 39 deletions
diff --git a/kernel/module.c b/kernel/module.c
index ab07f67de996..79c4d6f69dd7 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -110,6 +110,16 @@ int unregister_module_notifier(struct notifier_block * nb)
110} 110}
111EXPORT_SYMBOL(unregister_module_notifier); 111EXPORT_SYMBOL(unregister_module_notifier);
112 112
113struct load_info {
114 Elf_Ehdr *hdr;
115 unsigned long len;
116 Elf_Shdr *sechdrs;
117 char *secstrings, *args, *strtab;
118 struct {
119 unsigned int sym, str, mod, vers, info, pcpu;
120 } index;
121};
122
113/* We require a truly strong try_module_get(): 0 means failure due to 123/* We require a truly strong try_module_get(): 0 means failure due to
114 ongoing or failed initialization etc. */ 124 ongoing or failed initialization etc. */
115static inline int strong_try_module_get(struct module *mod) 125static inline int strong_try_module_get(struct module *mod)
@@ -1909,11 +1919,10 @@ static int is_exported(const char *name, unsigned long value,
1909} 1919}
1910 1920
1911/* As per nm */ 1921/* As per nm */
1912static char elf_type(const Elf_Sym *sym, 1922static char elf_type(const Elf_Sym *sym, const struct load_info *info)
1913 Elf_Shdr *sechdrs,
1914 const char *secstrings,
1915 struct module *mod)
1916{ 1923{
1924 const Elf_Shdr *sechdrs = info->sechdrs;
1925
1917 if (ELF_ST_BIND(sym->st_info) == STB_WEAK) { 1926 if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
1918 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT) 1927 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
1919 return 'v'; 1928 return 'v';
@@ -1943,8 +1952,10 @@ static char elf_type(const Elf_Sym *sym,
1943 else 1952 else
1944 return 'b'; 1953 return 'b';
1945 } 1954 }
1946 if (strstarts(secstrings + sechdrs[sym->st_shndx].sh_name, ".debug")) 1955 if (strstarts(info->secstrings + sechdrs[sym->st_shndx].sh_name,
1956 ".debug")) {
1947 return 'n'; 1957 return 'n';
1958 }
1948 return '?'; 1959 return '?';
1949} 1960}
1950 1961
@@ -2021,35 +2032,30 @@ static unsigned long layout_symtab(struct module *mod,
2021 return symoffs; 2032 return symoffs;
2022} 2033}
2023 2034
2024static void add_kallsyms(struct module *mod, 2035static void add_kallsyms(struct module *mod, struct load_info *info,
2025 Elf_Shdr *sechdrs,
2026 unsigned int shnum,
2027 unsigned int symindex,
2028 unsigned int strindex,
2029 unsigned long symoffs, 2036 unsigned long symoffs,
2030 unsigned long stroffs, 2037 unsigned long stroffs,
2031 const char *secstrings,
2032 unsigned long *strmap) 2038 unsigned long *strmap)
2033{ 2039{
2034 unsigned int i, ndst; 2040 unsigned int i, ndst;
2035 const Elf_Sym *src; 2041 const Elf_Sym *src;
2036 Elf_Sym *dst; 2042 Elf_Sym *dst;
2037 char *s; 2043 char *s;
2044 Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
2038 2045
2039 mod->symtab = (void *)sechdrs[symindex].sh_addr; 2046 mod->symtab = (void *)symsec->sh_addr;
2040 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym); 2047 mod->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
2041 mod->strtab = (void *)sechdrs[strindex].sh_addr; 2048 mod->strtab = info->strtab;
2042 2049
2043 /* Set types up while we still have access to sections. */ 2050 /* Set types up while we still have access to sections. */
2044 for (i = 0; i < mod->num_symtab; i++) 2051 for (i = 0; i < mod->num_symtab; i++)
2045 mod->symtab[i].st_info 2052 mod->symtab[i].st_info = elf_type(&mod->symtab[i], info);
2046 = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
2047 2053
2048 mod->core_symtab = dst = mod->module_core + symoffs; 2054 mod->core_symtab = dst = mod->module_core + symoffs;
2049 src = mod->symtab; 2055 src = mod->symtab;
2050 *dst = *src; 2056 *dst = *src;
2051 for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) { 2057 for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) {
2052 if (!is_core_symbol(src, sechdrs, shnum)) 2058 if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum))
2053 continue; 2059 continue;
2054 dst[ndst] = *src; 2060 dst[ndst] = *src;
2055 dst[ndst].st_name = bitmap_weight(strmap, dst[ndst].st_name); 2061 dst[ndst].st_name = bitmap_weight(strmap, dst[ndst].st_name);
@@ -2058,7 +2064,7 @@ static void add_kallsyms(struct module *mod,
2058 mod->core_num_syms = ndst; 2064 mod->core_num_syms = ndst;
2059 2065
2060 mod->core_strtab = s = mod->module_core + stroffs; 2066 mod->core_strtab = s = mod->module_core + stroffs;
2061 for (*s = 0, i = 1; i < sechdrs[strindex].sh_size; ++i) 2067 for (*s = 0, i = 1; i < info->sechdrs[info->index.str].sh_size; ++i)
2062 if (test_bit(i, strmap)) 2068 if (test_bit(i, strmap))
2063 *++s = mod->strtab[i]; 2069 *++s = mod->strtab[i];
2064} 2070}
@@ -2075,15 +2081,10 @@ static inline unsigned long layout_symtab(struct module *mod,
2075 return 0; 2081 return 0;
2076} 2082}
2077 2083
2078static inline void add_kallsyms(struct module *mod, 2084static void add_kallsyms(struct module *mod, struct load_info *info,
2079 Elf_Shdr *sechdrs, 2085 unsigned long symoffs,
2080 unsigned int shnum, 2086 unsigned long stroffs,
2081 unsigned int symindex, 2087 unsigned long *strmap)
2082 unsigned int strindex,
2083 unsigned long symoffs,
2084 unsigned long stroffs,
2085 const char *secstrings,
2086 const unsigned long *strmap)
2087{ 2088{
2088} 2089}
2089#endif /* CONFIG_KALLSYMS */ 2090#endif /* CONFIG_KALLSYMS */
@@ -2148,16 +2149,6 @@ static inline void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr,
2148} 2149}
2149#endif 2150#endif
2150 2151
2151struct load_info {
2152 Elf_Ehdr *hdr;
2153 unsigned long len;
2154 Elf_Shdr *sechdrs;
2155 char *secstrings, *args, *strtab;
2156 struct {
2157 unsigned int sym, str, mod, vers, info, pcpu;
2158 } index;
2159};
2160
2161/* Sets info->hdr and info->len. */ 2152/* Sets info->hdr and info->len. */
2162static int copy_and_check(struct load_info *info, const void __user *umod, unsigned long len) 2153static int copy_and_check(struct load_info *info, const void __user *umod, unsigned long len)
2163{ 2154{
@@ -2623,8 +2614,7 @@ static noinline struct module *load_module(void __user *umod,
2623 percpu_modcopy(mod, (void *)info.sechdrs[info.index.pcpu].sh_addr, 2614 percpu_modcopy(mod, (void *)info.sechdrs[info.index.pcpu].sh_addr,
2624 info.sechdrs[info.index.pcpu].sh_size); 2615 info.sechdrs[info.index.pcpu].sh_size);
2625 2616
2626 add_kallsyms(mod, info.sechdrs, info.hdr->e_shnum, info.index.sym, info.index.str, 2617 add_kallsyms(mod, &info, symoffs, stroffs, strmap);
2627 symoffs, stroffs, info.secstrings, strmap);
2628 kfree(strmap); 2618 kfree(strmap);
2629 strmap = NULL; 2619 strmap = NULL;
2630 2620