mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Oleksij Rempel <o.rempel@pengutronix.de>
Cc: barebox@lists.infradead.org
Subject: Re: [PATCH 2/4] add basic ELF parser
Date: Fri, 1 Jun 2018 08:49:29 +0200	[thread overview]
Message-ID: <20180601064929.aryh7oe2ktd3snya@pengutronix.de> (raw)
In-Reply-To: <20180531204851.1719-2-o.rempel@pengutronix.de>

On Thu, May 31, 2018 at 10:48:49PM +0200, Oleksij Rempel wrote:
> This parser is needed for kernel boot support on MIPS
> and can potentially reused on other platforms.
> 
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
> ---
>  common/Makefile |   1 +
>  common/elf.c    | 146 ++++++++++++++++++++++++++++++++++++++++++++++++
>  include/elf.h   |  10 ++++
>  3 files changed, 157 insertions(+)
>  create mode 100644 common/elf.c
> 
> diff --git a/common/Makefile b/common/Makefile
> index 1ff7d2370..4fe7eaaf6 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -8,6 +8,7 @@ obj-y				+= misc.o
>  obj-pbl-y			+= memsize.o
>  obj-y				+= resource.o
>  obj-y				+= bootsource.o
> +obj-y				+= elf.o
>  obj-y				+= restart.o
>  obj-y				+= poweroff.o
>  obj-$(CONFIG_AUTO_COMPLETE)	+= complete.o
> diff --git a/common/elf.c b/common/elf.c
> new file mode 100644
> index 000000000..d6a1f8b6a
> --- /dev/null
> +++ b/common/elf.c
> @@ -0,0 +1,146 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
> + */
> +
> +#include <common.h>
> +#include <elf.h>
> +#include <memory.h>
> +
> +struct elf_section {
> +	struct list_head list;
> +	struct resource *r;
> +};
> +
> +static int elf_request_region(struct elf_image *elf, resource_size_t start,
> +			      resource_size_t size)
> +{
> +	struct list_head *list = &elf->list;
> +	struct resource *r_new;
> +	struct elf_section *r;
> +
> +	r = xzalloc(sizeof(*r));
> +	r_new = request_sdram_region("elf_section", start, size);
> +	if (!r_new) {
> +		pr_err("Failed to request region: %x %x\n", start, size);

For resource_size_t type please use the %pa format specifier.

> +		return -EINVAL;
> +	}
> +
> +	r->r = r_new;
> +	list_add_tail(&r->list, list);
> +
> +	return 0;
> +}
> +
> +static void elf_release_regions(struct elf_image *elf)
> +{
> +	struct list_head *list = &elf->list;
> +	struct elf_section *r, *r_tmp;
> +
> +	list_for_each_entry_safe(r, r_tmp, list, list) {
> +		release_sdram_region(r->r);
> +		free(r);
> +	}
> +}
> +
> +
> +static int load_elf_phdr_segment(struct elf_image *elf, void *src,
> +				 Elf32_Phdr *phdr)
> +{
> +	void *dst = (void *)phdr->p_paddr;
> +	int ret;
> +
> +	/* we care only about PT_LOAD segments */
> +	if (phdr->p_type != PT_LOAD)
> +		return 0;
> +
> +	if (!phdr->p_filesz)
> +		return 0;
> +
> +	pr_debug("Loading phdr to 0x%p (%i bytes)\n", dst, phdr->p_filesz);
> +
> +	ret = elf_request_region(elf, (resource_size_t)dst, phdr->p_filesz);
> +	if (ret)
> +		return ret;
> +
> +	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);
> +
> +	return 0;
> +}
> +
> +static int load_elf_image_phdr(struct elf_image *elf)
> +{
> +	void *buf = elf->buf;
> +	Elf32_Ehdr *ehdr = buf;
> +	Elf32_Phdr *phdr = (Elf32_Phdr *)(buf + ehdr->e_phoff);
> +	int i, ret;
> +
> +	elf->entry = ehdr->e_entry;
> +
> +	for (i = 0; i < ehdr->e_phnum; ++i) {
> +		void *src = buf + phdr->p_offset;
> +
> +		ret = load_elf_phdr_segment(elf, src, phdr);
> +		/* in case of error elf_load_image() caller should clean up and
> +		 * call elf_release_image() */
> +		if (ret)
> +			return ret;
> +
> +		++phdr;
> +	}
> +
> +	return 0;
> +}
> +
> +static int elf_check_image(void *buf)
> +{
> +	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)buf;
> +
> +	if (strncmp(buf, ELFMAG, SELFMAG)) {
> +		pr_err("ELF magic not found.\n");
> +                return -EINVAL;
> +        }

Whitespace broken here

> +
> +	if (ehdr->e_type != ET_EXEC) {
> +		pr_err("Non EXEC ELF image.\n");
> +                return -ENOEXEC;
> +	}
> +
> +	return 0;
> +}
> +
> +struct elf_image *elf_load_image(void *buf)
> +{
> +	struct elf_image *elf;
> +	int ret;
> +
> +	elf = xzalloc(sizeof(*elf));
> +
> +	INIT_LIST_HEAD(&elf->list);
> +
> +	elf->buf = buf;
> +
> +	ret = elf_check_image(buf);
> +	if (ret)
> +		return ERR_PTR(ret);
> +
> +	ret = load_elf_image_phdr(elf);
> +	if (ret) {
> +		elf_release_image(elf);
> +		return ERR_PTR(ret);
> +	}
> +
> +	return elf;
> +}
> +
> +void elf_release_image(struct elf_image *elf)
> +{
> +	elf_release_regions(elf);
> +
> +	free(elf->buf);

elf->buf hasn't been allocated by elf_load_image, so it shouldn't be
freed by elf_release_image.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  reply	other threads:[~2018-06-01  6:49 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-31 20:48 [PATCH 1/4] filetype: add ELF type Oleksij Rempel
2018-05-31 20:48 ` [PATCH 2/4] add basic ELF parser Oleksij Rempel
2018-06-01  6:49   ` Sascha Hauer [this message]
2018-06-01 18:12   ` Sam Ravnborg
2018-05-31 20:48 ` [PATCH 3/4] bootm: split split bootm_load_devicetree function Oleksij Rempel
2018-05-31 20:48 ` [PATCH 4/4] MIPS: bootm: add ELF handler Oleksij Rempel
2018-06-01  6:54   ` Sascha Hauer

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=20180601064929.aryh7oe2ktd3snya@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    --cc=o.rempel@pengutronix.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox