[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCHv2 2/6] dump: extract out note helper
From: |
Rabin Vincent |
Subject: |
[Qemu-devel] [PATCHv2 2/6] dump: extract out note helper |
Date: |
Sun, 24 Mar 2013 18:27:17 +0100 |
Make a common helper function out of the x86 code to add ELF notes.
Signed-off-by: Rabin Vincent <address@hidden>
---
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