aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-user/aarch64/syscall.h9
-rw-r--r--linux-user/elfload.c15
-rw-r--r--linux-user/main.c16
3 files changed, 38 insertions, 2 deletions
diff --git a/linux-user/aarch64/syscall.h b/linux-user/aarch64/syscall.h
new file mode 100644
index 0000000000..aef419efeb
--- /dev/null
+++ b/linux-user/aarch64/syscall.h
@@ -0,0 +1,9 @@
+struct target_pt_regs {
+ uint64_t regs[31];
+ uint64_t sp;
+ uint64_t pc;
+ uint64_t pstate;
+};
+
+#define UNAME_MACHINE "aarch64"
+#define UNAME_MINIMUM_RELEASE "3.8.0"
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 7ce2eab1bb..e2f40b9860 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -269,16 +269,26 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ( (x) == EM_ARM )
+#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
-#define ELF_ARCH EM_ARM
+#endif
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));
+
+#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;
@@ -292,6 +302,7 @@ 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
diff --git a/linux-user/main.c b/linux-user/main.c
index d530f01f87..e213085805 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3964,6 +3964,22 @@ int main(int argc, char **argv, char **envp)
cpu_x86_load_seg(env, R_FS, 0);
cpu_x86_load_seg(env, R_GS, 0);
#endif
+#elif defined(TARGET_AARCH64)
+ {
+ int i;
+
+ if (!(arm_feature(env, ARM_FEATURE_AARCH64))) {
+ fprintf(stderr,
+ "The selected ARM CPU does not support 64 bit mode\n");
+ exit(1);
+ }
+
+ for (i = 0; i < 31; i++) {
+ env->xregs[i] = regs->regs[i];
+ }
+ env->pc = regs->pc;
+ env->xregs[31] = regs->sp;
+ }
#elif defined(TARGET_ARM)
{
int i;