[PATCHv7 08/13] kexec_file: Factor out routine to find a symbol in ELF
Pingfan Liu
piliu at redhat.com
Sat Mar 21 18:43:57 PDT 2026
The routine to search a symbol in ELF can be shared, so split it out.
Signed-off-by: Pingfan Liu <piliu at redhat.com>
Cc: Baoquan He <bhe at redhat.com>
Cc: Dave Young <dyoung at redhat.com>
Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: Philipp Rudo <prudo at redhat.com>
To: kexec at lists.infradead.org
---
kernel/kexec_file.c | 61 +++++++++++++++++++++++++++++++++++++++++
kernel/kexec_internal.h | 1 +
2 files changed, 62 insertions(+)
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index aca265034b4ed..15857a56e6278 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -902,6 +902,51 @@ static int kexec_calculate_store_digests(struct kimage *image)
return ret;
}
+#if defined(CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY) || defined(CONFIG_KEXEC_BPF)
+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_find_symbol - find a symbol in the purgatory
@@ -1221,6 +1266,22 @@ int kexec_load_purgatory(struct kimage *image, struct kexec_buf *kbuf)
return ret;
}
+/*
+ * kexec_purgatory_find_symbol - find a symbol in the purgatory
+ * @pi: Purgatory to search in.
+ * @name: Name of the symbol.
+ *
+ * Return: pointer to symbol in read-only symtab on success, NULL on error.
+ */
+static const Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi,
+ const char *name)
+{
+ if (!pi->ehdr)
+ return NULL;
+
+ return elf_find_symbol(pi->ehdr, name);
+}
+
void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name)
{
struct purgatory_info *pi = &image->purgatory_info;
diff --git a/kernel/kexec_internal.h b/kernel/kexec_internal.h
index 731ff02110b3c..224f09188db23 100644
--- a/kernel/kexec_internal.h
+++ b/kernel/kexec_internal.h
@@ -40,6 +40,7 @@ void kimage_file_post_load_cleanup(struct kimage *image);
extern char kexec_purgatory[];
extern size_t kexec_purgatory_size;
extern int decompose_kexec_image(struct kimage *image, int extended_fd);
+extern const Elf_Sym *elf_find_symbol(const Elf_Ehdr *ehdr, const char *name);
#else /* CONFIG_KEXEC_FILE */
static inline void kimage_file_post_load_cleanup(struct kimage *image) { }
#endif /* CONFIG_KEXEC_FILE */
--
2.49.0
More information about the kexec
mailing list