On Wed, Nov 14, 2012 at 1:28 PM, Olivia Yin <hong-hua....@freescale.com> wrote: > Signed-off-by: Olivia Yin <hong-hua....@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))
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 > > >