diff mbox series

[U-Boot,v2,09/18] elf: Add a very simple ELF64 loader

Message ID 1523509343-18123-10-git-send-email-bmeng.cn@gmail.com
State Accepted
Commit 839c4e9c5bb09ac1ef2c129c7082a15b9cbd3a8a
Delegated to: Bin Meng
Headers show
Series bootvx: Various enhancements to booting VxWorks x86 kernels | expand

Commit Message

Bin Meng April 12, 2018, 5:02 a.m. UTC
This adds a very simple ELF64 loader via program headers, similar
to load_elf_image_phdr() that we already have.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>

---

Changes in v2:
- update the ELF32 and ELF64 loader comments

 cmd/elf.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

Comments

Simon Glass April 12, 2018, 4:42 p.m. UTC | #1
On 11 April 2018 at 23:02, Bin Meng <bmeng.cn@gmail.com> wrote:
> This adds a very simple ELF64 loader via program headers, similar
> to load_elf_image_phdr() that we already have.
>
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
>
> ---
>
> Changes in v2:
> - update the ELF32 and ELF64 loader comments
>
>  cmd/elf.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 43 insertions(+), 1 deletion(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

I wonder if this should be used within the x86 relocate code?
Bin Meng April 13, 2018, 3:30 a.m. UTC | #2
Hi Simon,

On Fri, Apr 13, 2018 at 12:42 AM, Simon Glass <sjg@chromium.org> wrote:
> On 11 April 2018 at 23:02, Bin Meng <bmeng.cn@gmail.com> wrote:
>> This adds a very simple ELF64 loader via program headers, similar
>> to load_elf_image_phdr() that we already have.
>>
>> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
>>
>> ---
>>
>> Changes in v2:
>> - update the ELF32 and ELF64 loader comments
>>
>>  cmd/elf.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 43 insertions(+), 1 deletion(-)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> I wonder if this should be used within the x86 relocate code?

No, I don't think so.

Regards,
Bin
Bin Meng April 16, 2018, 9:16 a.m. UTC | #3
On Fri, Apr 13, 2018 at 12:42 AM, Simon Glass <sjg@chromium.org> wrote:
> On 11 April 2018 at 23:02, Bin Meng <bmeng.cn@gmail.com> wrote:
>> This adds a very simple ELF64 loader via program headers, similar
>> to load_elf_image_phdr() that we already have.
>>
>> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
>>
>> ---
>>
>> Changes in v2:
>> - update the ELF32 and ELF64 loader comments
>>
>>  cmd/elf.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 43 insertions(+), 1 deletion(-)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>

applied to u-boot-x86, thanks!
diff mbox series

Patch

diff --git a/cmd/elf.c b/cmd/elf.c
index 824f88e..8a0e7d9 100644
--- a/cmd/elf.c
+++ b/cmd/elf.c
@@ -24,8 +24,46 @@ 
 #endif
 
 /*
- * A very simple elf loader, assumes the image is valid, returns the
+ * A very simple ELF64 loader, assumes the image is valid, returns the
  * entry point address.
+ *
+ * Note if U-Boot is 32-bit, the loader assumes the to segment's
+ * physical address and size is within the lower 32-bit address space.
+ */
+static unsigned long load_elf64_image_phdr(unsigned long addr)
+{
+	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf64_Phdr *phdr; /* Program header structure pointer */
+	int i;
+
+	ehdr = (Elf64_Ehdr *)addr;
+	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
+
+	/* Load each program header */
+	for (i = 0; i < ehdr->e_phnum; ++i) {
+		void *dst = (void *)(ulong)phdr->p_paddr;
+		void *src = (void *)addr + phdr->p_offset;
+
+		debug("Loading phdr %i to 0x%p (%lu bytes)\n",
+		      i, dst, (ulong)phdr->p_filesz);
+		if (phdr->p_filesz)
+			memcpy(dst, src, phdr->p_filesz);
+		if (phdr->p_filesz != phdr->p_memsz)
+			memset(dst + phdr->p_filesz, 0x00,
+			       phdr->p_memsz - phdr->p_filesz);
+		flush_cache((unsigned long)dst, phdr->p_filesz);
+		++phdr;
+	}
+
+	return ehdr->e_entry;
+}
+
+/*
+ * A very simple ELF loader, assumes the image is valid, returns the
+ * entry point address.
+ *
+ * The loader firstly reads the EFI class to see if it's a 64-bit image.
+ * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
  */
 static unsigned long load_elf_image_phdr(unsigned long addr)
 {
@@ -34,12 +72,16 @@  static unsigned long load_elf_image_phdr(unsigned long addr)
 	int i;
 
 	ehdr = (Elf32_Ehdr *)addr;
+	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+		return load_elf64_image_phdr(addr);
+
 	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
 
 	/* Load each program header */
 	for (i = 0; i < ehdr->e_phnum; ++i) {
 		void *dst = (void *)(uintptr_t)phdr->p_paddr;
 		void *src = (void *)addr + phdr->p_offset;
+
 		debug("Loading phdr %i to 0x%p (%i bytes)\n",
 		      i, dst, phdr->p_filesz);
 		if (phdr->p_filesz)