From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56641) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YUvbM-000525-Ko for qemu-devel@nongnu.org; Mon, 09 Mar 2015 07:12:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YUvbG-0000CC-N5 for qemu-devel@nongnu.org; Mon, 09 Mar 2015 07:12:00 -0400 Received: from e06smtp10.uk.ibm.com ([195.75.94.106]:47108) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YUvbG-0000Br-Dd for qemu-devel@nongnu.org; Mon, 09 Mar 2015 07:11:54 -0400 Received: from /spool/local by e06smtp10.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 9 Mar 2015 11:11:52 -0000 Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by d06dlp03.portsmouth.uk.ibm.com (Postfix) with ESMTP id DE6351B0805F for ; Mon, 9 Mar 2015 11:12:09 +0000 (GMT) Received: from d06av10.portsmouth.uk.ibm.com (d06av10.portsmouth.uk.ibm.com [9.149.37.251]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t29BBosV10813730 for ; Mon, 9 Mar 2015 11:11:50 GMT Received: from d06av10.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av10.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t29BBnl6003731 for ; Mon, 9 Mar 2015 05:11:49 -0600 Message-ID: <54FD7FF5.5020509@de.ibm.com> Date: Mon, 09 Mar 2015 12:11:49 +0100 From: Christian Borntraeger MIME-Version: 1.0 References: <1425895973-15239-1-git-send-email-thuth@linux.vnet.ibm.com> <1425895973-15239-2-git-send-email-thuth@linux.vnet.ibm.com> In-Reply-To: <1425895973-15239-2-git-send-email-thuth@linux.vnet.ibm.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v2 1/2] elf-loader: Provide the possibility to relocate s390 ELF files List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Thomas Huth , qemu-devel@nongnu.org Cc: cornelia.huck@de.ibm.com, agraf@suse.de 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 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; > } >