All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Borntraeger <borntraeger@de.ibm.com>
To: Thomas Huth <thuth@linux.vnet.ibm.com>, qemu-devel@nongnu.org
Cc: cornelia.huck@de.ibm.com, agraf@suse.de
Subject: Re: [Qemu-devel] [PATCH v2 1/2] elf-loader: Provide the possibility to relocate s390 ELF files
Date: Mon, 09 Mar 2015 12:11:49 +0100	[thread overview]
Message-ID: <54FD7FF5.5020509@de.ibm.com> (raw)
In-Reply-To: <1425895973-15239-2-git-send-email-thuth@linux.vnet.ibm.com>

Am 09.03.2015 um 11:12 schrieb Thomas Huth:
> On s390, we would like to load our "BIOS" s390-ccw.img to the end of the
> RAM. Therefor we need the possibility to relocate the ELF file so that
> it can also run from different addresses. This patch adds the necessary
> code to the QEMU ELF loader function.
> 
> Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>

I think this was Acked by Alex?

> ---
>  hw/core/loader.c     |    2 +
>  include/elf.h        |    2 +
>  include/hw/elf_ops.h |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 82 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/core/loader.c b/hw/core/loader.c
> index e45dc0b..76d8aca 100644
> --- a/hw/core/loader.c
> +++ b/hw/core/loader.c
> @@ -297,6 +297,7 @@ static void *load_at(int fd, int offset, int size)
>  #undef elf_phdr
>  #undef elf_shdr
>  #undef elf_sym
> +#undef elf_rela
>  #undef elf_note
>  #undef elf_word
>  #undef elf_sword
> @@ -307,6 +308,7 @@ static void *load_at(int fd, int offset, int size)
>  #define elf_note	elf64_note
>  #define elf_shdr	elf64_shdr
>  #define elf_sym		elf64_sym
> +#define elf_rela        elf64_rela
>  #define elf_word        uint64_t
>  #define elf_sword        int64_t
>  #define bswapSZs	bswap64s
> diff --git a/include/elf.h b/include/elf.h
> index a516584..3e75f05 100644
> --- a/include/elf.h
> +++ b/include/elf.h
> @@ -1508,6 +1508,7 @@ struct elf32_fdpic_loadmap {
>  #define elf_shdr	elf32_shdr
>  #define elf_sym		elf32_sym
>  #define elf_addr_t	Elf32_Off
> +#define elf_rela  elf32_rela
> 
>  #ifdef ELF_USES_RELOCA
>  # define ELF_RELOC      Elf32_Rela
> @@ -1523,6 +1524,7 @@ struct elf32_fdpic_loadmap {
>  #define elf_shdr	elf64_shdr
>  #define elf_sym		elf64_sym
>  #define elf_addr_t	Elf64_Off
> +#define elf_rela  elf64_rela
> 
>  #ifdef ELF_USES_RELOCA
>  # define ELF_RELOC      Elf64_Rela
> diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
> index a517753..16a627b 100644
> --- a/include/hw/elf_ops.h
> +++ b/include/hw/elf_ops.h
> @@ -49,6 +49,13 @@ static void glue(bswap_sym, SZ)(struct elf_sym *sym)
>      bswap16s(&sym->st_shndx);
>  }
> 
> +static void glue(bswap_rela, SZ)(struct elf_rela *rela)
> +{
> +    bswapSZs(&rela->r_offset);
> +    bswapSZs(&rela->r_info);
> +    bswapSZs((elf_word *)&rela->r_addend);
> +}
> +
>  static struct elf_shdr *glue(find_section, SZ)(struct elf_shdr *shdr_table,
>                                                 int n, int type)
>  {
> @@ -182,6 +189,75 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
>      return -1;
>  }
> 
> +static int glue(elf_reloc, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
> +                               uint64_t (*translate_fn)(void *, uint64_t),
> +                               void *translate_opaque, uint8_t *data,
> +                               struct elf_phdr *ph, int elf_machine)
> +{
> +    struct elf_shdr *reltab, *shdr_table = NULL;
> +    struct elf_rela *rels = NULL;
> +    int nrels, i, ret = -1;
> +    elf_word wordval;
> +    void *addr;
> +
> +    shdr_table = load_at(fd, ehdr->e_shoff,
> +                         sizeof(struct elf_shdr) * ehdr->e_shnum);
> +    if (!shdr_table) {
> +        return -1;
> +    }
> +    if (must_swab) {
> +        for (i = 0; i < ehdr->e_shnum; i++) {
> +            glue(bswap_shdr, SZ)(&shdr_table[i]);
> +        }
> +    }
> +
> +    reltab = glue(find_section, SZ)(shdr_table, ehdr->e_shnum, SHT_RELA);
> +    if (!reltab) {
> +        goto fail;
> +    }
> +    rels = load_at(fd, reltab->sh_offset, reltab->sh_size);
> +    if (!rels) {
> +        goto fail;
> +    }
> +    nrels = reltab->sh_size / sizeof(struct elf_rela);
> +
> +    for (i = 0; i < nrels; i++) {
> +        if (must_swab) {
> +            glue(bswap_rela, SZ)(&rels[i]);
> +        }
> +        if (rels[i].r_offset < ph->p_vaddr ||
> +            rels[i].r_offset >= ph->p_vaddr + ph->p_filesz) {
> +            continue;
> +        }
> +        addr = &data[rels[i].r_offset - ph->p_vaddr];
> +        switch (elf_machine) {
> +        case EM_S390:
> +            switch (rels[i].r_info) {
> +            case R_390_RELATIVE:
> +                wordval = *(elf_word *)addr;
> +                if (must_swab) {
> +                    bswapSZs(&wordval);
> +                }
> +                wordval = translate_fn(translate_opaque, wordval);
> +                if (must_swab) {
> +                    bswapSZs(&wordval);
> +                }
> +                *(elf_word *)addr = wordval;
> +                break;
> +            default:
> +                fprintf(stderr, "Unsupported relocation type %i!\n",
> +                        (int)rels[i].r_info);
> +            }
> +        }
> +    }
> +
> +    ret = 0;
> +fail:
> +    g_free(rels);
> +    g_free(shdr_table);
> +    return ret;
> +}
> +
>  static int glue(load_elf, SZ)(const char *name, int fd,
>                                uint64_t (*translate_fn)(void *, uint64_t),
>                                void *translate_opaque,
> @@ -271,6 +347,8 @@ static int glue(load_elf, SZ)(const char *name, int fd,
>                 linked at the wrong physical address.  */
>              if (translate_fn) {
>                  addr = translate_fn(translate_opaque, ph->p_paddr);
> +                glue(elf_reloc, SZ)(&ehdr, fd, must_swab,  translate_fn,
> +                                    translate_opaque, data, ph, elf_machine);
>              } else {
>                  addr = ph->p_paddr;
>              }
> 

  reply	other threads:[~2015-03-09 11:12 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-09 10:12 [Qemu-devel] [PATCH v2 0/2] s390x: Make the s390-ccw BIOS relocatable Thomas Huth
2015-03-09 10:12 ` [Qemu-devel] [PATCH v2 1/2] elf-loader: Provide the possibility to relocate s390 ELF files Thomas Huth
2015-03-09 11:11   ` Christian Borntraeger [this message]
2015-03-09 13:30     ` Thomas Huth
2015-03-09 13:42       ` Alexander Graf
2015-03-09 10:12 ` [Qemu-devel] [PATCH v2 2/2] s390/bios: Make the s390-ccw.img relocatable Thomas Huth
2015-03-09 15:21 ` [Qemu-devel] [PATCH v2 0/2] s390x: Make the s390-ccw BIOS relocatable Christian Borntraeger

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=54FD7FF5.5020509@de.ibm.com \
    --to=borntraeger@de.ibm.com \
    --cc=agraf@suse.de \
    --cc=cornelia.huck@de.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=thuth@linux.vnet.ibm.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.