Skip to contentSkip to conversation

elf: Add support for PPC64 ELF V1 ABI in bootelf

PATCH New Rob Bracero 2 participants 2 messages Aug 1, 2018 – Aug 11, 2018

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 elf: Add support for PPC64 ELF V1 ABI in bootelf

This update adds PPC64 ELF V1 ABI support to bootelf for both the program header and section header options. Elf64 support was already present for the program header option, but it was not handling the PPC64 ELF V1 ABI case. For the PPC64 ELF V1 ABI, the e_entry field of the elf header must be treated as function descriptor pointer instead of a function address. The first doubleword of the function descriptor is the function's entry address.

---
:100644 100644 eafea38... 0c38bde... M cmd/elf.c
:100644 100644 6802428... 81f4019... M include/elf.h

 cmd/elf.c     | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 include/elf.h |  3 +++
 2 files changed, 77 insertions(+), 1 deletion(-)
cmd/elf.c +74 -1
index eafea38..0c38bde 100644
@@ -57,6 +57,77 @@ static unsigned long load_elf64_image_phdr(unsigned long addr)
 		++phdr;
 	}
 
+	if((ehdr->e_machine == EM_PPC64) && (ehdr->e_flags & EF_PPC64_ELFV1_ABI))
+	{
+	    /*
+	     * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function descriptor
+	     * pointer with the first double word being the address of the entry
+	     * point of the function.
+	     */
+	    uintptr_t addr = ehdr->e_entry;
+	    return *(Elf64_Addr *)addr;
+	}
+		
+	return ehdr->e_entry;
+}
+
+static unsigned long load_elf64_image_shdr(unsigned long addr)
+{
+	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf64_Shdr *shdr; /* Section header structure pointer */
+	unsigned char *strtab = 0; /* String table pointer */
+	unsigned char *image; /* Binary image pointer */
+	int i; /* Loop counter */
+
+	ehdr = (Elf64_Ehdr *)addr;
+
+	/* Find the section header string table for output info */
+	shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
+			     (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
+
+	if (shdr->sh_type == SHT_STRTAB)
+		strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
+
+	/* Load each appropriate section */
+	for (i = 0; i < ehdr->e_shnum; ++i) {
+		shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
+				     (i * sizeof(Elf64_Shdr)));
+
+		if (!(shdr->sh_flags & SHF_ALLOC) ||
+		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
+			continue;
+		}
+
+		if (strtab) {
+			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
+			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
+			       &strtab[shdr->sh_name],
+			       (unsigned long)shdr->sh_addr,
+			       (long)shdr->sh_size);
+		}
+
+		if (shdr->sh_type == SHT_NOBITS) {
+			memset((void *)(uintptr_t)shdr->sh_addr, 0,
+			       shdr->sh_size);
+		} else {
+			image = (unsigned char *)addr + (ulong)shdr->sh_offset;
+			memcpy((void *)(uintptr_t)shdr->sh_addr,
+			       (const void *)image, shdr->sh_size);
+		}
+		flush_cache((ulong)shdr->sh_addr, shdr->sh_size);
+	}
+
+	if((ehdr->e_machine == EM_PPC64) && (ehdr->e_flags & EF_PPC64_ELFV1_ABI))
+	{
+	    /*
+	     * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function descriptor
+	     * pointer with the first double word being the address of the entry
+	     * point of the function.
+	     */
+	    uintptr_t addr = ehdr->e_entry;
+	    return *(Elf64_Addr *)addr;
+	}
+	
 	return ehdr->e_entry;
 }
 
@@ -107,7 +178,9 @@ static unsigned long load_elf_image_shdr(unsigned long addr)
 	int i; /* Loop counter */
 
 	ehdr = (Elf32_Ehdr *)addr;
-
+	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+		return load_elf64_image_shdr(addr);
+	
 	/* Find the section header string table for output info */
 	shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
 			     (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
include/elf.h +3 -0
index 6802428..81f4019 100644
@@ -593,6 +593,9 @@ unsigned long elf_hash(const unsigned char *name);
 /* Values for Elf32/64_Ehdr.e_flags */
 #define EF_PPC_EMB		0x80000000	/* PowerPC embedded flag */
 
+#define EF_PPC64_ELFV1_ABI	0x00000001
+#define EF_PPC64_ELFV2_ABI	0x00000002
+
 /* Cygnus local bits below */
 #define EF_PPC_RELOCATABLE	0x00010000	/* PowerPC -mrelocatable flag*/
 #define EF_PPC_RELOCATABLE_LIB	0x00008000	/* PowerPC -mrelocatable-lib
Signature · 1 line
1.8.3.1
#1 lore raw

PATCH 1/1 elf: Add support for PPC64 ELF V1 ABI in bootelf

Quoted 9 lines · Rob Bracero

This update adds PPC64 ELF V1 ABI support to bootelf for both the program header and section header options. Elf64 support was already present for the program header option, but it was not handling the PPC64 ELF V1 ABI case. For the PPC64 ELF V1 ABI, the e_entry field of the elf header must be treated as function descriptor pointer instead of a function address. The first doubleword of the function descriptor is the function's entry address.

Applied to u-boot/master, thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180810/22cb0e9d/attachment.sig>