diff mbox series

[v4,28/46] windbg: implemented windbg_write_ks_regs

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

Commit Message

Mikhail Abakumov Dec. 11, 2017, 1:23 p.m. UTC
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>
---
 target/i386/windbgstub.c |  111 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 111 insertions(+)
diff mbox series

Patch

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index da7d1eae0c..25a0ee8a66 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -645,6 +645,117 @@  static int windbg_read_ks_regs(CPUState *cpu, uint8_t *buf, int buf_size,
 static int windbg_write_ks_regs(CPUState *cpu, uint8_t *buf, int buf_size,
                                 int offset, int len)
 {
+    CPUArchState *env = cpu->env_ptr;
+    int mem_size;
+    uint8_t *mem_ptr = buf;
+    while (len > 0 && offset < sizeof(CPU_KSPECIAL_REGISTERS)) {
+        mem_size = 1;
+        switch (offset) {
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Cr0):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Cr0);
+            cpu_x86_update_cr0(env, ldtul_p(buf + offset));
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Cr2):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Cr2);
+            env->cr[2] = ldtul_p(buf + offset);
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Cr3):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Cr3);
+            cpu_x86_update_cr3(env, ldtul_p(buf + offset));
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Cr4):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Cr4);
+            cpu_x86_update_cr4(env, ldtul_p(buf + offset));
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, KernelDr0):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, KernelDr0);
+            windbg_set_dr(cpu, 0, ldtul_p(buf + offset));
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, KernelDr1):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, KernelDr1);
+            windbg_set_dr(cpu, 1, ldtul_p(buf + offset));
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, KernelDr2):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, KernelDr2);
+            windbg_set_dr(cpu, 2, ldtul_p(buf + offset));
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, KernelDr3):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, KernelDr3);
+            windbg_set_dr(cpu, 3, ldtul_p(buf + offset));
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, KernelDr6):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, KernelDr6);
+            windbg_set_dr(cpu, 6, ldtul_p(buf + offset));
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, KernelDr7):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, KernelDr7);
+            windbg_set_dr(cpu, 7, ldtul_p(buf + offset));
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Gdtr.Pad):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Gdtr.Pad);
+            env->gdt.selector = lduw_p(buf + offset);
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Gdtr.Limit):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Gdtr.Limit);
+            env->gdt.limit = lduw_p(buf + offset);
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Gdtr.Base):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Gdtr.Base);
+            env->gdt.base = ldtul_p(buf + offset);
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Idtr.Pad):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Idtr.Pad);
+            env->idt.selector = lduw_p(buf + offset);
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Idtr.Limit):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Idtr.Limit);
+            env->idt.limit = lduw_p(buf + offset);
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Idtr.Base):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Idtr.Base);
+            env->idt.base = ldtul_p(buf + offset);
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Tr):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Tr);
+            env->tr.selector = lduw_p(buf + offset);
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Ldtr):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Ldtr);
+            env->ldt.selector = lduw_p(buf + offset);
+            break;
+
+        case offsetof(CPU_KSPECIAL_REGISTERS, Reserved):
+            mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Reserved);
+            break;
+
+        default:
+            WINDBG_ERROR("write_context: Unknown offset %d", offset);
+            return -1;
+        }
+
+        mem_ptr += mem_size;
+        offset += mem_size;
+        len -= mem_size;
+    }
+
     return 0;
 }