From: Sven Schnelle <svens@stackframe.org>
To: kexec@lists.infradead.org
Cc: Sven Schnelle <svens@stackframe.org>,
deller@gmx.de, linuxppc-dev@lists.ozlabs.org
Subject: [PATCH v4 7/7] kexec_elf: support 32 bit ELF files
Date: Mon, 15 Jul 2019 10:27:02 +0200 [thread overview]
Message-ID: <20190715082702.27308-8-svens@stackframe.org> (raw)
In-Reply-To: <20190715082702.27308-1-svens@stackframe.org>
The powerpc version only supported 64 bit. Add some
code to switch decoding of fields during runtime so
we can kexec a 32 bit kernel from a 64 bit kernel and
vice versa.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
kernel/kexec_elf.c | 57 ++++++++++++++++++++++++++++++++++------------
1 file changed, 42 insertions(+), 15 deletions(-)
diff --git a/kernel/kexec_elf.c b/kernel/kexec_elf.c
index 9421eebbacf0..a39d01154829 100644
--- a/kernel/kexec_elf.c
+++ b/kernel/kexec_elf.c
@@ -8,8 +8,6 @@
#include <linux/slab.h>
#include <linux/types.h>
-#define elf_addr_to_cpu elf64_to_cpu
-
static inline bool elf_is_elf_file(const struct elfhdr *ehdr)
{
return memcmp(ehdr->e_ident, ELFMAG, SELFMAG) == 0;
@@ -139,9 +137,6 @@ static int elf_read_ehdr(const char *buf, size_t len, struct elfhdr *ehdr)
ehdr->e_type = elf16_to_cpu(ehdr, buf_ehdr->e_type);
ehdr->e_machine = elf16_to_cpu(ehdr, buf_ehdr->e_machine);
ehdr->e_version = elf32_to_cpu(ehdr, buf_ehdr->e_version);
- ehdr->e_entry = elf_addr_to_cpu(ehdr, buf_ehdr->e_entry);
- ehdr->e_phoff = elf_addr_to_cpu(ehdr, buf_ehdr->e_phoff);
- ehdr->e_shoff = elf_addr_to_cpu(ehdr, buf_ehdr->e_shoff);
ehdr->e_flags = elf32_to_cpu(ehdr, buf_ehdr->e_flags);
ehdr->e_phentsize = elf16_to_cpu(ehdr, buf_ehdr->e_phentsize);
ehdr->e_phnum = elf16_to_cpu(ehdr, buf_ehdr->e_phnum);
@@ -149,6 +144,24 @@ static int elf_read_ehdr(const char *buf, size_t len, struct elfhdr *ehdr)
ehdr->e_shnum = elf16_to_cpu(ehdr, buf_ehdr->e_shnum);
ehdr->e_shstrndx = elf16_to_cpu(ehdr, buf_ehdr->e_shstrndx);
+ switch (ehdr->e_ident[EI_CLASS]) {
+ case ELFCLASS64:
+ ehdr->e_entry = elf64_to_cpu(ehdr, buf_ehdr->e_entry);
+ ehdr->e_phoff = elf64_to_cpu(ehdr, buf_ehdr->e_phoff);
+ ehdr->e_shoff = elf64_to_cpu(ehdr, buf_ehdr->e_shoff);
+ break;
+
+ case ELFCLASS32:
+ ehdr->e_entry = elf32_to_cpu(ehdr, buf_ehdr->e_entry);
+ ehdr->e_phoff = elf32_to_cpu(ehdr, buf_ehdr->e_phoff);
+ ehdr->e_shoff = elf32_to_cpu(ehdr, buf_ehdr->e_shoff);
+ break;
+
+ default:
+ pr_debug("Unknown ELF class.\n");
+ return -EINVAL;
+ }
+
return elf_is_ehdr_sane(ehdr, len) ? 0 : -ENOEXEC;
}
@@ -179,6 +192,7 @@ static int elf_read_phdr(const char *buf, size_t len,
{
/* Override the const in proghdrs, we are the ones doing the loading. */
struct elf_phdr *phdr = (struct elf_phdr *) &elf_info->proghdrs[idx];
+ const struct elfhdr *ehdr = elf_info->ehdr;
const char *pbuf;
struct elf_phdr *buf_phdr;
@@ -186,18 +200,31 @@ static int elf_read_phdr(const char *buf, size_t len,
buf_phdr = (struct elf_phdr *) pbuf;
phdr->p_type = elf32_to_cpu(elf_info->ehdr, buf_phdr->p_type);
- phdr->p_offset = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_offset);
- phdr->p_paddr = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_paddr);
- phdr->p_vaddr = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_vaddr);
phdr->p_flags = elf32_to_cpu(elf_info->ehdr, buf_phdr->p_flags);
- /*
- * The following fields have a type equivalent to Elf_Addr
- * both in 32 bit and 64 bit ELF.
- */
- phdr->p_filesz = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_filesz);
- phdr->p_memsz = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_memsz);
- phdr->p_align = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_align);
+ switch (ehdr->e_ident[EI_CLASS]) {
+ case ELFCLASS64:
+ phdr->p_offset = elf64_to_cpu(ehdr, buf_phdr->p_offset);
+ phdr->p_paddr = elf64_to_cpu(ehdr, buf_phdr->p_paddr);
+ phdr->p_vaddr = elf64_to_cpu(ehdr, buf_phdr->p_vaddr);
+ phdr->p_filesz = elf64_to_cpu(ehdr, buf_phdr->p_filesz);
+ phdr->p_memsz = elf64_to_cpu(ehdr, buf_phdr->p_memsz);
+ phdr->p_align = elf64_to_cpu(ehdr, buf_phdr->p_align);
+ break;
+
+ case ELFCLASS32:
+ phdr->p_offset = elf32_to_cpu(ehdr, buf_phdr->p_offset);
+ phdr->p_paddr = elf32_to_cpu(ehdr, buf_phdr->p_paddr);
+ phdr->p_vaddr = elf32_to_cpu(ehdr, buf_phdr->p_vaddr);
+ phdr->p_filesz = elf32_to_cpu(ehdr, buf_phdr->p_filesz);
+ phdr->p_memsz = elf32_to_cpu(ehdr, buf_phdr->p_memsz);
+ phdr->p_align = elf32_to_cpu(ehdr, buf_phdr->p_align);
+ break;
+
+ default:
+ pr_debug("Unknown ELF class.\n");
+ return -EINVAL;
+ }
return elf_is_phdr_sane(phdr, len) ? 0 : -ENOEXEC;
}
--
2.20.1
next prev parent reply other threads:[~2019-07-15 8:30 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-15 8:26 [PATCH v4 0/7] kexec: add generic support for elf kernel images Sven Schnelle
2019-07-15 8:26 ` [PATCH v4 1/7] kexec: add KEXEC_ELF Sven Schnelle
2019-08-21 0:58 ` Thiago Jung Bauermann
2019-08-21 20:15 ` Thiago Jung Bauermann
2019-07-15 8:26 ` [PATCH v4 2/7] kexec_elf: change order of elf_*_to_cpu() functions Sven Schnelle
2019-08-21 0:59 ` Thiago Jung Bauermann
2019-07-15 8:26 ` [PATCH v4 3/7] kexec_elf: remove parsing of section headers Sven Schnelle
2019-08-21 0:59 ` Thiago Jung Bauermann
2019-07-15 8:26 ` [PATCH v4 4/7] kexec_elf: remove PURGATORY_STACK_SIZE Sven Schnelle
2019-08-21 1:00 ` Thiago Jung Bauermann
2019-08-21 1:13 ` Thiago Jung Bauermann
2019-07-15 8:27 ` [PATCH v4 5/7] kexec_elf: remove Elf_Rel macro Sven Schnelle
2019-08-21 1:01 ` Thiago Jung Bauermann
2019-07-15 8:27 ` [PATCH v4 6/7] kexec_elf: remove unused variable in kexec_elf_load() Sven Schnelle
2019-08-21 1:02 ` Thiago Jung Bauermann
2019-07-15 8:27 ` Sven Schnelle [this message]
2019-08-21 1:03 ` [PATCH v4 7/7] kexec_elf: support 32 bit ELF files Thiago Jung Bauermann
2019-08-21 1:11 ` [PATCH v4 0/7] kexec: add generic support for elf kernel images Thiago Jung Bauermann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190715082702.27308-8-svens@stackframe.org \
--to=svens@stackframe.org \
--cc=deller@gmx.de \
--cc=kexec@lists.infradead.org \
--cc=linuxppc-dev@lists.ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).