qemu-devel.nongnu.org archive mirror
 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 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).