aboutsummaryrefslogtreecommitdiff
path: root/linux-user/xtensa
diff options
context:
space:
mode:
Diffstat (limited to 'linux-user/xtensa')
-rw-r--r--linux-user/xtensa/cpu_loop.c22
-rw-r--r--linux-user/xtensa/elfload.c31
-rw-r--r--linux-user/xtensa/signal.c1
-rw-r--r--linux-user/xtensa/target_elf.h18
-rw-r--r--linux-user/xtensa/target_ptrace.h22
-rw-r--r--linux-user/xtensa/target_syscall.h35
6 files changed, 83 insertions, 46 deletions
diff --git a/linux-user/xtensa/cpu_loop.c b/linux-user/xtensa/cpu_loop.c
index c0fcf74..43a194f 100644
--- a/linux-user/xtensa/cpu_loop.c
+++ b/linux-user/xtensa/cpu_loop.c
@@ -238,12 +238,22 @@ void cpu_loop(CPUXtensaState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- int i;
- for (i = 0; i < 16; ++i) {
- env->regs[i] = regs->areg[i];
+ CPUArchState *env = cpu_env(cs);
+
+ env->sregs[WINDOW_BASE] = 0;
+ env->sregs[WINDOW_START] = 1;
+ env->regs[1] = info->start_stack;
+ env->pc = info->entry;
+
+ if (info_is_fdpic(info)) {
+ env->regs[4] = info->loadmap_addr;
+ env->regs[5] = info->interpreter_loadmap_addr;
+ if (info->interpreter_loadmap_addr) {
+ env->regs[6] = info->interpreter_pt_dynamic_addr;
+ } else {
+ env->regs[6] = info->pt_dynamic_addr;
+ }
}
- env->sregs[WINDOW_START] = regs->windowstart;
- env->pc = regs->pc;
}
diff --git a/linux-user/xtensa/elfload.c b/linux-user/xtensa/elfload.c
new file mode 100644
index 0000000..68aeed8
--- /dev/null
+++ b/linux-user/xtensa/elfload.c
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+#include "target_elf.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return XTENSA_DEFAULT_CPU_MODEL;
+}
+
+void elf_core_copy_regs(target_elf_gregset_t *r, const CPUXtensaState *env)
+{
+ r->pt.pc = tswap32(env->pc);
+ r->pt.ps = tswap32(env->sregs[PS] & ~PS_EXCM);
+ r->pt.lbeg = tswap32(env->sregs[LBEG]);
+ r->pt.lend = tswap32(env->sregs[LEND]);
+ r->pt.lcount = tswap32(env->sregs[LCOUNT]);
+ r->pt.sar = tswap32(env->sregs[SAR]);
+ r->pt.windowstart = tswap32(env->sregs[WINDOW_START]);
+ r->pt.windowbase = tswap32(env->sregs[WINDOW_BASE]);
+ r->pt.threadptr = tswap32(env->uregs[THREADPTR]);
+
+ xtensa_sync_phys_from_window((CPUXtensaState *)env);
+
+ for (unsigned i = 0; i < env->config->nareg; ++i) {
+ r->pt.a[i] = tswap32(env->phys_regs[i]);
+ }
+}
diff --git a/linux-user/xtensa/signal.c b/linux-user/xtensa/signal.c
index 6514b8d..ef8b0c3 100644
--- a/linux-user/xtensa/signal.c
+++ b/linux-user/xtensa/signal.c
@@ -241,7 +241,6 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
give_sigsegv:
force_sigsegv(sig);
- return;
}
static void restore_sigcontext(CPUXtensaState *env,
diff --git a/linux-user/xtensa/target_elf.h b/linux-user/xtensa/target_elf.h
index a9a3fab..1bf8f2a 100644
--- a/linux-user/xtensa/target_elf.h
+++ b/linux-user/xtensa/target_elf.h
@@ -8,9 +8,19 @@
#ifndef XTENSA_TARGET_ELF_H
#define XTENSA_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return XTENSA_DEFAULT_CPU_MODEL;
-}
+#include "target_ptrace.h"
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_MACHINE EM_XTENSA
+
+#define HAVE_ELF_CORE_DUMP 1
+
+/*
+ * See linux kernel: arch/xtensa/include/asm/elf.h, where elf_gregset_t
+ * is mapped to struct user_pt_regs via typedef and sizeof.
+ */
+typedef struct target_elf_gregset_t {
+ struct target_user_pt_regs pt;
+} target_elf_gregset_t;
#endif
diff --git a/linux-user/xtensa/target_ptrace.h b/linux-user/xtensa/target_ptrace.h
new file mode 100644
index 0000000..32443d0
--- /dev/null
+++ b/linux-user/xtensa/target_ptrace.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef XTENSA_TARGET_PTRACE_H
+#define XTENSA_TARGET_PTRACE_H
+
+/* See arch/xtensa/include/uapi/asm/ptrace.h. */
+struct target_user_pt_regs {
+ uint32_t pc;
+ uint32_t ps;
+ uint32_t lbeg;
+ uint32_t lend;
+ uint32_t lcount;
+ uint32_t sar;
+ uint32_t windowstart;
+ uint32_t windowbase;
+ uint32_t threadptr;
+ uint32_t syscall;
+ uint32_t reserved[6 + 48];
+ uint32_t a[64];
+};
+
+#endif /* XTENSA_TARGET_PTRACE_H */
diff --git a/linux-user/xtensa/target_syscall.h b/linux-user/xtensa/target_syscall.h
index afc86a1..5d4352a 100644
--- a/linux-user/xtensa/target_syscall.h
+++ b/linux-user/xtensa/target_syscall.h
@@ -8,41 +8,6 @@
#define MMAP_SHIFT TARGET_PAGE_BITS
-typedef uint32_t xtensa_reg_t;
-typedef struct {
-} xtregs_opt_t; /* TODO */
-
-struct target_pt_regs {
- xtensa_reg_t pc; /* 4 */
- xtensa_reg_t ps; /* 8 */
- xtensa_reg_t depc; /* 12 */
- xtensa_reg_t exccause; /* 16 */
- xtensa_reg_t excvaddr; /* 20 */
- xtensa_reg_t debugcause; /* 24 */
- xtensa_reg_t wmask; /* 28 */
- xtensa_reg_t lbeg; /* 32 */
- xtensa_reg_t lend; /* 36 */
- xtensa_reg_t lcount; /* 40 */
- xtensa_reg_t sar; /* 44 */
- xtensa_reg_t windowbase; /* 48 */
- xtensa_reg_t windowstart; /* 52 */
- xtensa_reg_t syscall; /* 56 */
- xtensa_reg_t icountlevel; /* 60 */
- xtensa_reg_t scompare1; /* 64 */
- xtensa_reg_t threadptr; /* 68 */
-
- /* Additional configurable registers that are used by the compiler. */
- xtregs_opt_t xtregs_opt;
-
- /* Make sure the areg field is 16 bytes aligned. */
- int align[0] __attribute__ ((aligned(16)));
-
- /* current register frame.
- * Note: The ESF for kernel exceptions ends after 16 registers!
- */
- xtensa_reg_t areg[16];
-};
-
#define TARGET_MCL_CURRENT 1
#define TARGET_MCL_FUTURE 2
#define TARGET_MCL_ONFAULT 4