aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/module.h1
-rw-r--r--kernel/module-internal.h2
-rw-r--r--kernel/module.c21
3 files changed, 16 insertions, 8 deletions
diff --git a/include/linux/module.h b/include/linux/module.h
index 5bf5dcd91009..3abe8176df98 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -331,6 +331,7 @@ struct mod_kallsyms {
331 Elf_Sym *symtab; 331 Elf_Sym *symtab;
332 unsigned int num_symtab; 332 unsigned int num_symtab;
333 char *strtab; 333 char *strtab;
334 char *typetab;
334}; 335};
335 336
336#ifdef CONFIG_LIVEPATCH 337#ifdef CONFIG_LIVEPATCH
diff --git a/kernel/module-internal.h b/kernel/module-internal.h
index 79c9be2dbbe9..d354341f8cc0 100644
--- a/kernel/module-internal.h
+++ b/kernel/module-internal.h
@@ -20,7 +20,7 @@ struct load_info {
20 unsigned long len; 20 unsigned long len;
21 Elf_Shdr *sechdrs; 21 Elf_Shdr *sechdrs;
22 char *secstrings, *strtab; 22 char *secstrings, *strtab;
23 unsigned long symoffs, stroffs; 23 unsigned long symoffs, stroffs, init_typeoffs, core_typeoffs;
24 struct _ddebug *debug; 24 struct _ddebug *debug;
25 unsigned int num_debug; 25 unsigned int num_debug;
26 bool sig_ok; 26 bool sig_ok;
diff --git a/kernel/module.c b/kernel/module.c
index 0b9aa8ab89f0..69e52e82242a 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2647,6 +2647,8 @@ static void layout_symtab(struct module *mod, struct load_info *info)
2647 info->symoffs = ALIGN(mod->core_layout.size, symsect->sh_addralign ?: 1); 2647 info->symoffs = ALIGN(mod->core_layout.size, symsect->sh_addralign ?: 1);
2648 info->stroffs = mod->core_layout.size = info->symoffs + ndst * sizeof(Elf_Sym); 2648 info->stroffs = mod->core_layout.size = info->symoffs + ndst * sizeof(Elf_Sym);
2649 mod->core_layout.size += strtab_size; 2649 mod->core_layout.size += strtab_size;
2650 info->core_typeoffs = mod->core_layout.size;
2651 mod->core_layout.size += ndst * sizeof(char);
2650 mod->core_layout.size = debug_align(mod->core_layout.size); 2652 mod->core_layout.size = debug_align(mod->core_layout.size);
2651 2653
2652 /* Put string table section at end of init part of module. */ 2654 /* Put string table section at end of init part of module. */
@@ -2660,6 +2662,8 @@ static void layout_symtab(struct module *mod, struct load_info *info)
2660 __alignof__(struct mod_kallsyms)); 2662 __alignof__(struct mod_kallsyms));
2661 info->mod_kallsyms_init_off = mod->init_layout.size; 2663 info->mod_kallsyms_init_off = mod->init_layout.size;
2662 mod->init_layout.size += sizeof(struct mod_kallsyms); 2664 mod->init_layout.size += sizeof(struct mod_kallsyms);
2665 info->init_typeoffs = mod->init_layout.size;
2666 mod->init_layout.size += nsrc * sizeof(char);
2663 mod->init_layout.size = debug_align(mod->init_layout.size); 2667 mod->init_layout.size = debug_align(mod->init_layout.size);
2664} 2668}
2665 2669
@@ -2683,20 +2687,23 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
2683 mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym); 2687 mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
2684 /* Make sure we get permanent strtab: don't use info->strtab. */ 2688 /* Make sure we get permanent strtab: don't use info->strtab. */
2685 mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr; 2689 mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
2690 mod->kallsyms->typetab = mod->init_layout.base + info->init_typeoffs;
2686 2691
2687 /* Set types up while we still have access to sections. */ 2692 /*
2688 for (i = 0; i < mod->kallsyms->num_symtab; i++) 2693 * Now populate the cut down core kallsyms for after init
2689 mod->kallsyms->symtab[i].st_size 2694 * and set types up while we still have access to sections.
2690 = elf_type(&mod->kallsyms->symtab[i], info); 2695 */
2691
2692 /* Now populate the cut down core kallsyms for after init. */
2693 mod->core_kallsyms.symtab = dst = mod->core_layout.base + info->symoffs; 2696 mod->core_kallsyms.symtab = dst = mod->core_layout.base + info->symoffs;
2694 mod->core_kallsyms.strtab = s = mod->core_layout.base + info->stroffs; 2697 mod->core_kallsyms.strtab = s = mod->core_layout.base + info->stroffs;
2698 mod->core_kallsyms.typetab = mod->core_layout.base + info->core_typeoffs;
2695 src = mod->kallsyms->symtab; 2699 src = mod->kallsyms->symtab;
2696 for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) { 2700 for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
2701 mod->kallsyms->typetab[i] = elf_type(src + i, info);
2697 if (i == 0 || is_livepatch_module(mod) || 2702 if (i == 0 || is_livepatch_module(mod) ||
2698 is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum, 2703 is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
2699 info->index.pcpu)) { 2704 info->index.pcpu)) {
2705 mod->core_kallsyms.typetab[ndst] =
2706 mod->kallsyms->typetab[i];
2700 dst[ndst] = src[i]; 2707 dst[ndst] = src[i];
2701 dst[ndst++].st_name = s - mod->core_kallsyms.strtab; 2708 dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
2702 s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name], 2709 s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name],
@@ -4080,7 +4087,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
4080 const Elf_Sym *sym = &kallsyms->symtab[symnum]; 4087 const Elf_Sym *sym = &kallsyms->symtab[symnum];
4081 4088
4082 *value = kallsyms_symbol_value(sym); 4089 *value = kallsyms_symbol_value(sym);
4083 *type = sym->st_size; 4090 *type = kallsyms->typetab[symnum];
4084 strlcpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN); 4091 strlcpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN);
4085 strlcpy(module_name, mod->name, MODULE_NAME_LEN); 4092 strlcpy(module_name, mod->name, MODULE_NAME_LEN);
4086 *exported = is_exported(name, *value, mod); 4093 *exported = is_exported(name, *value, mod);