All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
To: u-boot@lists.denx.de
Subject: [PATCH v2 1/9] lib: elf: Move the generic elf loading/validating functions to lib
Date: Fri, 17 Jan 2020 08:49:03 +0100	[thread overview]
Message-ID: <CAAh8qsz5h8LNAwpgz-gkyuR+hJaYrEh_Q4aQ1knccSwQeZuong@mail.gmail.com> (raw)
In-Reply-To: <be6fe45a-4c17-d30b-07e7-c8d85c1f9838@ti.com>

On Fri, Jan 17, 2020 at 5:27 AM Lokesh Vutla <lokeshvutla@ti.com> wrote:
>
> Simon,
>
> On 13/01/20 11:24 AM, Keerthy wrote:
> > Move the generic elf loading/validating functions to lib/
> > so that they can be re-used and accessed by code existing
> > outside cmd.
> >
> > Signed-off-by: Keerthy <j-keerthy@ti.com>
> > Suggested-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
>
> Are you okay with this patch? If yes, Ill apply to u-boot-ti along with other
> patches in this series.

Yes.

Reviewed-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>

Regards,
Simon

>
> Thanks and regards,
> Lokesh
>
> > ---
> > Changes in v2:
> >
> >   * Factored out all the generic elf handling functions under lib/elf.c
> >
> >  cmd/Kconfig   |   1 +
> >  cmd/elf.c     | 229 --------------------------------------------
> >  include/elf.h |   4 +
> >  lib/Kconfig   |   3 +
> >  lib/Makefile  |   1 +
> >  lib/elf.c     | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  6 files changed, 265 insertions(+), 229 deletions(-)
> >  create mode 100644 lib/elf.c
> >
> > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > index 298feae24d..6f4f08d02a 100644
> > --- a/cmd/Kconfig
> > +++ b/cmd/Kconfig
> > @@ -375,6 +375,7 @@ config CMD_ADTIMG
> >  config CMD_ELF
> >       bool "bootelf, bootvx"
> >       default y
> > +     select ELF
> >       help
> >         Boot an ELF/vxWorks image from the memory.
> >
> > diff --git a/cmd/elf.c b/cmd/elf.c
> > index 32f12a72b9..23cc17aebc 100644
> > --- a/cmd/elf.c
> > +++ b/cmd/elf.c
> > @@ -26,211 +26,6 @@
> >  #include <linux/linkage.h>
> >  #endif
> >
> > -/*
> > - * 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(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> > -                         roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> > -             ++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(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> > -                         roundup((shdr->sh_addr + shdr->sh_size),
> > -                                  ARCH_DMA_MINALIGN) -
> > -                                 rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> > -     }
> > -
> > -     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;
> > -}
> > -
> > -/*
> > - * 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)
> > -{
> > -     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > -     Elf32_Phdr *phdr; /* Program header structure pointer */
> > -     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)
> > -                     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(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> > -                         roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> > -             ++phdr;
> > -     }
> > -
> > -     return ehdr->e_entry;
> > -}
> > -
> > -static unsigned long load_elf_image_shdr(unsigned long addr)
> > -{
> > -     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > -     Elf32_Shdr *shdr; /* Section header structure pointer */
> > -     unsigned char *strtab = 0; /* String table pointer */
> > -     unsigned char *image; /* Binary image pointer */
> > -     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)));
> > -
> > -     if (shdr->sh_type == SHT_STRTAB)
> > -             strtab = (unsigned char *)(addr + shdr->sh_offset);
> > -
> > -     /* Load each appropriate section */
> > -     for (i = 0; i < ehdr->e_shnum; ++i) {
> > -             shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> > -                                  (i * sizeof(Elf32_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 + shdr->sh_offset;
> > -                     memcpy((void *)(uintptr_t)shdr->sh_addr,
> > -                            (const void *)image, shdr->sh_size);
> > -             }
> > -             flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> > -                         roundup((shdr->sh_addr + shdr->sh_size),
> > -                                 ARCH_DMA_MINALIGN) -
> > -                         rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> > -     }
> > -
> > -     return ehdr->e_entry;
> > -}
> > -
> >  /* Allow ports to override the default behavior */
> >  static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
> >                                    int argc, char * const argv[])
> > @@ -246,30 +41,6 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
> >       return ret;
> >  }
> >
> > -/*
> > - * Determine if a valid ELF image exists at the given memory location.
> > - * First look at the ELF header magic field, then make sure that it is
> > - * executable.
> > - */
> > -int valid_elf_image(unsigned long addr)
> > -{
> > -     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > -
> > -     ehdr = (Elf32_Ehdr *)addr;
> > -
> > -     if (!IS_ELF(*ehdr)) {
> > -             printf("## No elf image at address 0x%08lx\n", addr);
> > -             return 0;
> > -     }
> > -
> > -     if (ehdr->e_type != ET_EXEC) {
> > -             printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
> > -             return 0;
> > -     }
> > -
> > -     return 1;
> > -}
> > -
> >  /* Interpreter command to boot an arbitrary ELF image from memory */
> >  int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> >  {
> > diff --git a/include/elf.h b/include/elf.h
> > index 81f40191d7..e7c51986df 100644
> > --- a/include/elf.h
> > +++ b/include/elf.h
> > @@ -692,6 +692,10 @@ unsigned long elf_hash(const unsigned char *name);
> >
> >  #ifndef __ASSEMBLER__
> >  int valid_elf_image(unsigned long addr);
> > +unsigned long load_elf64_image_phdr(unsigned long addr);
> > +unsigned long load_elf64_image_shdr(unsigned long addr);
> > +unsigned long load_elf_image_phdr(unsigned long addr);
> > +unsigned long load_elf_image_shdr(unsigned long addr);
> >  #endif
> >
> >  #endif /* _ELF_H */
> > diff --git a/lib/Kconfig b/lib/Kconfig
> > index d040a87d26..b155ced4b2 100644
> > --- a/lib/Kconfig
> > +++ b/lib/Kconfig
> > @@ -601,4 +601,7 @@ config TEST_FDTDEC
> >  config LIB_DATE
> >       bool
> >
> > +config ELF
> > +     bool "enable basic elf loading/validating functions"
> > +
> >  endmenu
> > diff --git a/lib/Makefile b/lib/Makefile
> > index 6b7b9ce85c..93f22d210e 100644
> > --- a/lib/Makefile
> > +++ b/lib/Makefile
> > @@ -121,6 +121,7 @@ obj-y += vsprintf.o strto.o
> >  endif
> >
> >  obj-y += date.o
> > +obj-$(CONFIG_ELF) += elf.o
> >
> >  #
> >  # Build a fast OID lookup registry from include/linux/oid_registry.h
> > diff --git a/lib/elf.c b/lib/elf.c
> > new file mode 100644
> > index 0000000000..54ac4ee502
> > --- /dev/null
> > +++ b/lib/elf.c
> > @@ -0,0 +1,256 @@
> > +/*
> > + * Copyright (c) 2001 William L. Pitts
> > + * All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms are freely
> > + * permitted provided that the above copyright notice and this
> > + * paragraph and the following disclaimer are duplicated in all
> > + * such forms.
> > + *
> > + * This software is provided "AS IS" and without any express or
> > + * implied warranties, including, without limitation, the implied
> > + * warranties of merchantability and fitness for a particular
> > + * purpose.
> > + */
> > +
> > +#include <common.h>
> > +#include <command.h>
> > +#include <cpu_func.h>
> > +#include <elf.h>
> > +#include <env.h>
> > +#include <net.h>
> > +#include <vxworks.h>
> > +#ifdef CONFIG_X86
> > +#include <vbe.h>
> > +#include <asm/e820.h>
> > +#include <linux/linkage.h>
> > +#endif
> > +
> > +/*
> > + * 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.
> > + */
> > +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(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> > +                         roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> > +             ++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;
> > +}
> > +
> > +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(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> > +                         roundup((shdr->sh_addr + shdr->sh_size),
> > +                                  ARCH_DMA_MINALIGN) -
> > +                                 rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> > +     }
> > +
> > +     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;
> > +}
> > +
> > +/*
> > + * 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.
> > + */
> > +unsigned long load_elf_image_phdr(unsigned long addr)
> > +{
> > +     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > +     Elf32_Phdr *phdr; /* Program header structure pointer */
> > +     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)
> > +                     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(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> > +                         roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> > +             ++phdr;
> > +     }
> > +
> > +     return ehdr->e_entry;
> > +}
> > +
> > +unsigned long load_elf_image_shdr(unsigned long addr)
> > +{
> > +     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > +     Elf32_Shdr *shdr; /* Section header structure pointer */
> > +     unsigned char *strtab = 0; /* String table pointer */
> > +     unsigned char *image; /* Binary image pointer */
> > +     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)));
> > +
> > +     if (shdr->sh_type == SHT_STRTAB)
> > +             strtab = (unsigned char *)(addr + shdr->sh_offset);
> > +
> > +     /* Load each appropriate section */
> > +     for (i = 0; i < ehdr->e_shnum; ++i) {
> > +             shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> > +                                  (i * sizeof(Elf32_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 + shdr->sh_offset;
> > +                     memcpy((void *)(uintptr_t)shdr->sh_addr,
> > +                            (const void *)image, shdr->sh_size);
> > +             }
> > +             flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> > +                         roundup((shdr->sh_addr + shdr->sh_size),
> > +                                 ARCH_DMA_MINALIGN) -
> > +                         rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> > +     }
> > +
> > +     return ehdr->e_entry;
> > +}
> > +
> > +/*
> > + * Determine if a valid ELF image exists at the given memory location.
> > + * First look at the ELF header magic field, then make sure that it is
> > + * executable.
> > + */
> > +int valid_elf_image(unsigned long addr)
> > +{
> > +     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > +
> > +     ehdr = (Elf32_Ehdr *)addr;
> > +
> > +     if (!IS_ELF(*ehdr)) {
> > +             printf("## No elf image at address 0x%08lx\n", addr);
> > +             return 0;
> > +     }
> > +
> > +     if (ehdr->e_type != ET_EXEC) {
> > +             printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
> > +             return 0;
> > +     }
> > +
> > +     return 1;
> > +}
> >

  reply	other threads:[~2020-01-17  7:49 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-13  5:54 [PATCH v2 0/9]k3: Add support for loading main_r5fss0_core0 Keerthy
2020-01-13  5:54 ` [PATCH v2 1/9] lib: elf: Move the generic elf loading/validating functions to lib Keerthy
2020-01-17  4:27   ` Lokesh Vutla
2020-01-17  7:49     ` Simon Goldschmidt [this message]
2020-01-17  8:06       ` Keerthy
2020-01-13  5:54 ` [PATCH v2 2/9] arm: k3: Add support for loading non linux remote cores Keerthy
2020-01-13  5:54 ` [PATCH v2 3/9] armv7R: K3: r5_mpu: Enable execute permission for MCU0 BTCM Keerthy
2020-01-13  5:54 ` [PATCH v2 4/9] armv7R: K3: Add support for jumping to firmware Keerthy
2020-01-13  5:54 ` [PATCH v2 5/9] arm: dts: k3-j721e-r5: Add fs_loader node Keerthy
2020-01-13  5:54 ` [PATCH v2 6/9] arm: dts: k3-j721e-r5: Enable r5fss0 cluster in SPL Keerthy
2020-01-13  5:54 ` [PATCH v2 7/9] include: configs: j721e_evm: Add env variables for mcu_r5fss0_core0 & main_r5fss0_core0 Keerthy
2020-01-13  5:54 ` [PATCH v2 8/9] configs: j721e_evm_r5: Add configs for environment in eMMC Keerthy
2020-01-17  5:14   ` Lokesh Vutla
2020-01-13  5:54 ` [PATCH v2 9/9] configs: j721e_evm_r5: Enable R5F remoteproc support Keerthy

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=CAAh8qsz5h8LNAwpgz-gkyuR+hJaYrEh_Q4aQ1knccSwQeZuong@mail.gmail.com \
    --to=simon.k.r.goldschmidt@gmail.com \
    --cc=u-boot@lists.denx.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.