Patchwork [RFC,v7,3/4] use elf_reset to reload elf image

login
register
mail settings
Submitter Olivia Yin
Date Nov. 29, 2012, 5:26 a.m.
Message ID <1354166782-5146-4-git-send-email-hong-hua.yin@freescale.com>
Download mbox | patch
Permalink /patch/202664/
State New
Headers show

Comments

Olivia Yin - Nov. 29, 2012, 5:26 a.m.
Signed-off-by: Olivia Yin <hong-hua.yin@freescale.com>
---
 elf.h        |   10 ++++++++++
 hw/elf_ops.h |   44 +++++++++++++++++++++++++++++++++++++++-----
 hw/loader.c  |   11 +++++++++++
 3 files changed, 60 insertions(+), 5 deletions(-)
Alexander Graf - Dec. 2, 2012, 11:37 a.m.
Missing patch description

On 29.11.2012, at 06:26, Olivia Yin wrote:

> Signed-off-by: Olivia Yin <hong-hua.yin@freescale.com>
> ---
> elf.h        |   10 ++++++++++
> hw/elf_ops.h |   44 +++++++++++++++++++++++++++++++++++++++-----
> hw/loader.c  |   11 +++++++++++
> 3 files changed, 60 insertions(+), 5 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..3ff8ffd 100644
> --- a/hw/elf_ops.h
> +++ b/hw/elf_ops.h
> @@ -187,12 +187,12 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
>     return -1;
> }
> 
> -static int glue(load_elf, SZ)(const char *name, int fd,
> +static int glue(elf_phy_loader, SZ)(const char *name, int fd,
>                               uint64_t (*translate_fn)(void *, uint64_t),
>                               void *translate_opaque,
>                               int must_swab, uint64_t *pentry,
>                               uint64_t *lowaddr, uint64_t *highaddr,
> -                              int elf_machine, int clear_lsb)
> +                              int elf_machine, int clear_lsb, int reset)
> {
>     struct elfhdr ehdr;
>     struct elf_phdr *phdr = NULL, *ph;
> @@ -202,6 +202,9 @@ static int glue(load_elf, SZ)(const char *name, int fd,
>     uint8_t *data = NULL;
>     char label[128];
> 
> +    if (reset) {
> +        fd = open(name, O_RDONLY | O_BINARY);
> +    }
>     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
>         goto fail;
>     if (must_swab) {
> @@ -232,7 +235,9 @@ static int glue(load_elf, SZ)(const char *name, int fd,
>     if (pentry)
>    	*pentry = (uint64_t)(elf_sword)ehdr.e_entry;
> 
> -    glue(load_symbols, SZ)(&ehdr, fd, must_swab, clear_lsb);
> +    if (!reset) {
> +        glue(load_symbols, SZ)(&ehdr, fd, must_swab, clear_lsb);
> +    }
> 
>     size = ehdr.e_phnum * sizeof(phdr[0]);
>     lseek(fd, ehdr.e_phoff, SEEK_SET);
> @@ -280,8 +285,12 @@ static int glue(load_elf, SZ)(const char *name, int fd,
>                 *pentry = ehdr.e_entry - ph->p_vaddr + ph->p_paddr;
>             }
> 
> -            snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
> -            rom_add_blob_fixed(label, data, mem_size, addr);
> +            if (!reset) {
> +                snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
> +                rom_add_blob_fixed(label, data, mem_size, addr);
> +            } else {
> +                cpu_physical_memory_write(addr, data, mem_size);
> +            }
> 
>             total_size += mem_size;
>             if (addr < low)
> @@ -304,3 +313,28 @@ static int glue(load_elf, SZ)(const char *name, int fd,
>     g_free(phdr);
>     return -1;
> }
> +
> +static void glue(elf_reset, SZ)(void *opaque)
> +{
> +    ImageElf *elf = opaque;
> +    int fd;
> +    
> +    fd = open(elf->name, O_RDONLY | O_BINARY);
> +    glue(elf_phy_loader, SZ)(elf->name, fd, elf->fn, elf->opaque, elf->swab, 
> +                             NULL, NULL, NULL, elf->machine, elf->lsb, 1);
> +}
> +
> +static int glue(load_elf, SZ)(const char *name, int fd,
> +                              uint64_t (*translate_fn)(void *, uint64_t),
> +                              void *translate_opaque,
> +                              int must_swab, uint64_t *pentry,
> +                              uint64_t *lowaddr, uint64_t *highaddr,
> +                              int elf_machine, int clear_lsb)
> +{
> +    int ret;
> +
> +    ret = glue(elf_phy_loader, SZ)(name, fd, (*translate_fn), translate_opaque,
> +                                   must_swab, pentry, lowaddr, highaddr,
> +                                   elf_machine, clear_lsb, 0);
> +    return ret;
> +}
> diff --git a/hw/loader.c b/hw/loader.c
> index 151ef20..10e5726 100644
> --- a/hw/loader.c
> +++ b/hw/loader.c
> @@ -342,13 +342,24 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
>         goto fail;
>     }
> 
> +    ImageElf *elf;
> +    elf = g_malloc0(sizeof(*elf));
> +    elf->name = g_strdup(filename);
> +    elf->fn = translate_fn;
> +    elf->opaque = translate_opaque;
> +    elf->swab = must_swab;
> +    elf->machine = elf_machine;
> +    elf->lsb = clear_lsb;

See my other mails on comments about these fields.


Alex

> +
>     lseek(fd, 0, SEEK_SET);
>     if (e_ident[EI_CLASS] == ELFCLASS64) {
>         ret = load_elf64(filename, fd, translate_fn, translate_opaque, must_swab,
>                          pentry, lowaddr, highaddr, elf_machine, clear_lsb);
> +        qemu_register_reset(elf_reset64, elf);
>     } else {
>         ret = load_elf32(filename, fd, translate_fn, translate_opaque, must_swab,
>                          pentry, lowaddr, highaddr, elf_machine, clear_lsb);
> +        qemu_register_reset(elf_reset32, elf);
>     }
> 
>     close(fd);
> -- 
> 1.7.1
> 
> 
>

Patch

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..3ff8ffd 100644
--- a/hw/elf_ops.h
+++ b/hw/elf_ops.h
@@ -187,12 +187,12 @@  static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
     return -1;
 }
 
-static int glue(load_elf, SZ)(const char *name, int fd,
+static int glue(elf_phy_loader, SZ)(const char *name, int fd,
                               uint64_t (*translate_fn)(void *, uint64_t),
                               void *translate_opaque,
                               int must_swab, uint64_t *pentry,
                               uint64_t *lowaddr, uint64_t *highaddr,
-                              int elf_machine, int clear_lsb)
+                              int elf_machine, int clear_lsb, int reset)
 {
     struct elfhdr ehdr;
     struct elf_phdr *phdr = NULL, *ph;
@@ -202,6 +202,9 @@  static int glue(load_elf, SZ)(const char *name, int fd,
     uint8_t *data = NULL;
     char label[128];
 
+    if (reset) {
+        fd = open(name, O_RDONLY | O_BINARY);
+    }
     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
         goto fail;
     if (must_swab) {
@@ -232,7 +235,9 @@  static int glue(load_elf, SZ)(const char *name, int fd,
     if (pentry)
    	*pentry = (uint64_t)(elf_sword)ehdr.e_entry;
 
-    glue(load_symbols, SZ)(&ehdr, fd, must_swab, clear_lsb);
+    if (!reset) {
+        glue(load_symbols, SZ)(&ehdr, fd, must_swab, clear_lsb);
+    }
 
     size = ehdr.e_phnum * sizeof(phdr[0]);
     lseek(fd, ehdr.e_phoff, SEEK_SET);
@@ -280,8 +285,12 @@  static int glue(load_elf, SZ)(const char *name, int fd,
                 *pentry = ehdr.e_entry - ph->p_vaddr + ph->p_paddr;
             }
 
-            snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
-            rom_add_blob_fixed(label, data, mem_size, addr);
+            if (!reset) {
+                snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
+                rom_add_blob_fixed(label, data, mem_size, addr);
+            } else {
+                cpu_physical_memory_write(addr, data, mem_size);
+            }
 
             total_size += mem_size;
             if (addr < low)
@@ -304,3 +313,28 @@  static int glue(load_elf, SZ)(const char *name, int fd,
     g_free(phdr);
     return -1;
 }
+
+static void glue(elf_reset, SZ)(void *opaque)
+{
+    ImageElf *elf = opaque;
+    int fd;
+    
+    fd = open(elf->name, O_RDONLY | O_BINARY);
+    glue(elf_phy_loader, SZ)(elf->name, fd, elf->fn, elf->opaque, elf->swab, 
+                             NULL, NULL, NULL, elf->machine, elf->lsb, 1);
+}
+
+static int glue(load_elf, SZ)(const char *name, int fd,
+                              uint64_t (*translate_fn)(void *, uint64_t),
+                              void *translate_opaque,
+                              int must_swab, uint64_t *pentry,
+                              uint64_t *lowaddr, uint64_t *highaddr,
+                              int elf_machine, int clear_lsb)
+{
+    int ret;
+
+    ret = glue(elf_phy_loader, SZ)(name, fd, (*translate_fn), translate_opaque,
+                                   must_swab, pentry, lowaddr, highaddr,
+                                   elf_machine, clear_lsb, 0);
+    return ret;
+}
diff --git a/hw/loader.c b/hw/loader.c
index 151ef20..10e5726 100644
--- a/hw/loader.c
+++ b/hw/loader.c
@@ -342,13 +342,24 @@  int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
         goto fail;
     }
 
+    ImageElf *elf;
+    elf = g_malloc0(sizeof(*elf));
+    elf->name = g_strdup(filename);
+    elf->fn = translate_fn;
+    elf->opaque = translate_opaque;
+    elf->swab = must_swab;
+    elf->machine = elf_machine;
+    elf->lsb = clear_lsb;
+
     lseek(fd, 0, SEEK_SET);
     if (e_ident[EI_CLASS] == ELFCLASS64) {
         ret = load_elf64(filename, fd, translate_fn, translate_opaque, must_swab,
                          pentry, lowaddr, highaddr, elf_machine, clear_lsb);
+        qemu_register_reset(elf_reset64, elf);
     } else {
         ret = load_elf32(filename, fd, translate_fn, translate_opaque, must_swab,
                          pentry, lowaddr, highaddr, elf_machine, clear_lsb);
+        qemu_register_reset(elf_reset32, elf);
     }
 
     close(fd);