[PATCH 1/7] kexec: add a elf_rel_find_section service

Cédric Le Goater clg at fr.ibm.com
Fri Apr 18 07:08:34 PDT 2014


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




More information about the kexec mailing list