[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [Qemu-ppc] [RFC PATCH v4 3/3] use elf_reset to reload e
From: |
Blue Swirl |
Subject: |
Re: [Qemu-devel] [Qemu-ppc] [RFC PATCH v4 3/3] use elf_reset to reload elf image |
Date: |
Sat, 17 Nov 2012 16:09:59 +0000 |
On Wed, Nov 14, 2012 at 1:28 PM, Olivia Yin <address@hidden> wrote:
> Signed-off-by: Olivia Yin <address@hidden>
> ---
> elf.h | 10 ++++++
> hw/elf_ops.h | 101
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 111 insertions(+), 0 deletions(-)
>
> diff --git a/elf.h b/elf.h
> index a21ea53..335f1af 100644
> --- a/elf.h
> +++ b/elf.h
> @@ -1078,6 +1078,16 @@ typedef struct elf64_hdr {
> Elf64_Half e_shstrndx;
> } Elf64_Ehdr;
>
> +typedef struct ImageElf ImageElf;
> +struct ImageElf {
> + char *name;
> + uint64_t (*fn)(void *, uint64_t);
> + void *opaque;
> + int swab;
> + int machine;
> + int lsb;
> +};
> +
> /* These constants define the permissions on sections in the program
> header, p_flags. */
> #define PF_R 0x4
> diff --git a/hw/elf_ops.h b/hw/elf_ops.h
> index 531a425..89654bb 100644
> --- a/hw/elf_ops.h
> +++ b/hw/elf_ops.h
> @@ -187,6 +187,95 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr,
> int fd, int must_swab,
> return -1;
> }
>
> +static void glue(elf_reset, SZ)(void *opaque)
> +{
> + ImageElf *elf = opaque;
> + struct elfhdr ehdr;
> + struct elf_phdr *phdr = NULL, *ph;
> + int size, i, fd;
> + elf_word mem_size;
> + uint64_t addr;
> + uint8_t *data = NULL;
> +
> + fd = open(elf->name, O_RDONLY | O_BINARY);
> + if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
Please add braces and check your patches with checkpatch.pl.
> + goto fail;
> + if (elf->swab) {
> + glue(bswap_ehdr, SZ)(&ehdr);
> + }
> +
> + switch (elf->machine) {
> + case EM_PPC64:
> + if (EM_PPC64 != ehdr.e_machine)
> + if (EM_PPC != ehdr.e_machine)
> + goto fail;
> + break;
> + case EM_X86_64:
> + if (EM_X86_64 != ehdr.e_machine)
> + if (EM_386 != ehdr.e_machine)
> + goto fail;
> + break;
> + case EM_MICROBLAZE:
> + if (EM_MICROBLAZE != ehdr.e_machine)
> + if (EM_MICROBLAZE_OLD != ehdr.e_machine)
> + goto fail;
> + break;
> + default:
> + if (elf->machine != ehdr.e_machine)
> + goto fail;
> + }
> +
> + glue(load_symbols, SZ)(&ehdr, fd, elf->swab, elf->lsb);
> +
> + size = ehdr.e_phnum * sizeof(phdr[0]);
> + lseek(fd, ehdr.e_phoff, SEEK_SET);
> + phdr = g_malloc0(size);
> + if (!phdr)
> + goto fail;
> + if (read(fd, phdr, size) != size)
> + goto fail;
> + if (elf->swab) {
> + for(i = 0; i < ehdr.e_phnum; i++) {
> + ph = &phdr[i];
> + glue(bswap_phdr, SZ)(ph);
> + }
> + }
> +
> + for(i = 0; i < ehdr.e_phnum; i++) {
> + ph = &phdr[i];
> + if (ph->p_type == PT_LOAD) {
> + mem_size = ph->p_memsz;
> + /* XXX: avoid allocating */
> + data = g_malloc0(mem_size);
> + if (ph->p_filesz > 0) {
> + if (lseek(fd, ph->p_offset, SEEK_SET) < 0)
> + goto fail;
> + if (read(fd, data, ph->p_filesz) != ph->p_filesz)
> + goto fail;
> + }
> + /* address_offset is hack for kernel images that are
> + linked at the wrong physical address. */
> + if (elf->fn) {
> + addr = elf->fn(elf->opaque, ph->p_paddr);
> + } else {
> + addr = ph->p_paddr;
> + }
> +
> + cpu_physical_memory_write(addr, data, mem_size);
> +
> + g_free(data);
> + data = NULL;
> + }
> + }
> + close(fd);
> + g_free(phdr);
> + phdr = NULL;
> + fail:
> + close(fd);
> + g_free(data);
> + g_free(phdr);
> +}
> +
> static int glue(load_elf, SZ)(const char *name, int fd,
> uint64_t (*translate_fn)(void *, uint64_t),
> void *translate_opaque,
> @@ -293,6 +382,18 @@ static int glue(load_elf, SZ)(const char *name, int fd,
> data = NULL;
> }
> }
> +
> + ImageElf *elf;
> + elf = g_malloc0(sizeof(*elf));
> + elf->name = g_strdup(name);
> + elf->fn = translate_fn;
> + elf->opaque = translate_opaque;
> + elf->swab = must_swab;
> + elf->machine = elf_machine;
> + elf->lsb = clear_lsb;
> +
> + qemu_register_reset(glue(elf_reset, SZ), elf);
> +
> g_free(phdr);
> if (lowaddr)
> *lowaddr = (uint64_t)(elf_sword)low;
> --
> 1.7.1
>
>
>
Re: [Qemu-devel] [RFC PATCH v4 1/3] use image_file_reset to reload initrd image, Stuart Yoder, 2012/11/15
Re: [Qemu-devel] [RFC PATCH v4 0/3] reload kernel/initrd/elf images when reset, Yin Olivia-R63875, 2012/11/15