Make a common helper function out of the x86 code to add ELF notes. Signed-off-by: Rabin Vincent <ra...@rab.in> --- dump.c | 51 ++++++++++++ include/sysemu/dump.h | 4 + target-i386/arch_dump.c | 208 +++++++++++------------------------------------ 3 files changed, 104 insertions(+), 159 deletions(-)
diff --git a/dump.c b/dump.c index 8dd86b4..c5e009a 100644 --- a/dump.c +++ b/dump.c @@ -465,6 +465,57 @@ static hwaddr get_offset(hwaddr phys_addr, return -1; } +int dump_write_elf_note(int class, const char *name, uint32_t type, + void *desc, size_t descsz, + write_core_dump_function f, void *opaque) +{ + DumpState *s = opaque; + int endian = s->dump_info.d_endian; + Elf64_Nhdr *note64; + Elf32_Nhdr *note32; + void *note; + char *buf; + size_t note_size, name_size, note_head_size; + int ret; + + name_size = strlen(name) + 1; + + if (class == ELFCLASS32) { + note_head_size = sizeof(Elf32_Nhdr); + } else { + note_head_size = sizeof(Elf64_Nhdr); + } + note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 + + (descsz + 3) / 4) * 4; + note = g_malloc(note_size); + + memset(note, 0, note_size); + if (class == ELFCLASS32) { + note32 = note; + note32->n_namesz = cpu_convert_to_target32(name_size, endian); + note32->n_descsz = cpu_convert_to_target32(descsz, endian); + note32->n_type = cpu_convert_to_target32(type, endian); + } else { + note64 = note; + note64->n_namesz = cpu_convert_to_target64(name_size, endian); + note64->n_descsz = cpu_convert_to_target64(descsz, endian); + note64->n_type = cpu_convert_to_target64(type, endian); + } + buf = note; + buf += ((note_head_size + 3) / 4) * 4; + memcpy(buf, name, name_size); + buf += ((name_size + 3) / 4) * 4; + memcpy(buf, desc, descsz); + + ret = f(note, note_size, opaque); + g_free(note); + if (ret < 0) { + return -1; + } + + return 0; +} + static int write_elf_loads(DumpState *s) { hwaddr offset; diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h index e25b7cf..b07816a 100644 --- a/include/sysemu/dump.h +++ b/include/sysemu/dump.h @@ -32,4 +32,8 @@ int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env, int cpu_get_dump_info(ArchDumpInfo *info); ssize_t cpu_get_note_size(int class, int machine, int nr_cpus); +int dump_write_elf_note(int class, const char *name, uint32_t type, void *desc, + size_t descsz, write_core_dump_function f, + void *opaque); + #endif diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c index 2cd2f7f..eea7f7f 100644 --- a/target-i386/arch_dump.c +++ b/target-i386/arch_dump.c @@ -38,66 +38,43 @@ static int x86_64_write_elf64_note(write_core_dump_function f, CPUArchState *env, int id, void *opaque) { - 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 = sizeof(x86_64_elf_prstatus); - 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)); - - ret = f(note, note_size, opaque); - g_free(note); - if (ret < 0) { - return -1; - } - - return 0; + x86_64_elf_prstatus prstatus; + + memset(&prstatus, 0, sizeof(prstatus)); + + prstatus.pid = id; + prstatus.regs.r15 = env->regs[15]; + prstatus.regs.r14 = env->regs[14]; + prstatus.regs.r13 = env->regs[13]; + prstatus.regs.r12 = env->regs[12]; + prstatus.regs.r11 = env->regs[11]; + prstatus.regs.r10 = env->regs[10]; + prstatus.regs.r9 = env->regs[9]; + prstatus.regs.r8 = env->regs[8]; + prstatus.regs.rbp = env->regs[R_EBP]; + prstatus.regs.rsp = env->regs[R_ESP]; + prstatus.regs.rdi = env->regs[R_EDI]; + prstatus.regs.rsi = env->regs[R_ESI]; + prstatus.regs.rdx = env->regs[R_EDX]; + prstatus.regs.rcx = env->regs[R_ECX]; + prstatus.regs.rbx = env->regs[R_EBX]; + prstatus.regs.rax = env->regs[R_EAX]; + prstatus.regs.rip = env->eip; + prstatus.regs.eflags = env->eflags; + + prstatus.regs.orig_rax = 0; /* FIXME */ + prstatus.regs.cs = env->segs[R_CS].selector; + prstatus.regs.ss = env->segs[R_SS].selector; + prstatus.regs.fs_base = env->segs[R_FS].base; + prstatus.regs.gs_base = env->segs[R_GS].base; + prstatus.regs.ds = env->segs[R_DS].selector; + prstatus.regs.es = env->segs[R_ES].selector; + prstatus.regs.fs = env->segs[R_FS].selector; + prstatus.regs.gs = env->segs[R_GS].selector; + + return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS, + &prstatus, sizeof(prstatus), + f, opaque); } #endif @@ -148,35 +125,12 @@ static int x86_write_elf64_note(write_core_dump_function f, CPUArchState *env, int id, void *opaque) { x86_elf_prstatus prstatus; - Elf64_Nhdr *note; - char *buf; - int descsz, note_size, name_size = 5; - const char *name = "CORE"; - int ret; x86_fill_elf_prstatus(&prstatus, env, id); - descsz = sizeof(x86_elf_prstatus); - 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, &prstatus, sizeof(prstatus)); - - ret = f(note, note_size, opaque); - g_free(note); - if (ret < 0) { - return -1; - } - return 0; + return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS, + &prstatus, sizeof(prstatus), + f, opaque); } int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env, @@ -202,35 +156,12 @@ int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env, int cpuid, void *opaque) { x86_elf_prstatus prstatus; - Elf32_Nhdr *note; - char *buf; - int descsz, note_size, name_size = 5; - const char *name = "CORE"; - int ret; x86_fill_elf_prstatus(&prstatus, env, cpuid); - descsz = sizeof(x86_elf_prstatus); - 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, &prstatus, sizeof(prstatus)); - - ret = f(note, note_size, opaque); - g_free(note); - if (ret < 0) { - return -1; - } - return 0; + return dump_write_elf_note(ELFCLASS32, "CORE", NT_PRSTATUS, + &prstatus, sizeof(prstatus), + f, opaque); } /* @@ -317,69 +248,28 @@ static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env) s->cr[4] = env->cr[4]; } -static inline int cpu_write_qemu_note(write_core_dump_function f, +static inline int cpu_write_qemu_note(int class, write_core_dump_function f, CPUArchState *env, - void *opaque, - int type) + void *opaque) { QEMUCPUState state; - Elf64_Nhdr *note64; - Elf32_Nhdr *note32; - void *note; - char *buf; - int descsz, note_size, name_size = 5, note_head_size; - const char *name = "QEMU"; - int ret; qemu_get_cpustate(&state, env); - descsz = sizeof(state); - if (type == 0) { - note_head_size = sizeof(Elf32_Nhdr); - } else { - note_head_size = sizeof(Elf64_Nhdr); - } - note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 + - (descsz + 3) / 4) * 4; - note = g_malloc(note_size); - - memset(note, 0, note_size); - if (type == 0) { - note32 = note; - note32->n_namesz = cpu_to_le32(name_size); - note32->n_descsz = cpu_to_le32(descsz); - note32->n_type = 0; - } else { - note64 = note; - note64->n_namesz = cpu_to_le32(name_size); - note64->n_descsz = cpu_to_le32(descsz); - note64->n_type = 0; - } - buf = note; - buf += ((note_head_size + 3) / 4) * 4; - memcpy(buf, name, name_size); - buf += ((name_size + 3) / 4) * 4; - memcpy(buf, &state, sizeof(state)); - - ret = f(note, note_size, opaque); - g_free(note); - if (ret < 0) { - return -1; - } - - return 0; + return dump_write_elf_note(class, "QEMU", 0, &state, sizeof(state), + f, opaque); } int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env, void *opaque) { - return cpu_write_qemu_note(f, env, opaque, 1); + return cpu_write_qemu_note(ELFCLASS64, f, env, opaque); } int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env, void *opaque) { - return cpu_write_qemu_note(f, env, opaque, 0); + return cpu_write_qemu_note(ELFCLASS32, f, env, opaque); } int cpu_get_dump_info(ArchDumpInfo *info) -- 1.7.10.4