diff options
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/elfload.c | 17 | ||||
-rw-r--r-- | linux-user/ppc/syscall.h | 4 |
2 files changed, 19 insertions, 2 deletions
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" |