0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/string.h>
0010 #include <linux/slab.h>
0011 #include "internal.h"
0012
0013
0014
0015
0016
0017
0018 int copy_module_elf(struct module *mod, struct load_info *info)
0019 {
0020 unsigned int size, symndx;
0021 int ret;
0022
0023 size = sizeof(*mod->klp_info);
0024 mod->klp_info = kmalloc(size, GFP_KERNEL);
0025 if (!mod->klp_info)
0026 return -ENOMEM;
0027
0028
0029 size = sizeof(mod->klp_info->hdr);
0030 memcpy(&mod->klp_info->hdr, info->hdr, size);
0031
0032
0033 size = sizeof(*info->sechdrs) * info->hdr->e_shnum;
0034 mod->klp_info->sechdrs = kmemdup(info->sechdrs, size, GFP_KERNEL);
0035 if (!mod->klp_info->sechdrs) {
0036 ret = -ENOMEM;
0037 goto free_info;
0038 }
0039
0040
0041 size = info->sechdrs[info->hdr->e_shstrndx].sh_size;
0042 mod->klp_info->secstrings = kmemdup(info->secstrings, size, GFP_KERNEL);
0043 if (!mod->klp_info->secstrings) {
0044 ret = -ENOMEM;
0045 goto free_sechdrs;
0046 }
0047
0048
0049 symndx = info->index.sym;
0050 mod->klp_info->symndx = symndx;
0051
0052
0053
0054
0055
0056
0057
0058 mod->klp_info->sechdrs[symndx].sh_addr = (unsigned long)mod->core_kallsyms.symtab;
0059
0060 return 0;
0061
0062 free_sechdrs:
0063 kfree(mod->klp_info->sechdrs);
0064 free_info:
0065 kfree(mod->klp_info);
0066 return ret;
0067 }
0068
0069 void free_module_elf(struct module *mod)
0070 {
0071 kfree(mod->klp_info->sechdrs);
0072 kfree(mod->klp_info->secstrings);
0073 kfree(mod->klp_info);
0074 }