[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 08/29] target-i386: Add API to write cpu status to c
From: |
Luiz Capitulino |
Subject: |
[Qemu-devel] [PATCH 08/29] target-i386: Add API to write cpu status to core file |
Date: |
Tue, 5 Jun 2012 14:24:47 -0300 |
From: Wen Congyang <address@hidden>
The core file has register's value. But it does not include all registers value.
Store the cpu status into QEMU note, and the user can get more information
from vmcore. If you change QEMUCPUState, please count up QEMUCPUSTATE_VERSION.
Signed-off-by: Wen Congyang <address@hidden>
Signed-off-by: Luiz Capitulino <address@hidden>
---
cpu-all.h | 18 ++++++
target-i386/arch_dump.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 167 insertions(+)
diff --git a/cpu-all.h b/cpu-all.h
index a71e887..a167bac 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -547,6 +547,10 @@ int cpu_write_elf64_note(write_core_dump_function f,
CPUArchState *env,
int cpuid, void *opaque);
int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
int cpuid, void *opaque);
+int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
+ void *opaque);
+int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
+ void *opaque);
#else
static inline int cpu_write_elf64_note(write_core_dump_function f,
CPUArchState *env, int cpuid,
@@ -561,6 +565,20 @@ static inline int
cpu_write_elf32_note(write_core_dump_function f,
{
return -1;
}
+
+static inline int cpu_write_elf64_qemunote(write_core_dump_function f,
+ CPUArchState *env,
+ void *opaque)
+{
+ return -1;
+}
+
+static inline int cpu_write_elf32_qemunote(write_core_dump_function f,
+ CPUArchState *env,
+ void *opaque)
+{
+ return -1;
+}
#endif
#endif /* CPU_ALL_H */
diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
index d55c2ce..ddbe20c 100644
--- a/target-i386/arch_dump.c
+++ b/target-i386/arch_dump.c
@@ -231,3 +231,152 @@ int cpu_write_elf32_note(write_core_dump_function f,
CPUArchState *env,
return 0;
}
+
+/*
+ * please count up QEMUCPUSTATE_VERSION if you have changed definition of
+ * QEMUCPUState, and modify the tools using this information accordingly.
+ */
+#define QEMUCPUSTATE_VERSION (1)
+
+struct QEMUCPUSegment {
+ uint32_t selector;
+ uint32_t limit;
+ uint32_t flags;
+ uint32_t pad;
+ uint64_t base;
+};
+
+typedef struct QEMUCPUSegment QEMUCPUSegment;
+
+struct QEMUCPUState {
+ uint32_t version;
+ uint32_t size;
+ uint64_t rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp;
+ uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
+ uint64_t rip, rflags;
+ QEMUCPUSegment cs, ds, es, fs, gs, ss;
+ QEMUCPUSegment ldt, tr, gdt, idt;
+ uint64_t cr[5];
+};
+
+typedef struct QEMUCPUState QEMUCPUState;
+
+static void copy_segment(QEMUCPUSegment *d, SegmentCache *s)
+{
+ d->pad = 0;
+ d->selector = s->selector;
+ d->limit = s->limit;
+ d->flags = s->flags;
+ d->base = s->base;
+}
+
+static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env)
+{
+ memset(s, 0, sizeof(QEMUCPUState));
+
+ s->version = QEMUCPUSTATE_VERSION;
+ s->size = sizeof(QEMUCPUState);
+
+ s->rax = env->regs[R_EAX];
+ s->rbx = env->regs[R_EBX];
+ s->rcx = env->regs[R_ECX];
+ s->rdx = env->regs[R_EDX];
+ s->rsi = env->regs[R_ESI];
+ s->rdi = env->regs[R_EDI];
+ s->rsp = env->regs[R_ESP];
+ s->rbp = env->regs[R_EBP];
+#ifdef TARGET_X86_64
+ s->r8 = env->regs[8];
+ s->r9 = env->regs[9];
+ s->r10 = env->regs[10];
+ s->r11 = env->regs[11];
+ s->r12 = env->regs[12];
+ s->r13 = env->regs[13];
+ s->r14 = env->regs[14];
+ s->r15 = env->regs[15];
+#endif
+ s->rip = env->eip;
+ s->rflags = env->eflags;
+
+ copy_segment(&s->cs, &env->segs[R_CS]);
+ copy_segment(&s->ds, &env->segs[R_DS]);
+ copy_segment(&s->es, &env->segs[R_ES]);
+ copy_segment(&s->fs, &env->segs[R_FS]);
+ copy_segment(&s->gs, &env->segs[R_GS]);
+ copy_segment(&s->ss, &env->segs[R_SS]);
+ copy_segment(&s->ldt, &env->ldt);
+ copy_segment(&s->tr, &env->tr);
+ copy_segment(&s->gdt, &env->gdt);
+ copy_segment(&s->idt, &env->idt);
+
+ s->cr[0] = env->cr[0];
+ s->cr[1] = env->cr[1];
+ s->cr[2] = env->cr[2];
+ s->cr[3] = env->cr[3];
+ s->cr[4] = env->cr[4];
+}
+
+static inline int cpu_write_qemu_note(write_core_dump_function f,
+ CPUArchState *env,
+ void *opaque,
+ int type)
+{
+ 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;
+}
+
+int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
+ void *opaque)
+{
+ return cpu_write_qemu_note(f, env, opaque, 1);
+}
+
+int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
+ void *opaque)
+{
+ return cpu_write_qemu_note(f, env, opaque, 0);
+}
--
1.7.10.2.565.gbd578b5
- [Qemu-devel] [PULL 00/29]: QMP queue, Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 01/29] Add API to create memory mapping list, Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 02/29] Add API to check whether a physical address is I/O address, Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 03/29] implement cpu_get_memory_mapping(), Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 05/29] Add API to get memory mapping, Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 04/29] Add API to check whether paging mode is enabled, Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 06/29] Add API to get memory mapping without do paging, Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 09/29] target-i386: add API to get dump info, Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 08/29] target-i386: Add API to write cpu status to core file,
Luiz Capitulino <=
- [Qemu-devel] [PATCH 07/29] target-i386: Add API to write elf notes to core file, Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 11/29] make gdb_id() generally avialable and rename it to cpu_index(), Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 10/29] target-i386: Add API to get note's size, Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 18/29] qemu-option: qemu_opts_validate(): use error_set(), Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 16/29] qemu-option: parse_option_size(): use error_set(), Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 20/29] qemu-option: introduce qemu_opt_set_err(), Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 25/29] net: purge the monitor object from all init functions, Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 22/29] qerror: introduce QERR_INVALID_OPTION_GROUP, Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 24/29] qemu-config: introduce qemu_find_opts_err(), Luiz Capitulino, 2012/06/05
- [Qemu-devel] [PATCH 29/29] Add 'query-events' command to QMP to query async events, Luiz Capitulino, 2012/06/05