The routine to search a symbol in ELF can be shared, so split it out. Signed-off-by: Pingfan Liu <piliu@xxxxxxxxxx> Cc: Baoquan He <bhe@xxxxxxxxxx> Cc: Dave Young <dyoung@xxxxxxxxxx> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Philipp Rudo <prudo@xxxxxxxxxx> To: kexec@xxxxxxxxxxxxxxxxxxx --- include/linux/kexec.h | 4 ++ kernel/kexec_file.c | 86 +++++++++++++++++++++++-------------------- 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/include/linux/kexec.h b/include/linux/kexec.h index da527f323a930..6ab4d66a6a3fe 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -540,6 +540,10 @@ void set_kexec_sig_enforced(void); static inline void set_kexec_sig_enforced(void) {} #endif +#if defined(CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY) || defined(CONFIG_KEXEC_PE_IMAGE) +const Elf_Sym *elf_find_symbol(const Elf_Ehdr *ehdr, const char *name); +#endif + #endif /* !defined(__ASSEBMLY__) */ #endif /* LINUX_KEXEC_H */ diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index c92afe1a3aa5e..ce2ddb8d4bd80 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -831,6 +831,51 @@ static int kexec_calculate_store_digests(struct kimage *image) return ret; } +#if defined(CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY) || defined(CONFIG_KEXEC_PE_IMAGE) +const Elf_Sym *elf_find_symbol(const Elf_Ehdr *ehdr, const char *name) +{ + const Elf_Shdr *sechdrs; + const Elf_Sym *syms; + const char *strtab; + int i, k; + + sechdrs = (void *)ehdr + ehdr->e_shoff; + + for (i = 0; i < ehdr->e_shnum; i++) { + if (sechdrs[i].sh_type != SHT_SYMTAB) + continue; + + if (sechdrs[i].sh_link >= ehdr->e_shnum) + /* Invalid strtab section number */ + continue; + strtab = (void *)ehdr + sechdrs[sechdrs[i].sh_link].sh_offset; + syms = (void *)ehdr + sechdrs[i].sh_offset; + + /* Go through symbols for a match */ + for (k = 0; k < sechdrs[i].sh_size/sizeof(Elf_Sym); k++) { + if (ELF_ST_BIND(syms[k].st_info) != STB_GLOBAL) + continue; + + if (strcmp(strtab + syms[k].st_name, name) != 0) + continue; + + if (syms[k].st_shndx == SHN_UNDEF || + syms[k].st_shndx >= ehdr->e_shnum) { + pr_debug("Symbol: %s has bad section index %d.\n", + name, syms[k].st_shndx); + return NULL; + } + + /* Found the symbol we are looking for */ + return &syms[k]; + } + } + + return NULL; +} + +#endif + #ifdef CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY /* * kexec_purgatory_setup_kbuf - prepare buffer to load purgatory. @@ -1088,49 +1133,10 @@ int kexec_load_purgatory(struct kimage *image, struct kexec_buf *kbuf) static const Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi, const char *name) { - const Elf_Shdr *sechdrs; - const Elf_Ehdr *ehdr; - const Elf_Sym *syms; - const char *strtab; - int i, k; - if (!pi->ehdr) return NULL; - ehdr = pi->ehdr; - sechdrs = (void *)ehdr + ehdr->e_shoff; - - for (i = 0; i < ehdr->e_shnum; i++) { - if (sechdrs[i].sh_type != SHT_SYMTAB) - continue; - - if (sechdrs[i].sh_link >= ehdr->e_shnum) - /* Invalid strtab section number */ - continue; - strtab = (void *)ehdr + sechdrs[sechdrs[i].sh_link].sh_offset; - syms = (void *)ehdr + sechdrs[i].sh_offset; - - /* Go through symbols for a match */ - for (k = 0; k < sechdrs[i].sh_size/sizeof(Elf_Sym); k++) { - if (ELF_ST_BIND(syms[k].st_info) != STB_GLOBAL) - continue; - - if (strcmp(strtab + syms[k].st_name, name) != 0) - continue; - - if (syms[k].st_shndx == SHN_UNDEF || - syms[k].st_shndx >= ehdr->e_shnum) { - pr_debug("Symbol: %s has bad section index %d.\n", - name, syms[k].st_shndx); - return NULL; - } - - /* Found the symbol we are looking for */ - return &syms[k]; - } - } - - return NULL; + return elf_find_symbol(pi->ehdr, name); } void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name) -- 2.49.0