From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42124) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WiJfZ-0007bJ-5q for qemu-devel@nongnu.org; Thu, 08 May 2014 04:27:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WiJfY-0005sB-B6 for qemu-devel@nongnu.org; Thu, 08 May 2014 04:27:09 -0400 Received: from mail-ve0-x24a.google.com ([2607:f8b0:400c:c01::24a]:45468) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WiJfY-0005r9-6J for qemu-devel@nongnu.org; Thu, 08 May 2014 04:27:08 -0400 Received: by mail-ve0-f202.google.com with SMTP id pa12so325664veb.5 for ; Thu, 08 May 2014 01:27:07 -0700 (PDT) From: Doug Kwan Date: Thu, 8 May 2014 01:26:41 -0700 Message-Id: <1399537603-6905-2-git-send-email-dougkwan@google.com> In-Reply-To: <1399537603-6905-1-git-send-email-dougkwan@google.com> References: <1399537603-6905-1-git-send-email-dougkwan@google.com> Subject: [Qemu-devel] [PATCH 1/3] linux-user: Handle ELFv2 PPC64 binaries in user mode. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org Cc: riku.voipio@iki.fi, Doug Kwan , agraf@suse.de Look at ELF header to determin ABI version on PPC64. This is required for executing the first instruction correctly. Signed-off-by: Doug Kwan --- include/elf.h | 5 +++++ linux-user/elfload.c | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/include/elf.h b/include/elf.h index 1599ab2..b39f5db 100644 --- a/include/elf.h +++ b/include/elf.h @@ -561,6 +561,11 @@ typedef struct { #define SHF_ALPHA_GPREL 0x10000000 +/* PowerPC specific definitions. */ + +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_PPC64_ABI 3 + /* PowerPC relocations defined by the ABIs */ #define R_PPC_NONE 0 #define R_PPC_ADDR32 1 /* 32bit absolute address */ diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 995f999..b96d64a 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -777,12 +777,18 @@ static uint32_t get_elf_hwcap(void) NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \ } while (0) +static inline uint32_t get_ppc64_abi(struct image_info *infop); + static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop) { _regs->gpr[1] = infop->start_stack; #if defined(TARGET_PPC64) && !defined(TARGET_ABI32) - _regs->gpr[2] = ldq_raw(infop->entry + 8) + infop->load_bias; - infop->entry = ldq_raw(infop->entry) + infop->load_bias; + if (get_ppc64_abi(infop) < 2) { + _regs->gpr[2] = ldq_raw(infop->entry + 8) + infop->load_bias; + infop->entry = ldq_raw(infop->entry) + infop->load_bias; + } else { + _regs->gpr[12] = infop->entry; /* r12 set to global entry address */ + } #endif _regs->nip = infop->entry; } @@ -1152,6 +1158,13 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i #include "elf.h" +#ifdef TARGET_PPC +static inline uint32_t get_ppc64_abi(struct image_info *infop) +{ + return infop->elf_flags & EF_PPC64_ABI; +} +#endif + struct exec { unsigned int a_info; /* Use macros N_MAGIC, etc for access */ -- 1.9.1.423.g4596e3a