It can be directly used to find the .toc section on ppc64 and it will be used to look for the section containing the compressed vmlinux in a ppc64 zImage. Signed-off-by: C?dric Le Goater <clg at fr.ibm.com> --- kexec/arch/ppc64/kexec-elf-rel-ppc64.c | 19 +------------------ kexec/kexec-elf-rel.c | 17 +++++++++++++++++ kexec/kexec-elf.h | 2 ++ 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/kexec/arch/ppc64/kexec-elf-rel-ppc64.c b/kexec/arch/ppc64/kexec-elf-rel-ppc64.c index 9b191d0025a4..708f507a50a6 100644 --- a/kexec/arch/ppc64/kexec-elf-rel-ppc64.c +++ b/kexec/arch/ppc64/kexec-elf-rel-ppc64.c @@ -17,23 +17,6 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr) return 1; } -static struct mem_shdr *toc_section(const struct mem_ehdr *ehdr) -{ - struct mem_shdr *shdr, *shdr_end; - unsigned char *strtab; - - strtab = (unsigned char *)ehdr->e_shdr[ehdr->e_shstrndx].sh_data; - shdr_end = &ehdr->e_shdr[ehdr->e_shnum]; - for (shdr = ehdr->e_shdr; shdr != shdr_end; shdr++) { - if (shdr->sh_size && - strcmp((char *)&strtab[shdr->sh_name], ".toc") == 0) { - return shdr; - } - } - - return NULL; -} - /* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this gives the value maximum span in an instruction which uses a signed offset) */ @@ -41,7 +24,7 @@ unsigned long my_r2(const struct mem_ehdr *ehdr) { struct mem_shdr *shdr; - shdr = toc_section(ehdr); + shdr = elf_rel_find_section(ehdr, ".toc"); if (!shdr) { die("TOC reloc without a toc section?"); } diff --git a/kexec/kexec-elf-rel.c b/kexec/kexec-elf-rel.c index c625f30381bc..322ac123cbd6 100644 --- a/kexec/kexec-elf-rel.c +++ b/kexec/kexec-elf-rel.c @@ -435,6 +435,23 @@ void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, } } +struct mem_shdr *elf_rel_find_section(const struct mem_ehdr *ehdr, + const char *name) +{ + struct mem_shdr *shdr, *shdr_end; + unsigned char *strtab; + + strtab = (unsigned char *)ehdr->e_shdr[ehdr->e_shstrndx].sh_data; + shdr_end = &ehdr->e_shdr[ehdr->e_shnum]; + for (shdr = ehdr->e_shdr; shdr != shdr_end; shdr++) { + if (shdr->sh_size && + strcmp((char *)&strtab[shdr->sh_name], name) == 0) { + return shdr; + } + } + return NULL; +} + int elf_rel_find_symbol(struct mem_ehdr *ehdr, const char *name, struct mem_sym *ret_sym) { diff --git a/kexec/kexec-elf.h b/kexec/kexec-elf.h index d0e9dc0b1e02..19b5769d1838 100644 --- a/kexec/kexec-elf.h +++ b/kexec/kexec-elf.h @@ -109,6 +109,8 @@ extern void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, const char *buf, off_t len, unsigned long min, unsigned long max, int end, uint32_t flags); +extern struct mem_shdr *elf_rel_find_section(const struct mem_ehdr *ehdr, + const char *name); extern int elf_rel_find_symbol(struct mem_ehdr *ehdr, const char *name, struct mem_sym *ret_sym); extern unsigned long elf_rel_get_addr(struct mem_ehdr *ehdr, const char *name); -- 1.7.10.4