From d90b94cd78af672cdfd52dc3789ab249534c2f40 Mon Sep 17 00:00:00 2001 From: Doug Kwan Date: Thu, 29 May 2014 09:12:19 -0500 Subject: target-ppc: Support little-endian PPC64 in user mode. Look at ELF header to determine ABI version on PPC64. This is required for executing the first instruction correctly. Also print correct machine name in uname() system call. Signed-off-by: Doug Kwan Signed-off-by: Tom Musta Signed-off-by: Alexander Graf --- linux-user/elfload.c | 17 +++++++++++++++-- linux-user/ppc/syscall.h | 4 ++++ 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'linux-user') diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 68b9793649..d08fc80051 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -784,12 +784,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; } @@ -1159,6 +1165,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 */ diff --git a/linux-user/ppc/syscall.h b/linux-user/ppc/syscall.h index 6514c637a5..db92bbee17 100644 --- a/linux-user/ppc/syscall.h +++ b/linux-user/ppc/syscall.h @@ -58,8 +58,12 @@ struct target_revectored_struct { */ #if defined(TARGET_PPC64) && !defined(TARGET_ABI32) +#ifdef TARGET_WORDS_BIGENDIAN #define UNAME_MACHINE "ppc64" #else +#define UNAME_MACHINE "ppc64le" +#endif +#else #define UNAME_MACHINE "ppc" #endif #define UNAME_MINIMUM_RELEASE "2.6.32" -- cgit v1.2.3