aboutsummaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@iki.fi>2009-04-07 09:57:59 +0300
committerRiku Voipio <riku.voipio@nokia.com>2009-06-16 16:56:28 +0300
commit9edc5d79666777c226554df5daf8bd5ffca8099d (patch)
tree8b4be6111c981c8adc55f50c9f8c64f6a675496f /linux-user
parentedf8e2af1453ce56c72b2f25a745e3734177a05d (diff)
linux-user: added x86 and x86_64 support for ELF coredump
Signed-off-by: Mika Westerberg <mika.westerberg@iki.fi> Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/elfload.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 8996c16126..d31cca71d1 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -134,6 +134,52 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
regs->rip = infop->entry;
}
+typedef target_ulong elf_greg_t;
+typedef uint32_t target_uid_t;
+typedef uint32_t target_gid_t;
+typedef int32_t target_pid_t;
+
+#define ELF_NREG 27
+typedef elf_greg_t elf_gregset_t[ELF_NREG];
+
+/*
+ * Note that ELF_NREG should be 29 as there should be place for
+ * TRAPNO and ERR "registers" as well but linux doesn't dump
+ * those.
+ *
+ * See linux kernel: arch/x86/include/asm/elf.h
+ */
+static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
+{
+ (*regs)[0] = env->regs[15];
+ (*regs)[1] = env->regs[14];
+ (*regs)[2] = env->regs[13];
+ (*regs)[3] = env->regs[12];
+ (*regs)[4] = env->regs[R_EBP];
+ (*regs)[5] = env->regs[R_EBX];
+ (*regs)[6] = env->regs[11];
+ (*regs)[7] = env->regs[10];
+ (*regs)[8] = env->regs[9];
+ (*regs)[9] = env->regs[8];
+ (*regs)[10] = env->regs[R_EAX];
+ (*regs)[11] = env->regs[R_ECX];
+ (*regs)[12] = env->regs[R_EDX];
+ (*regs)[13] = env->regs[R_ESI];
+ (*regs)[14] = env->regs[R_EDI];
+ (*regs)[15] = env->regs[R_EAX]; /* XXX */
+ (*regs)[16] = env->eip;
+ (*regs)[17] = env->segs[R_CS].selector & 0xffff;
+ (*regs)[18] = env->eflags;
+ (*regs)[19] = env->regs[R_ESP];
+ (*regs)[20] = env->segs[R_SS].selector & 0xffff;
+ (*regs)[21] = env->segs[R_FS].selector & 0xffff;
+ (*regs)[22] = env->segs[R_GS].selector & 0xffff;
+ (*regs)[23] = env->segs[R_DS].selector & 0xffff;
+ (*regs)[24] = env->segs[R_ES].selector & 0xffff;
+ (*regs)[25] = env->segs[R_FS].selector & 0xffff;
+ (*regs)[26] = env->segs[R_GS].selector & 0xffff;
+}
+
#else
#define ELF_START_MMAP 0x80000000
@@ -164,8 +210,45 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
A value of 0 tells we have no such handler. */
regs->edx = 0;
}
+
+typedef target_ulong elf_greg_t;
+typedef uint16_t target_uid_t;
+typedef uint16_t target_gid_t;
+typedef int32_t target_pid_t;
+
+#define ELF_NREG 17
+typedef elf_greg_t elf_gregset_t[ELF_NREG];
+
+/*
+ * Note that ELF_NREG should be 19 as there should be place for
+ * TRAPNO and ERR "registers" as well but linux doesn't dump
+ * those.
+ *
+ * See linux kernel: arch/x86/include/asm/elf.h
+ */
+static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
+{
+ (*regs)[0] = env->regs[R_EBX];
+ (*regs)[1] = env->regs[R_ECX];
+ (*regs)[2] = env->regs[R_EDX];
+ (*regs)[3] = env->regs[R_ESI];
+ (*regs)[4] = env->regs[R_EDI];
+ (*regs)[5] = env->regs[R_EBP];
+ (*regs)[6] = env->regs[R_EAX];
+ (*regs)[7] = env->segs[R_DS].selector & 0xffff;
+ (*regs)[8] = env->segs[R_ES].selector & 0xffff;
+ (*regs)[9] = env->segs[R_FS].selector & 0xffff;
+ (*regs)[10] = env->segs[R_GS].selector & 0xffff;
+ (*regs)[11] = env->regs[R_EAX]; /* XXX */
+ (*regs)[12] = env->eip;
+ (*regs)[13] = env->segs[R_CS].selector & 0xffff;
+ (*regs)[14] = env->eflags;
+ (*regs)[15] = env->regs[R_ESP];
+ (*regs)[16] = env->segs[R_SS].selector & 0xffff;
+}
#endif
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
#endif