diff options
-rw-r--r-- | linux-user/elfload.c | 86 |
1 files changed, 73 insertions, 13 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c index d372300886..ad07c43e75 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -267,17 +267,15 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en #ifdef TARGET_ARM +#ifndef TARGET_AARCH64 +/* 32 bit ARM definitions */ + #define ELF_START_MMAP 0x80000000 #define elf_check_arch(x) ((x) == ELF_MACHINE) #define ELF_ARCH ELF_MACHINE - -#ifdef TARGET_AARCH64 -#define ELF_CLASS ELFCLASS64 -#else #define ELF_CLASS ELFCLASS32 -#endif static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) @@ -285,10 +283,6 @@ static inline void init_thread(struct target_pt_regs *regs, abi_long stack = infop->start_stack; memset(regs, 0, sizeof(*regs)); -#ifdef TARGET_AARCH64 - regs->pc = infop->entry & ~0x3ULL; - regs->sp = stack; -#else regs->ARM_cpsr = 0x10; if (infop->entry & 1) regs->ARM_cpsr |= CPSR_T; @@ -302,7 +296,6 @@ static inline void init_thread(struct target_pt_regs *regs, /* For uClinux PIC binaries. */ /* XXX: Linux does this only on ARM with no MMU (do we care ?) */ regs->ARM_r10 = infop->start_data; -#endif } #define ELF_NREG 18 @@ -360,7 +353,6 @@ enum ARM_HWCAP_ARM_EVTSTRM = 1 << 21, }; -#ifndef TARGET_AARCH64 /* The commpage only exists for 32 bit kernels */ #define TARGET_HAS_VALIDATE_GUEST_SPACE @@ -422,7 +414,6 @@ static int validate_guest_space(unsigned long guest_base, return 1; /* All good */ } -#endif #define ELF_HWCAP get_elf_hwcap() @@ -462,7 +453,76 @@ static uint32_t get_elf_hwcap(void) return hwcaps; } -#endif +#else +/* 64 bit ARM definitions */ +#define ELF_START_MMAP 0x80000000 + +#define elf_check_arch(x) ((x) == ELF_MACHINE) + +#define ELF_ARCH ELF_MACHINE +#define ELF_CLASS ELFCLASS64 +#define ELF_PLATFORM "aarch64" + +static inline void init_thread(struct target_pt_regs *regs, + struct image_info *infop) +{ + abi_long stack = infop->start_stack; + memset(regs, 0, sizeof(*regs)); + + regs->pc = infop->entry & ~0x3ULL; + regs->sp = stack; +} + +#define ELF_NREG 34 +typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG]; + +static void elf_core_copy_regs(target_elf_gregset_t *regs, + const CPUARMState *env) +{ + int i; + + for (i = 0; i < 32; i++) { + (*regs)[i] = tswapreg(env->xregs[i]); + } + (*regs)[32] = tswapreg(env->pc); + (*regs)[33] = tswapreg(pstate_read((CPUARMState *)env)); +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +enum { + ARM_HWCAP_A64_FP = 1 << 0, + ARM_HWCAP_A64_ASIMD = 1 << 1, + ARM_HWCAP_A64_EVTSTRM = 1 << 2, + ARM_HWCAP_A64_AES = 1 << 3, + ARM_HWCAP_A64_PMULL = 1 << 4, + ARM_HWCAP_A64_SHA1 = 1 << 5, + ARM_HWCAP_A64_SHA2 = 1 << 6, + ARM_HWCAP_A64_CRC32 = 1 << 7, +}; + +#define ELF_HWCAP get_elf_hwcap() + +static uint32_t get_elf_hwcap(void) +{ + ARMCPU *cpu = ARM_CPU(thread_cpu); + uint32_t hwcaps = 0; + + hwcaps |= ARM_HWCAP_A64_FP; + hwcaps |= ARM_HWCAP_A64_ASIMD; + + /* probe for the extra features */ +#define GET_FEATURE(feat, hwcap) \ + do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0) + GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP_A64_PMULL); +#undef GET_FEATURE + + return hwcaps; +} + +#endif /* not TARGET_AARCH64 */ +#endif /* TARGET_ARM */ #ifdef TARGET_UNICORE32 |