diff mbox series

[14/43] windbg: init DBGKD_ANY_WAIT_STATE_CHANGE

Message ID 150642392471.3900.18243723823459989509.stgit@Misha-PC.lan02.inno
State New
Headers show
Series Windbg supporting | expand

Commit Message

Mikhail Abakumov Sept. 26, 2017, 11:05 a.m. UTC
Added function for init DBGKD_ANY_WAIT_STATE_CHANGE. It is a header of 'state change' packets.


Signed-off-by: Mihail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltunov@ispras.ru>
---
 include/exec/windbgstub-utils.h |    8 +++++
 windbgstub-utils.c              |   57 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)
diff mbox series

Patch

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 63df5e339c..cf2996d8cb 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -62,6 +62,14 @@ 
     _t;                                                       \
 })
 
+#if TARGET_LONG_BITS == 64
+# define sttul_p(p, v) stq_p(p, v)
+# define ldtul_p(p) ldq_p(p)
+#else
+# define sttul_p(p, v) stl_p(p, v)
+# define ldtul_p(p) ldl_p(p)
+#endif
+
 typedef struct InitedAddr {
     target_ulong addr;
     bool is_init;
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 662096647e..60f6705f7c 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -14,9 +14,13 @@ 
 #ifdef TARGET_X86_64
 # define OFFSET_SELF_PCR         0x18
 # define OFFSET_VERS             0x108
+# define OFFSET_KPRCB            0x20
+# define OFFSET_KPRCB_CURRTHREAD 0x8
 #else
 # define OFFSET_SELF_PCR         0x1C
 # define OFFSET_VERS             0x34
+# define OFFSET_KPRCB            0x20
+# define OFFSET_KPRCB_CURRTHREAD 0x4
 #endif
 
 typedef struct KDData {
@@ -26,6 +30,59 @@  typedef struct KDData {
 
 static KDData *kd;
 
+static void kd_breakpoint_remove_range(CPUState *cpu, target_ulong base,
+                                       target_ulong limit)
+{}
+
+__attribute__ ((unused)) /* unused yet */
+static void kd_init_state_change(CPUState *cpu,
+                                 DBGKD_ANY_WAIT_STATE_CHANGE *sc)
+{
+    CPUArchState *env = cpu->env_ptr;
+    DBGKD_CONTROL_REPORT *cr = &sc->ControlReport;
+    int err = 0;
+
+    /* T0D0: HEADER */
+
+    sc->Processor = 0;
+
+    sc->NumberProcessors = 0;
+    CPUState *cpu_tmp;
+    CPU_FOREACH(cpu_tmp) {
+        sc->NumberProcessors++;
+    }
+    sc->NumberProcessors = ldl_p(&sc->NumberProcessors);
+
+    target_ulong KPRCB = READ_VMEM(cpu, kd->KPCR.addr +
+                                   OFFSET_KPRCB, target_ulong);
+    sc->Thread = READ_VMEM(cpu, KPRCB + OFFSET_KPRCB_CURRTHREAD,
+                           target_ulong);
+    sc->Thread = ldtul_p(&sc->Thread);
+    sc->ProgramCounter = ldtul_p(&env->eip);
+
+    /* T0D0: CONTROL REPORT */
+
+    cr->Dr6 = ldtul_p(&env->dr[6]);
+    cr->Dr7 = ldtul_p(&env->dr[7]);
+    cr->ReportFlags = REPORT_INCLUDES_SEGS | REPORT_STANDARD_CS;
+    cr->ReportFlags = lduw_p(&cr->ReportFlags);
+    cr->SegCs = lduw_p(&env->segs[R_CS].selector);
+    cr->SegDs = lduw_p(&env->segs[R_DS].selector);
+    cr->SegEs = lduw_p(&env->segs[R_ES].selector);
+    cr->SegFs = lduw_p(&env->segs[R_FS].selector);
+    cr->EFlags = ldl_p(&env->eflags);
+
+    err = cpu_memory_rw_debug(cpu, sc->ProgramCounter,
+                              PTR(cr->InstructionStream[0]),
+                              DBGKD_MAXSTREAM, 0);
+    if (!err) {
+        cr->InstructionCount = DBGKD_MAXSTREAM;
+        cr->InstructionCount = lduw_p(&cr->InstructionCount);
+        kd_breakpoint_remove_range(cpu, sc->ProgramCounter,
+                                   sc->ProgramCounter + DBGKD_MAXSTREAM);
+    }
+}
+
 bool windbg_on_load(void)
 {
     CPUState *cpu = qemu_get_cpu(0);