The core file contains register's value. These APIs write registers to core file, and them will be called in the following patch.
Signed-off-by: Wen Congyang <we...@cn.fujitsu.com> --- cpu-all.h | 6 + target-i386/arch-dump.c | 243 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+), 0 deletions(-) diff --git a/cpu-all.h b/cpu-all.h index bc32c11..ffb539c 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -578,8 +578,14 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr, #if defined(TARGET_I386) void cpu_get_memory_mapping(MemoryMappingList *list, CPUState *env); +int cpu_write_elf64_note(int fd, CPUState *env, int cpuid, + target_phys_addr_t *offset); +int cpu_write_elf32_note(int fd, CPUState *env, int cpuid, + target_phys_addr_t *offset); #else #define cpu_get_memory_mapping(list, env) +#define cpu_write_elf64_note(fd, env, cpuid, offset) ({ -1; }) +#define cpu_write_elf32_note(fd, env, cpuid, offset) ({ -1; }) #endif #endif /* CPU_ALL_H */ diff --git a/target-i386/arch-dump.c b/target-i386/arch-dump.c index 2e921c7..4c0ff77 100644 --- a/target-i386/arch-dump.c +++ b/target-i386/arch-dump.c @@ -11,8 +11,11 @@ * */ +#include <elf.h> + #include "cpu.h" #include "cpu-all.h" +#include "monitor.h" /* PAE Paging or IA-32e Paging */ static void walk_pte(MemoryMappingList *list, target_phys_addr_t pte_start_addr, @@ -252,3 +255,243 @@ void cpu_get_memory_mapping(MemoryMappingList *list, CPUState *env) walk_pde2(list, pde_addr, env->a20_mask, pse); } } + +#ifdef TARGET_X86_64 +typedef struct { + target_ulong r15, r14, r13, r12, rbp, rbx, r11, r10; + target_ulong r9, r8, rax, rcx, rdx, rsi, rdi, orig_rax; + target_ulong rip, cs, eflags; + target_ulong rsp, ss; + target_ulong fs_base, gs_base; + target_ulong ds, es, fs, gs; +} x86_64_user_regs_struct; + +static int x86_64_write_elf64_note(int fd, CPUState *env, int id, + target_phys_addr_t *offset) +{ + x86_64_user_regs_struct regs; + Elf64_Nhdr *note; + char *buf; + int descsz, note_size, name_size = 5; + const char *name = "CORE"; + int ret; + + regs.r15 = env->regs[15]; + regs.r14 = env->regs[14]; + regs.r13 = env->regs[13]; + regs.r12 = env->regs[12]; + regs.r11 = env->regs[11]; + regs.r10 = env->regs[10]; + regs.r9 = env->regs[9]; + regs.r8 = env->regs[8]; + regs.rbp = env->regs[R_EBP]; + regs.rsp = env->regs[R_ESP]; + regs.rdi = env->regs[R_EDI]; + regs.rsi = env->regs[R_ESI]; + regs.rdx = env->regs[R_EDX]; + regs.rcx = env->regs[R_ECX]; + regs.rbx = env->regs[R_EBX]; + regs.rax = env->regs[R_EAX]; + regs.rip = env->eip; + regs.eflags = env->eflags; + + regs.orig_rax = 0; /* FIXME */ + regs.cs = env->segs[R_CS].selector; + regs.ss = env->segs[R_SS].selector; + regs.fs_base = env->segs[R_FS].base; + regs.gs_base = env->segs[R_GS].base; + regs.ds = env->segs[R_DS].selector; + regs.es = env->segs[R_ES].selector; + regs.fs = env->segs[R_FS].selector; + regs.gs = env->segs[R_GS].selector; + + descsz = 336; /* sizeof(prstatus_t) is 336 on x86_64 box */ + note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 + + (descsz + 3) / 4) * 4; + note = g_malloc(note_size); + + memset(note, 0, note_size); + note->n_namesz = cpu_to_le32(name_size); + note->n_descsz = cpu_to_le32(descsz); + note->n_type = cpu_to_le32(NT_PRSTATUS); + buf = (char *)note; + buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4; + memcpy(buf, name, name_size); + buf += ((name_size + 3) / 4) * 4; + memcpy(buf + 32, &id, 4); /* pr_pid */ + buf += descsz - sizeof(x86_64_user_regs_struct)-sizeof(target_ulong); + memcpy(buf, ®s, sizeof(x86_64_user_regs_struct)); + + lseek(fd, *offset, SEEK_SET); + ret = write(fd, note, note_size); + g_free(note); + if (ret < 0) { + return -1; + } + + *offset += note_size; + + return 0; +} +#endif + +typedef struct { + uint32_t ebx, ecx, edx, esi, edi, ebp, eax; + unsigned short ds, __ds, es, __es; + unsigned short fs, __fs, gs, __gs; + uint32_t orig_eax, eip; + unsigned short cs, __cs; + uint32_t eflags, esp; + unsigned short ss, __ss; +} x86_user_regs_struct; + +static int x86_write_elf64_note(int fd, CPUState *env, int id, + target_phys_addr_t *offset) +{ + x86_user_regs_struct regs; + Elf64_Nhdr *note; + char *buf; + int descsz, note_size, name_size = 5; + const char *name = "CORE"; + int ret; + + regs.ebp = env->regs[R_EBP] & 0xffffffff; + regs.esp = env->regs[R_ESP] & 0xffffffff; + regs.edi = env->regs[R_EDI] & 0xffffffff; + regs.esi = env->regs[R_ESI] & 0xffffffff; + regs.edx = env->regs[R_EDX] & 0xffffffff; + regs.ecx = env->regs[R_ECX] & 0xffffffff; + regs.ebx = env->regs[R_EBX] & 0xffffffff; + regs.eax = env->regs[R_EAX] & 0xffffffff; + regs.eip = env->eip & 0xffffffff; + regs.eflags = env->eflags & 0xffffffff; + + regs.cs = env->segs[R_CS].selector; + regs.__cs = 0; + regs.ss = env->segs[R_SS].selector; + regs.__ss = 0; + regs.ds = env->segs[R_DS].selector; + regs.__ds = 0; + regs.es = env->segs[R_ES].selector; + regs.__es = 0; + regs.fs = env->segs[R_FS].selector; + regs.__fs = 0; + regs.gs = env->segs[R_GS].selector; + regs.__gs = 0; + + descsz = 144; /* sizeof(prstatus_t) is 144 on x86 box */ + note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 + + (descsz + 3) / 4) * 4; + note = g_malloc(note_size); + + memset(note, 0, note_size); + note->n_namesz = cpu_to_le32(name_size); + note->n_descsz = cpu_to_le32(descsz); + note->n_type = cpu_to_le32(NT_PRSTATUS); + buf = (char *)note; + buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4; + memcpy(buf, name, name_size); + buf += ((name_size + 3) / 4) * 4; + memcpy(buf + 24, &id, 4); /* pr_pid */ + buf += descsz - sizeof(x86_user_regs_struct)-4; + memcpy(buf, ®s, sizeof(x86_user_regs_struct)); + + lseek(fd, *offset, SEEK_SET); + ret = write(fd, note, note_size); + g_free(note); + if (ret < 0) { + return -1; + } + + *offset += note_size; + + return 0; +} + +static int x86_write_elf32_note(int fd, CPUState *env, int id, + target_phys_addr_t *offset) +{ + x86_user_regs_struct regs; + Elf32_Nhdr *note; + char *buf; + int descsz, note_size, name_size = 5; + const char *name = "CORE"; + int ret; + + regs.ebp = env->regs[R_EBP] & 0xffffffff; + regs.esp = env->regs[R_ESP] & 0xffffffff; + regs.edi = env->regs[R_EDI] & 0xffffffff; + regs.esi = env->regs[R_ESI] & 0xffffffff; + regs.edx = env->regs[R_EDX] & 0xffffffff; + regs.ecx = env->regs[R_ECX] & 0xffffffff; + regs.ebx = env->regs[R_EBX] & 0xffffffff; + regs.eax = env->regs[R_EAX] & 0xffffffff; + regs.eip = env->eip & 0xffffffff; + regs.eflags = env->eflags & 0xffffffff; + + regs.cs = env->segs[R_CS].selector; + regs.__cs = 0; + regs.ss = env->segs[R_SS].selector; + regs.__ss = 0; + regs.ds = env->segs[R_DS].selector; + regs.__ds = 0; + regs.es = env->segs[R_ES].selector; + regs.__es = 0; + regs.fs = env->segs[R_FS].selector; + regs.__fs = 0; + regs.gs = env->segs[R_GS].selector; + regs.__gs = 0; + + descsz = 144; /* sizeof(prstatus_t) is 144 on x86 box */ + note_size = ((sizeof(Elf32_Nhdr) + 3) / 4 + (name_size + 3) / 4 + + (descsz + 3) / 4) * 4; + note = g_malloc(note_size); + + memset(note, 0, note_size); + note->n_namesz = cpu_to_le32(name_size); + note->n_descsz = cpu_to_le32(descsz); + note->n_type = cpu_to_le32(NT_PRSTATUS); + buf = (char *)note; + buf += ((sizeof(Elf32_Nhdr) + 3) / 4) * 4; + memcpy(buf, name, name_size); + buf += ((name_size + 3) / 4) * 4; + memcpy(buf + 24, &id, 4); /* pr_pid */ + buf += descsz - sizeof(x86_user_regs_struct)-4; + memcpy(buf, ®s, sizeof(x86_user_regs_struct)); + + lseek(fd, *offset, SEEK_SET); + ret = write(fd, note, note_size); + g_free(note); + if (ret < 0) { + return -1; + } + + *offset += note_size; + + return 0; +} + +int cpu_write_elf64_note(int fd, CPUState *env, int cpuid, + target_phys_addr_t *offset) +{ + int ret; +#ifdef TARGET_X86_64 + bool lma = !!(first_cpu->hflags & HF_LMA_MASK); + + if (lma) { + ret = x86_64_write_elf64_note(fd, env, cpuid, offset); + } else { +#endif + ret = x86_write_elf64_note(fd, env, cpuid, offset); +#ifdef TARGET_X86_64 + } +#endif + + return ret; +} + +int cpu_write_elf32_note(int fd, CPUState *env, int cpuid, + target_phys_addr_t *offset) +{ + return x86_write_elf32_note(fd, env, cpuid, offset); +} -- 1.7.1