From: Olivia Yin <hong-hua.yin@freescale.com>
To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org
Cc: Olivia Yin <hong-hua.yin@freescale.com>
Subject: [Qemu-devel] [RFC PATCH v4 3/3] use elf_reset to reload elf image
Date: Wed, 14 Nov 2012 21:28:52 +0800 [thread overview]
Message-ID: <1352899732-1197-4-git-send-email-hong-hua.yin@freescale.com> (raw)
In-Reply-To: <1352899732-1197-3-git-send-email-hong-hua.yin@freescale.com>
Signed-off-by: Olivia Yin <hong-hua.yin@freescale.com>
---
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))
+ 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
next prev parent reply other threads:[~2012-11-14 14:14 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-14 13:28 [Qemu-devel] [RFC PATCH v4 0/3] reload kernel/initrd/elf images when reset Olivia Yin
2012-11-14 13:28 ` [Qemu-devel] [RFC PATCH v4 1/3] use image_file_reset to reload initrd image Olivia Yin
2012-11-14 13:28 ` [Qemu-devel] [RFC PATCH v4 2/3] use uimage_reset to reload uimage Olivia Yin
2012-11-14 13:28 ` Olivia Yin [this message]
2012-11-17 16:09 ` [Qemu-devel] [Qemu-ppc] [RFC PATCH v4 3/3] use elf_reset to reload elf image Blue Swirl
2012-11-15 20:46 ` [Qemu-devel] [RFC PATCH v4 2/3] use uimage_reset to reload uimage Stuart Yoder
2012-11-16 6:11 ` Yin Olivia-R63875
2012-11-19 11:26 ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
2012-11-15 19:52 ` [Qemu-devel] [RFC PATCH v4 1/3] use image_file_reset to reload initrd image Stuart Yoder
2012-11-16 5:50 ` Yin Olivia-R63875
2012-11-15 5:12 ` [Qemu-devel] [RFC PATCH v4 0/3] reload kernel/initrd/elf images when reset Yin Olivia-R63875
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=1352899732-1197-4-git-send-email-hong-hua.yin@freescale.com \
--to=hong-hua.yin@freescale.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
/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;
as well as URLs for NNTP newsgroup(s).