From 9edc5d79666777c226554df5daf8bd5ffca8099d Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 7 Apr 2009 09:57:59 +0300 Subject: linux-user: added x86 and x86_64 support for ELF coredump Signed-off-by: Mika Westerberg Signed-off-by: Riku Voipio --- linux-user/elfload.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'linux-user') 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 -- cgit v1.2.1