>From 3d737a7ea51261eb3d39febbcbf93cce02b458c1 Mon Sep 17 00:00:00 2001 From: Hu Tao Date: Wed, 20 Oct 2010 15:40:07 +0800 Subject: [PATCH 4/4] Add a command cpu to show cpu registers --- defs.h | 18 +++++++++++++++++- global_data.c | 1 + help.c | 14 +------------- kernel.c | 10 ++++++++++ kvmdump.c | 2 +- qemu-load.c | 3 ++- qemu-load.h | 12 ------------ x86.c | 20 ++++++++++++++++++++ x86_64.c | 28 ++++++++++++++++++++++++++++ 9 files changed, 80 insertions(+), 28 deletions(-) diff --git a/defs.h b/defs.h index f84f9d4..1e8f2f9 100755 --- a/defs.h +++ b/defs.h @@ -807,6 +807,7 @@ struct machdep_table { int (*xen_kdump_p2m_create)(struct xen_kdump_data *); int (*in_alternate_stack)(int, ulong); void (*dumpfile_init)(int, void *); + void (*show_cpu)(void); }; /* @@ -3357,6 +3358,7 @@ void cmd_sys(void); /* kernel.c */ void cmd_irq(void); /* kernel.c */ void cmd_timer(void); /* kernel.c */ void cmd_waitq(void); /* kernel.c */ +void cmd_cpu(void); /* kernel.c */ void cmd_sym(void); /* symbols.c */ void cmd_struct(void); /* symbols.c */ void cmd_union(void); /* symbols.c */ @@ -3821,6 +3823,7 @@ extern char *help_union[]; extern char *help_vm[]; extern char *help_vtop[]; extern char *help_waitq[]; +extern char *help_cpu[]; extern char *help_whatis[]; extern char *help_wr[]; #if defined(S390) || defined(S390X) @@ -4992,9 +4995,22 @@ extern int have_full_symbols(void); #define XEN_HYPERVISOR_ARCH #endif +enum CPU_REG { + R_EAX, + R_ECX, + R_EDX, + R_EBX, + R_ESP, + R_EBP, + R_ESI, + R_EDI, + R_GP_MAX, +}; + struct cpu_info { - uint64_t esp; + uint64_t regs[16]; uint64_t eip; + uint64_t eflags; }; extern struct cpu_info cpu_infos[]; diff --git a/global_data.c b/global_data.c index e936ca5..20539fb 100755 --- a/global_data.c +++ b/global_data.c @@ -118,6 +118,7 @@ struct command_table_entry linux_command_table[] = { {"waitq", cmd_waitq, help_waitq, REFRESH_TASK_TABLE}, {"whatis", cmd_whatis, help_whatis, 0}, {"wr", cmd_wr, help_wr, 0}, + {"cpu", cmd_cpu, help_cpu, 0}, #if defined(S390) || defined(S390X) {"s390dbf", cmd_s390dbf, help_s390dbf, 0}, #endif diff --git a/help.c b/help.c index 94402f9..6fb6846 100755 --- a/help.c +++ b/help.c @@ -2248,19 +2248,7 @@ NULL char *help_cpu[] = { "cpu", -"set context to the active task on a cpu", -"[cpu]", -" This command sets the current context to the active task on a cpu. If no", -" argument is given, the current context is displayed.\n", -" cpu a valid cpu number\n", -" This command is not allowable on live systems.", -"\nEXAMPLES", -" %s> cpu 1", -" PID: 286", -" COMMAND: \"in.rlogind\"", -" TASK: c0b3a000 ", -" CPU: 1 ", -" STATE: TASK_RUNNING (ACTIVE)", +"Show cpu registers", NULL }; diff --git a/kernel.c b/kernel.c index e399099..1d04e68 100755 --- a/kernel.c +++ b/kernel.c @@ -6070,6 +6070,16 @@ cmd_waitq(void) } } +void +cmd_cpu(void) +{ + if (machdep->show_cpu) + machdep->show_cpu(); + else + printf("This command is not supported on %s.\n", MACHINE_TYPE); +} + + static void dump_waitq(ulong wq, char *wq_name) { diff --git a/kvmdump.c b/kvmdump.c index 4b60551..6205892 100644 --- a/kvmdump.c +++ b/kvmdump.c @@ -312,7 +312,7 @@ get_kvmdump_regs(struct bt_info *bt, ulong *pc, ulong *sp) { if (is_task_active(bt->task)) { assert(bt->tc->processor < n_cpu); - *sp = cpu_infos[bt->tc->processor].esp; + *sp = cpu_infos[bt->tc->processor].regs[R_ESP]; *pc = cpu_infos[bt->tc->processor].eip; } else machdep->get_stack_frame(bt, pc, sp); diff --git a/qemu-load.c b/qemu-load.c index a7beb0b..303ed94 100644 --- a/qemu-load.c +++ b/qemu-load.c @@ -611,8 +611,9 @@ cpu_load (struct qemu_device *d, FILE *fp, int size) } assert(d->instance_id == n_cpu); + memcpy(cpu_infos[n_cpu].regs, dx86->regs, sizeof(cpu_infos[n_cpu].regs)); cpu_infos[n_cpu].eip = dx86->eip; - cpu_infos[n_cpu].esp = dx86->regs[R_ESP]; + cpu_infos[n_cpu].eflags = dx86->eflags; n_cpu++; return QEMU_FEATURE_CPU; diff --git a/qemu-load.h b/qemu-load.h index 0d8db4e..578fedd 100644 --- a/qemu-load.h +++ b/qemu-load.h @@ -140,18 +140,6 @@ struct qemu_x86_mce { uint64_t mce_banks[10 * 4]; }; -enum CPU_REG { - R_EAX, - R_ECX, - R_EDX, - R_EBX, - R_ESP, - R_EBP, - R_ESI, - R_EDI, - R_GP_MAX, -}; - struct qemu_device_x86 { struct qemu_device dev_base; diff --git a/x86.c b/x86.c index 4121e28..4ab0677 100755 --- a/x86.c +++ b/x86.c @@ -1673,6 +1673,25 @@ x86_user_eframe(struct bt_info *bt) } +static void +show_cpu(void) +{ + unsigned int i; + + for (i = 0; i < n_cpu; i++) { + printf("CPU %d:\n", i); + + printf(" eax %08llx ebx %08llx ecx %08llx edx %08llx\n" + " esi %08llx edi %08llx esp %08llx ebp %08llx\n", + cpu_infos[i].regs[R_EAX], cpu_infos[i].regs[R_EBX], + cpu_infos[i].regs[R_ECX], cpu_infos[i].regs[R_EDX], + cpu_infos[i].regs[R_ESI], cpu_infos[i].regs[R_EDI], + cpu_infos[i].regs[R_ESP], cpu_infos[i].regs[R_EBP]); + + printf(" eip %08llx\n", cpu_infos[i].eip); + } +} + /* * Do all necessary machine-specific setup here. This is called three times, * during symbol table initialization, and before and after GDB has been @@ -1717,6 +1736,7 @@ x86_init(int when) machdep->last_ptbl_read = 0; machdep->machspec = &x86_machine_specific; machdep->verify_paddr = generic_verify_paddr; + machdep->show_cpu = show_cpu; break; case PRE_GDB: diff --git a/x86_64.c b/x86_64.c index be81247..5a500ee 100755 --- a/x86_64.c +++ b/x86_64.c @@ -102,6 +102,7 @@ static ulong x86_64_get_framepointer(struct bt_info *, ulong); static int x86_64_get_framesize(struct bt_info *, ulong, ulong); static void x86_64_framesize_debug(struct bt_info *); static void x86_64_get_active_set(void); +static void show_cpu(void); struct machine_specific x86_64_machine_specific = { 0 }; @@ -154,6 +155,7 @@ x86_64_init(int when) machdep->machspec->irq_eframe_link = UNINITIALIZED; if (machdep->cmdline_args[0]) parse_cmdline_args(); + machdep->show_cpu = show_cpu; break; case PRE_GDB: @@ -6850,4 +6852,30 @@ x86_64_get_active_set(void) } } +static void +show_cpu(void) +{ + unsigned int i; + + for (i = 0; i < n_cpu; i++) { + printf("CPU %d:\n", i); + + printf(" rax %016llx rbx %016llx rcx %016llx rdx %016llx\n" + " rsi %016llx rdi %016llx rsp %016llx rbp %016llx\n", + cpu_infos[i].regs[R_EAX], cpu_infos[i].regs[R_EBX], + cpu_infos[i].regs[R_ECX], cpu_infos[i].regs[R_EDX], + cpu_infos[i].regs[R_ESI], cpu_infos[i].regs[R_EDI], + cpu_infos[i].regs[R_ESP], cpu_infos[i].regs[R_EBP]); + + printf(" r8 %016llx r9 %016llx r10 %016llx r11 %016llx\n" + " r12 %016llx r13 %016llx r14 %016llx r15 %016llx\n", + cpu_infos[i].regs[8], cpu_infos[i].regs[9], + cpu_infos[i].regs[10], cpu_infos[i].regs[11], + cpu_infos[i].regs[12], cpu_infos[i].regs[13], + cpu_infos[i].regs[14], cpu_infos[i].regs[15]); + + printf(" rip %16llx\n", cpu_infos[i].eip); + } +} + #endif /* X86_64 */ -- 1.7.3