Re: [Qemu-devel] [PATCH v4 00/46] Windbg supporting

2018-01-15 Thread Mihail Abakumov

Paolo Bonzini писал 2018-01-12 11:27:

On 11/12/2017 14:21, Mihail Abakumov wrote:

How it works:
The WinDbg debugger has the possibility of connecting to a remote 
debug service
(Kdsrv.exe) in the Windows kernel. Therefore, it is possible to 
connect to the
guest system running in the QEMU emulator. Kernel debugging is 
possible only
with the enabled debugging mode, may change at the same time. Our 
module of
WinDbg debugger for QEMU is an alternative of the remote debugging 
service in
the kernel. Thus, the debugger connects to the debugging module, not 
to the
kernel of the operating system. The module obtains all the necessary 
information
answering debugger requests from the QEMU emulator. At the same time 
for
debugging there is no need to enable debugging mode in the kernel. 
This leads to
hidden debugging. Our module supports all features of WinDbg regarding 
remote
debugging, besides interception of events and exceptions. Only i386 is 
supported

now.


How hard would it be to support x86_64?  I'm not sure how useful this 
is

for 32-bit only.

Paolo


I tried it a year ago. But I did it only partially because I could not 
even
run Windows 7 x64 on x86_64 due to some kind of error. Today I tried the 
last

version and it ran. So I think I can add support x86_64.

--
Thanks,
Mihail



[Qemu-devel] [PATCH v4 44/46] windbg: implemented kd_api_get_context_ex and kd_api_set_context_ex

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 +
 target/i386/windbgstub.c|  130 ---
 windbgstub.c|   14 +++-
 3 files changed, 106 insertions(+), 40 deletions(-)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 8d36354b7c..d3e737e031 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -94,6 +94,8 @@ void kd_api_search_memory(CPUState *cpu, PacketData *pd);
 void kd_api_fill_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 void kd_api_query_memory(CPUState *cpu, PacketData *pd);
+void kd_api_get_context_ex(CPUState *cpu, PacketData *pd);
+void kd_api_set_context_ex(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
 SizedBuf kd_gen_load_symbols_sc(CPUState *cpu);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 7985dcfaf0..96cb015752 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -903,6 +903,52 @@ static int windbg_write_ks_regs(CPUState *cpu, uint8_t 
*buf, int buf_size,
 return 0;
 }
 
+static int windbg_rw_context_ex(CPUState *cpu, uint8_t *buf, int buf_size,
+int offset, int len, bool is_read)
+{
+uint32_t context_len;
+uint32_t ks_regs_len;
+int err = -1;
+
+if (offset < sizeof(CPU_KPROCESSOR_STATE)) {
+len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - offset);
+
+context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - offset));
+ks_regs_len = len - context_len;
+
+if (context_len > 0) {
+if (is_read) {
+err = windbg_read_context(cpu, buf, context_len, offset,
+  context_len);
+} else {
+err = windbg_write_context(cpu, buf, context_len, offset,
+   context_len);
+}
+
+if (err) {
+return err;
+}
+}
+
+if (ks_regs_len > 0) {
+offset += context_len - sizeof(CPU_CONTEXT);
+if (is_read) {
+err = windbg_read_ks_regs(cpu, buf + context_len, ks_regs_len,
+  offset, ks_regs_len);
+} else {
+err = windbg_write_ks_regs(cpu, buf + context_len, ks_regs_len,
+   offset, ks_regs_len);
+}
+
+if (err) {
+return err;
+}
+}
+}
+
+return err;
+}
+
 void kd_api_get_context(CPUState *cpu, PacketData *pd)
 {
 int err;
@@ -934,31 +980,14 @@ void kd_api_read_control_space(CPUState *cpu, PacketData 
*pd)
 {
 DBGKD_READ_MEMORY64 *mem = >m64.u.ReadMemory;
 uint32_t len;
-uint32_t context_len;
-uint32_t ks_regs_len;
 target_ulong addr;
-int err = -1;
+int err;
 
 len = MIN(ldl_p(>TransferCount),
   PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
 addr = ldtul_p(>TargetBaseAddress);
 
-if (addr < sizeof(CPU_KPROCESSOR_STATE)) {
-len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - addr);
-
-context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - addr));
-ks_regs_len = len - context_len;
-
-if (context_len > 0) {
-err = windbg_read_context(cpu, pd->extra, context_len, addr,
-  context_len);
-}
-if (ks_regs_len > 0) {
-addr = addr - sizeof(CPU_CONTEXT) + context_len;
-err = windbg_read_ks_regs(cpu, pd->extra + context_len,
-  ks_regs_len, addr, ks_regs_len);
-}
-}
+err = windbg_rw_context_ex(cpu, pd->extra, len, addr, len, true);
 
 if (err) {
 len = 0;
@@ -973,38 +1002,64 @@ void kd_api_write_control_space(CPUState *cpu, 
PacketData *pd)
 {
 DBGKD_WRITE_MEMORY64 *mem = >m64.u.WriteMemory;
 uint32_t len;
-uint32_t context_len;
-uint32_t ks_regs_len;
 target_ulong addr;
-int err = -1;
+int err;
 
 len = MIN(ldl_p(>TransferCount), pd->extra_size);
 addr = ldtul_p(>TargetBaseAddress);
 
-if (addr < sizeof(CPU_KPROCESSOR_STATE)) {
-len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - addr);
+err = windbg_rw_context_ex(cpu, pd->extra, len, addr, len, false);
 
-context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - addr));
-ks_regs_len = len - context_len;
+if (err) {
+len = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
 
-if (context_len > 0) {
-err = windbg_write_context(cpu, pd->extra, context_len, addr,
-   

[Qemu-devel] [PATCH v4 46/46] windbg: maintainers

2017-12-11 Thread Mihail Abakumov
Added WinDbg stub to the MAINTAINERS.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 MAINTAINERS |   12 
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ccee28b12d..8ee2c780e3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1300,6 +1300,18 @@ S: Odd Fixes
 F: gdbstub*
 F: gdb-xml/
 
+WinDbg stub
+M: Mihail Abakumov <mikhail.abaku...@ispras.ru>
+R: Pavel Dovgalyuk <pavel.dovga...@ispras.ru>
+S: Supported
+F: include/exec/windbgstub.h
+F: include/exec/windbgstub-utils.h
+F: include/exec/windbgkd.h
+F: windbgstub.c
+F: windbgstub-utils.c
+F: stubs/windbgstub.c
+F: target/i386/windbgstub.c
+
 Memory API
 M: Paolo Bonzini <pbonz...@redhat.com>
 S: Supported




[Qemu-devel] [PATCH v4 41/46] windbg: implemented kd_api_fill_memory

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   39 +++
 windbgstub.c|4 
 3 files changed, 44 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index a58c47d359..f4adfe44dd 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -91,6 +91,7 @@ void kd_api_get_version(CPUState *cpu, PacketData *pd);
 void kd_api_read_msr(CPUState *cpu, PacketData *pd);
 void kd_api_write_msr(CPUState *cpu, PacketData *pd);
 void kd_api_search_memory(CPUState *cpu, PacketData *pd);
+void kd_api_fill_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 79899d3295..a34f5ae8bd 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -294,6 +294,45 @@ void kd_api_search_memory(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_fill_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_FILL_MEMORY *m64c = >m64.u.FillMemory;
+uint32_t len = ldl_p(>Length);
+target_ulong addr = ldq_p(>Address);
+uint16_t pattern = ldl_p(>PatternLength);
+uint16_t flags = ldl_p(>Flags);
+int err, offset = 0;
+
+uint8_t mem[pattern];
+memcpy(mem, pd->extra, pattern);
+
+pd->extra_size = 0;
+
+switch (flags) {
+case DBGKD_FILL_MEMORY_VIRTUAL:
+while (offset < len) {
+err = cpu_memory_rw_debug(cpu, addr + offset, mem,
+  MIN(pattern, len - offset), 1);
+offset += pattern;
+if (err) {
+WINDBG_DEBUG("fill_memory: No physical page mapped: " FMT_ADDR,
+ addr);
+}
+}
+break;
+
+case DBGKD_FILL_MEMORY_PHYSICAL:
+while (offset < len) {
+cpu_physical_memory_rw(addr, mem, MIN(pattern, len - offset), 1);
+offset += pattern;
+}
+break;
+
+default:
+break;
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index 3dcac03be1..f0b3ca3390 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -216,6 +216,10 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_search_memory(cpu, >data);
 break;
 
+case DbgKdFillMemoryApi:
+kd_api_fill_memory(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v4 45/46] windbg: changed kd_api_read_msr and kd_api_write_msr

2017-12-11 Thread Mihail Abakumov
Added sub functions for helper_wrmsr and helper_rdmsr: cpu_x86_write_msr and 
cpu_x86_read_msr. Also they are used in packet handlers, i.e. duplication of 
code is removed.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/cpu.h |3 
 target/i386/misc_helper.c |   49 +--
 target/i386/windbgstub.c  |  303 +
 3 files changed, 43 insertions(+), 312 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 051867399b..04c5aac795 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1481,6 +1481,9 @@ void cpu_x86_update_cr3(CPUX86State *env, target_ulong 
new_cr3);
 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
 void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7);
 
+void cpu_x86_write_msr(CPUX86State *env, uint64_t val);
+uint64_t cpu_x86_read_msr(CPUX86State *env);
+
 /* hw/pc.c */
 uint64_t cpu_get_tsc(CPUX86State *env);
 
diff --git a/target/i386/misc_helper.c b/target/i386/misc_helper.c
index ec1fcd2899..5d74c31998 100644
--- a/target/i386/misc_helper.c
+++ b/target/i386/misc_helper.c
@@ -220,6 +220,14 @@ void helper_rdpmc(CPUX86State *env)
 }
 
 #if defined(CONFIG_USER_ONLY)
+void cpu_x86_write_msr(CPUX86State *env, uint64_t val)
+{
+}
+
+uint64_t cpu_x86_read_msr(CPUX86State *env)
+{
+}
+
 void helper_wrmsr(CPUX86State *env)
 {
 }
@@ -228,15 +236,8 @@ void helper_rdmsr(CPUX86State *env)
 {
 }
 #else
-void helper_wrmsr(CPUX86State *env)
+void cpu_x86_write_msr(CPUX86State *env, uint64_t val)
 {
-uint64_t val;
-
-cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC());
-
-val = ((uint32_t)env->regs[R_EAX]) |
-((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
-
 switch ((uint32_t)env->regs[R_ECX]) {
 case MSR_IA32_SYSENTER_CS:
 env->sysenter_cs = val & 0x;
@@ -386,16 +387,12 @@ void helper_wrmsr(CPUX86State *env)
 /* XXX: exception? */
 break;
 }
-
-windbg_try_load();
 }
 
-void helper_rdmsr(CPUX86State *env)
+uint64_t cpu_x86_read_msr(CPUX86State *env)
 {
 uint64_t val;
 
-cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, GETPC());
-
 switch ((uint32_t)env->regs[R_ECX]) {
 case MSR_IA32_SYSENTER_CS:
 val = env->sysenter_cs;
@@ -534,6 +531,32 @@ void helper_rdmsr(CPUX86State *env)
 val = 0;
 break;
 }
+
+return val;
+}
+
+void helper_wrmsr(CPUX86State *env)
+{
+uint64_t val;
+
+cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC());
+
+val = ((uint32_t)env->regs[R_EAX]) |
+((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
+
+cpu_x86_write_msr(env, val);
+
+windbg_try_load();
+}
+
+void helper_rdmsr(CPUX86State *env)
+{
+uint64_t val;
+
+cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, GETPC());
+
+val = cpu_x86_read_msr(env);
+
 env->regs[R_EAX] = (uint32_t)(val);
 env->regs[R_EDX] = (uint32_t)(val >> 32);
 }
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 96cb015752..c38bfa7448 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -1076,150 +1076,9 @@ void kd_api_read_msr(CPUState *cpu, PacketData *pd)
 DBGKD_READ_WRITE_MSR *m64c = >m64.u.ReadWriteMsr;
 CPUArchState *env = cpu->env_ptr;
 
-uint64_t val;
-
-cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, 0);
-
-switch ((uint32_t)env->regs[R_ECX]) {
-case MSR_IA32_SYSENTER_CS:
-val = env->sysenter_cs;
-break;
-case MSR_IA32_SYSENTER_ESP:
-val = env->sysenter_esp;
-break;
-case MSR_IA32_SYSENTER_EIP:
-val = env->sysenter_eip;
-break;
-case MSR_IA32_APICBASE:
-val = cpu_get_apic_base(x86_env_get_cpu(env)->apic_state);
-break;
-case MSR_EFER:
-val = env->efer;
-break;
-case MSR_STAR:
-val = env->star;
-break;
-case MSR_PAT:
-val = env->pat;
-break;
-case MSR_VM_HSAVE_PA:
-val = env->vm_hsave;
-break;
-case MSR_IA32_PERF_STATUS:
-/* tsc_increment_by_tick */
-val = 1000ULL;
-/* CPU multiplier */
-val |= (((uint64_t)4ULL) << 40);
-break;
-#ifdef TARGET_X86_64
-case MSR_LSTAR:
-val = env->lstar;
-break;
-case MSR_CSTAR:
-val = env->cstar;
-break;
-case MSR_FMASK:
-val = env->fmask;
-break;
-case MSR_FSBASE:
-val = env->segs[R_FS].base;
-break;
-case MSR_GSBASE:
-val = env->segs[R_GS].base;
-break;
-case MSR_KERNELGSBASE:
-val = env->kernelgsbase;
-break;
-case MSR_TSC_AUX:
-val = env->tsc_aux;
-break;
-#endif
-case MSR_MTRRphys

[Qemu-devel] [PATCH v4 42/46] windbg: implemented kd_api_query_memory

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |9 +
 windbgstub.c|4 
 3 files changed, 14 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index f4adfe44dd..8d36354b7c 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -93,6 +93,7 @@ void kd_api_write_msr(CPUState *cpu, PacketData *pd);
 void kd_api_search_memory(CPUState *cpu, PacketData *pd);
 void kd_api_fill_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
+void kd_api_query_memory(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
 SizedBuf kd_gen_load_symbols_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index a34f5ae8bd..e3b1276dab 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -333,6 +333,15 @@ void kd_api_fill_memory(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_query_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_QUERY_MEMORY *mem = >m64.u.QueryMemory;
+
+stl_p(>AddressSpace, DBGKD_QUERY_MEMORY_PROCESS);
+stl_p(>Flags, DBGKD_QUERY_MEMORY_READ |
+   DBGKD_QUERY_MEMORY_WRITE | DBGKD_QUERY_MEMORY_EXECUTE);
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index f0b3ca3390..f0930f20a8 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -220,6 +220,10 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_fill_memory(cpu, >data);
 break;
 
+case DbgKdQueryMemoryApi:
+kd_api_query_memory(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v4 39/46] windbg: implemented kd_api_read_msr and kd_api_write_msr

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 
 target/i386/windbgstub.c|  328 +++
 windbgstub.c|8 +
 3 files changed, 338 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 8cdb27..6e73ef973c 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -88,6 +88,8 @@ void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_get_version(CPUState *cpu, PacketData *pd);
+void kd_api_read_msr(CPUState *cpu, PacketData *pd);
+void kd_api_write_msr(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 5e094e81d7..7985dcfaf0 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -1007,6 +1007,334 @@ void kd_api_write_control_space(CPUState *cpu, 
PacketData *pd)
 stl_p(>ActualBytesWritten, len);
 }
 
+#if defined(CONFIG_USER_ONLY)
+void kd_api_read_msr(CPUState *cpu, PacketData *pd)
+{
+}
+
+void kd_api_write_msr(CPUState *cpu, PacketData *pd)
+{
+}
+#else
+void kd_api_read_msr(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_WRITE_MSR *m64c = >m64.u.ReadWriteMsr;
+CPUArchState *env = cpu->env_ptr;
+
+uint64_t val;
+
+cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, 0);
+
+switch ((uint32_t)env->regs[R_ECX]) {
+case MSR_IA32_SYSENTER_CS:
+val = env->sysenter_cs;
+break;
+case MSR_IA32_SYSENTER_ESP:
+val = env->sysenter_esp;
+break;
+case MSR_IA32_SYSENTER_EIP:
+val = env->sysenter_eip;
+break;
+case MSR_IA32_APICBASE:
+val = cpu_get_apic_base(x86_env_get_cpu(env)->apic_state);
+break;
+case MSR_EFER:
+val = env->efer;
+break;
+case MSR_STAR:
+val = env->star;
+break;
+case MSR_PAT:
+val = env->pat;
+break;
+case MSR_VM_HSAVE_PA:
+val = env->vm_hsave;
+break;
+case MSR_IA32_PERF_STATUS:
+/* tsc_increment_by_tick */
+val = 1000ULL;
+/* CPU multiplier */
+val |= (((uint64_t)4ULL) << 40);
+break;
+#ifdef TARGET_X86_64
+case MSR_LSTAR:
+val = env->lstar;
+break;
+case MSR_CSTAR:
+val = env->cstar;
+break;
+case MSR_FMASK:
+val = env->fmask;
+break;
+case MSR_FSBASE:
+val = env->segs[R_FS].base;
+break;
+case MSR_GSBASE:
+val = env->segs[R_GS].base;
+break;
+case MSR_KERNELGSBASE:
+val = env->kernelgsbase;
+break;
+case MSR_TSC_AUX:
+val = env->tsc_aux;
+break;
+#endif
+case MSR_MTRRphysBase(0):
+case MSR_MTRRphysBase(1):
+case MSR_MTRRphysBase(2):
+case MSR_MTRRphysBase(3):
+case MSR_MTRRphysBase(4):
+case MSR_MTRRphysBase(5):
+case MSR_MTRRphysBase(6):
+case MSR_MTRRphysBase(7):
+val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+ MSR_MTRRphysBase(0)) / 2].base;
+break;
+case MSR_MTRRphysMask(0):
+case MSR_MTRRphysMask(1):
+case MSR_MTRRphysMask(2):
+case MSR_MTRRphysMask(3):
+case MSR_MTRRphysMask(4):
+case MSR_MTRRphysMask(5):
+case MSR_MTRRphysMask(6):
+case MSR_MTRRphysMask(7):
+val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+ MSR_MTRRphysMask(0)) / 2].mask;
+break;
+case MSR_MTRRfix64K_0:
+val = env->mtrr_fixed[0];
+break;
+case MSR_MTRRfix16K_8:
+case MSR_MTRRfix16K_A:
+val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+  MSR_MTRRfix16K_8 + 1];
+break;
+case MSR_MTRRfix4K_C:
+case MSR_MTRRfix4K_C8000:
+case MSR_MTRRfix4K_D:
+case MSR_MTRRfix4K_D8000:
+case MSR_MTRRfix4K_E:
+case MSR_MTRRfix4K_E8000:
+case MSR_MTRRfix4K_F:
+case MSR_MTRRfix4K_F8000:
+val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+  MSR_MTRRfix4K_C + 3];
+break;
+case MSR_MTRRdefType:
+val = env->mtrr_deftype;
+break;
+case MSR_MTRRcap:
+if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
+val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT |
+MSR_MTRRcap_WC_SUPPORTED;
+} else {
+/* XXX: exception? */
+val = 0;
+}
+

[Qemu-devel] [PATCH v4 43/46] windbg: added new api functions

2017-12-11 Thread Mihail Abakumov
Added some definitions for new windbg.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgkd.h |   21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/include/exec/windbgkd.h b/include/exec/windbgkd.h
index 5008cbb729..aa2b4fdbd9 100755
--- a/include/exec/windbgkd.h
+++ b/include/exec/windbgkd.h
@@ -112,7 +112,10 @@
 #define DbgKdFillMemoryApi  0x315b
 #define DbgKdQueryMemoryApi 0x315c
 #define DbgKdSwitchPartition0x315d
-#define DbgKdMaximumManipulate  0x315e
+#define DbgKdWriteCustomBreakpointApi   0x315e
+#define DbgKdGetContextExApi0x315f
+#define DbgKdSetContextExApi0x3160
+#define DbgKdMaximumManipulate  0x3161
 
 /*
  * Debug I/O Types
@@ -723,6 +726,20 @@ typedef struct _DBGKD_SWITCH_PARTITION {
 uint32_t Partition;
 } DBGKD_SWITCH_PARTITION;
 
+typedef struct _DBGKD_CONTEXT_EX {
+   uint32_t Offset;
+   uint32_t ByteCount;
+   uint32_t BytesCopied;
+} DBGKD_CONTEXT_EX, *PDBGKD_CONTEXT_EX;
+
+typedef struct _DBGKD_WRITE_CUSTOM_BREAKPOINT {
+   uint64_t BreakPointAddress;
+   uint64_t BreakPointInstruction;
+   uint32_t BreakPointHandle;
+   uint16_t BreakPointInstructionSize;
+   uint16_t BreakPointInstructionAlignment;
+} DBGKD_WRITE_CUSTOM_BREAKPOINT, *PDBGKD_WRITE_CUSTOM_BREAKPOINT;
+
 /*
  * DBGKD Structure for Manipulate
  */
@@ -787,6 +804,8 @@ typedef struct _DBGKD_MANIPULATE_STATE64 {
 DBGKD_FILL_MEMORY FillMemory;
 DBGKD_QUERY_MEMORY QueryMemory;
 DBGKD_SWITCH_PARTITION SwitchPartition;
+DBGKD_WRITE_CUSTOM_BREAKPOINT WriteCustomBreakpoint;
+DBGKD_CONTEXT_EX ContextEx;
 } u;
 } DBGKD_MANIPULATE_STATE64, *PDBGKD_MANIPULATE_STATE64;
 




[Qemu-devel] [PATCH v4 40/46] windbg: implemented kd_api_search_memory

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   33 +
 windbgstub.c|4 
 3 files changed, 38 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 6e73ef973c..a58c47d359 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -90,6 +90,7 @@ void kd_api_write_physical_memory(CPUState *cpu, PacketData 
*pd);
 void kd_api_get_version(CPUState *cpu, PacketData *pd);
 void kd_api_read_msr(CPUState *cpu, PacketData *pd);
 void kd_api_write_msr(CPUState *cpu, PacketData *pd);
+void kd_api_search_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 7ef301bac7..79899d3295 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -261,6 +261,39 @@ void kd_api_get_version(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_search_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_SEARCH_MEMORY *m64c = >m64.u.SearchMemory;
+int s_len = MAX(ldq_p(>SearchLength), 1);
+int p_len = MIN(ldl_p(>PatternLength), pd->extra_size);
+target_ulong addr = ldq_p(>SearchAddress);
+int size = MIN(s_len, 1024);
+uint8_t mem[size + p_len];
+int i, err;
+
+pd->extra_size = 0;
+pd->m64.ReturnStatus = STATUS_NO_MORE_ENTRIES;
+
+while (s_len) {
+err = cpu_memory_rw_debug(cpu, addr, mem, size + p_len, 0);
+if (!err) {
+for (i = 0; i < size; ++i) {
+if (memcmp(mem + i, pd->extra, p_len) == 0) {
+stl_p(>FoundAddress, addr + i);
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+return;
+}
+}
+} else {
+WINDBG_DEBUG("search_memory: No physical page mapped: " FMT_ADDR,
+ addr);
+}
+s_len -= size;
+addr += size;
+size = MIN(s_len, 1024);
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index 45f61917d9..3dcac03be1 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -212,6 +212,10 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 case DbgKdClearAllInternalBreakpointsApi:
 return;
 
+case DbgKdSearchMemoryApi:
+kd_api_search_memory(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v4 38/46] windbg: implemented kd_api_get_version

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   22 ++
 windbgstub.c|4 
 3 files changed, 27 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index a40253f18a..8cdb27 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -87,6 +87,7 @@ void kd_api_read_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd);
+void kd_api_get_version(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 6708e62798..7ef301bac7 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -239,6 +239,28 @@ void kd_api_write_physical_memory(CPUState *cpu, 
PacketData *pd)
 stl_p(>ActualBytesWritten, len);
 }
 
+void kd_api_get_version(CPUState *cpu, PacketData *pd)
+{
+DBGKD_GET_VERSION64 *kdver;
+int err = cpu_memory_rw_debug(cpu, version.addr, PTR(pd->m64) + 0x10,
+  sizeof(DBGKD_MANIPULATE_STATE64) - 0x10, 0);
+if (!err) {
+kdver = (DBGKD_GET_VERSION64 *) (PTR(pd->m64) + 0x10);
+
+stw_p(>MajorVersion, kdver->MajorVersion);
+stw_p(>MinorVersion, kdver->MinorVersion);
+stw_p(>Flags, kdver->Flags);
+stw_p(>MachineType, kdver->MachineType);
+stw_p(>Unused[0], kdver->Unused[0]);
+sttul_p(>KernBase, kdver->KernBase);
+sttul_p(>PsLoadedModuleList, kdver->PsLoadedModuleList);
+sttul_p(>DebuggerDataList, kdver->DebuggerDataList);
+} else {
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+WINDBG_ERROR("get_version: " FMT_ERR, err);
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index 9cf25bc6dd..06e99199b6 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -197,6 +197,10 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_write_physical_memory(cpu, >data);
 break;
 
+case DbgKdGetVersionApi:
+kd_api_get_version(cpu, >data);
+break;
+
 case DbgKdClearAllInternalBreakpointsApi:
 return;
 




[Qemu-devel] [PATCH v4 33/46] windbg: implemented kd_api_write_breakpoint and kd_api_restore_breakpoint

2017-12-11 Thread Mihail Abakumov
Added supporting of windbg breakpoints.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 +
 windbgstub-utils.c  |   62 +++
 windbgstub.c|   11 +++
 3 files changed, 75 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index e04bd59d46..cc4809de0d 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -78,6 +78,8 @@ void kd_api_read_virtual_memory(CPUState *cpu, PacketData 
*pd);
 void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd);
 void kd_api_get_context(CPUState *cpu, PacketData *pd);
 void kd_api_set_context(CPUState *cpu, PacketData *pd);
+void kd_api_write_breakpoint(CPUState *cpu, PacketData *pd);
+void kd_api_restore_breakpoint(CPUState *cpu, PacketData *pd);
 void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 1e81c37501..f00dab2a9d 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -14,6 +14,8 @@
 static InitedAddr KPCR;
 static InitedAddr version;
 
+static InitedAddr bps[KD_BREAKPOINT_MAX];
+
 InitedAddr *windbg_get_KPCR(void)
 {
 return 
@@ -71,6 +73,66 @@ void kd_api_write_virtual_memory(CPUState *cpu, PacketData 
*pd)
 stl_p(>ActualBytesWritten, len);
 }
 
+void kd_api_write_breakpoint(CPUState *cpu, PacketData *pd)
+{
+DBGKD_WRITE_BREAKPOINT64 *m64c = >m64.u.WriteBreakPoint;
+target_ulong addr;
+int i, err = 0;
+
+addr = ldtul_p(>BreakPointAddress);
+
+for (i = 0; i < KD_BREAKPOINT_MAX; ++i) {
+if (!bps[i].is_init) {
+err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
+if (!err) {
+bps[i].addr = addr;
+bps[i].is_init = true;
+WINDBG_DEBUG("write_breakpoint: " FMT_ADDR, addr);
+break;
+} else {
+WINDBG_ERROR("write_breakpoint: " FMT_ADDR ", " FMT_ERR,
+ addr, err);
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+return;
+}
+} else if (addr == bps[i].addr) {
+break;
+}
+}
+
+if (!err) {
+stl_p(>BreakPointHandle, i + 1);
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+} else {
+WINDBG_ERROR("write_breakpoint: All breakpoints occupied");
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+}
+
+void kd_api_restore_breakpoint(CPUState *cpu, PacketData *pd)
+{
+DBGKD_RESTORE_BREAKPOINT *m64c = >m64.u.RestoreBreakPoint;
+uint8_t index;
+int err = -1;
+
+index = ldtul_p(>BreakPointHandle) - 1;
+
+if (bps[index].is_init) {
+err = cpu_breakpoint_remove(cpu, bps[index].addr, BP_GDB);
+if (!err) {
+WINDBG_DEBUG("restore_breakpoint: " FMT_ADDR ", index(%d)",
+ bps[index].addr, index);
+} else {
+WINDBG_ERROR("restore_breakpoint: " FMT_ADDR ", index(%d), "
+ FMT_ERR, bps[index].addr, index, err);
+}
+bps[index].is_init = false;
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+} else {
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index 53a7e75683..a534fe170b 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -156,6 +156,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_set_context(cpu, >data);
 break;
 
+case DbgKdWriteBreakPointApi:
+kd_api_write_breakpoint(cpu, >data);
+break;
+
+case DbgKdRestoreBreakPointApi:
+kd_api_restore_breakpoint(cpu, >data);
+break;
+
 case DbgKdReadControlSpaceApi:
 kd_api_read_control_space(cpu, >data);
 break;
@@ -164,6 +172,9 @@ static void windbg_process_manipulate_packet(ParsingContext 
*ctx)
 kd_api_write_control_space(cpu, >data);
 break;
 
+case DbgKdClearAllInternalBreakpointsApi:
+return;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v4 37/46] windbg: implemented kd_api_read_physical_memory and kd_api_write_physical_memory

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 ++
 windbgstub-utils.c  |   29 +
 windbgstub.c|8 
 3 files changed, 39 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 131eb6418a..a40253f18a 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -85,6 +85,8 @@ void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_read_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
+void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd);
+void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 3f8ce1f8be..6708e62798 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -210,6 +210,35 @@ void kd_api_write_io_space(CPUState *cpu, PacketData *pd)
 pd->m64.ReturnStatus = STATUS_SUCCESS;
 }
 
+void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_MEMORY64 *mem = >m64.u.ReadMemory;
+uint32_t len;
+target_ulong addr;
+
+len = MIN(ldl_p(>TransferCount),
+  PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+addr = ldtul_p(>TargetBaseAddress);
+
+cpu_physical_memory_rw(addr, pd->extra, len, 0);
+pd->extra_size = len;
+stl_p(>ActualBytesRead, len);
+}
+
+void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_WRITE_MEMORY64 *mem = >m64.u.WriteMemory;
+uint32_t len;
+target_ulong addr;
+
+len = MIN(ldl_p(>TransferCount), pd->extra_size);
+addr = ldtul_p(>TargetBaseAddress);
+
+cpu_physical_memory_rw(addr, pd->extra, len, 1);
+pd->extra_size = 0;
+stl_p(>ActualBytesWritten, len);
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index a88bfde072..9cf25bc6dd 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -189,6 +189,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_write_control_space(cpu, >data);
 break;
 
+case DbgKdReadPhysicalMemoryApi:
+kd_api_read_physical_memory(cpu, >data);
+break;
+
+case DbgKdWritePhysicalMemoryApi:
+kd_api_write_physical_memory(cpu, >data);
+break;
+
 case DbgKdClearAllInternalBreakpointsApi:
 return;
 




[Qemu-devel] [PATCH v4 35/46] windbg: implemented kd_api_continue

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   15 +++
 windbgstub.c|5 +
 3 files changed, 21 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index cc4809de0d..b2416d7698 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -80,6 +80,7 @@ void kd_api_get_context(CPUState *cpu, PacketData *pd);
 void kd_api_set_context(CPUState *cpu, PacketData *pd);
 void kd_api_write_breakpoint(CPUState *cpu, PacketData *pd);
 void kd_api_restore_breakpoint(CPUState *cpu, PacketData *pd);
+void kd_api_continue(CPUState *cpu, PacketData *pd);
 void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index f00dab2a9d..fe3adb0b88 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -10,6 +10,7 @@
  */
 
 #include "exec/windbgstub-utils.h"
+#include "sysemu/sysemu.h"
 
 static InitedAddr KPCR;
 static InitedAddr version;
@@ -133,6 +134,20 @@ void kd_api_restore_breakpoint(CPUState *cpu, PacketData 
*pd)
 }
 }
 
+void kd_api_continue(CPUState *cpu, PacketData *pd)
+{
+uint32_t status = ldl_p(>m64.u.Continue2.ContinueStatus);
+uint32_t trace = ldl_p(>m64.u.Continue2.ControlSet.TraceFlag);
+int ssFlag = trace ? SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER : 0;
+
+if (NT_SUCCESS(status)) {
+cpu_single_step(cpu, ssFlag);
+if (!runstate_needs_reset()) {
+vm_start();
+}
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index d3c1317255..bc59c0903a 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -168,6 +168,11 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_restore_breakpoint(cpu, >data);
 break;
 
+case DbgKdContinueApi:
+case DbgKdContinueApi2:
+kd_api_continue(cpu, >data);
+return;
+
 case DbgKdReadControlSpaceApi:
 kd_api_read_control_space(cpu, >data);
 break;




[Qemu-devel] [PATCH v4 36/46] windbg: implemented kd_api_read_io_space and kd_api_write_io_space

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 +
 windbgstub-utils.c  |   62 +++
 windbgstub.c|8 +
 3 files changed, 72 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index b2416d7698..131eb6418a 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -83,6 +83,8 @@ void kd_api_restore_breakpoint(CPUState *cpu, PacketData *pd);
 void kd_api_continue(CPUState *cpu, PacketData *pd);
 void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
+void kd_api_read_io_space(CPUState *cpu, PacketData *pd);
+void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index fe3adb0b88..3f8ce1f8be 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -11,6 +11,7 @@
 
 #include "exec/windbgstub-utils.h"
 #include "sysemu/sysemu.h"
+#include "exec/address-spaces.h"
 
 static InitedAddr KPCR;
 static InitedAddr version;
@@ -148,6 +149,67 @@ void kd_api_continue(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_read_io_space(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_WRITE_IO64 *io = >m64.u.ReadWriteIo;
+CPUArchState *env = cpu->env_ptr;
+
+target_ulong addr = ldtul_p(>IoAddress);
+uint32_t value = 0;
+
+switch (io->DataSize) {
+case 1:
+value = address_space_ldub(_space_io, addr,
+   cpu_get_mem_attrs(env), NULL);
+stl_p(>DataValue, value);
+break;
+case 2:
+value = address_space_lduw(_space_io, addr,
+   cpu_get_mem_attrs(env), NULL);
+stl_p(>DataValue, value);
+break;
+case 4:
+value = address_space_ldl(_space_io, addr,
+  cpu_get_mem_attrs(env), NULL);
+stl_p(>DataValue, value);
+break;
+default:
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+return;
+}
+
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+}
+
+void kd_api_write_io_space(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_WRITE_IO64 *io = >m64.u.ReadWriteIo;
+CPUArchState *env = cpu->env_ptr;
+
+target_ulong addr = ldtul_p(>IoAddress);
+uint32_t value = ldl_p(>DataValue);
+
+switch (io->DataSize) {
+case 1:
+address_space_stb(_space_io, addr, value,
+  cpu_get_mem_attrs(env), NULL);
+break;
+case 2:
+address_space_stw(_space_io, addr, value,
+  cpu_get_mem_attrs(env), NULL);
+break;
+case 4:
+address_space_stl(_space_io, addr, value,
+  cpu_get_mem_attrs(env), NULL);
+break;
+default:
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+return;
+}
+
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index bc59c0903a..a88bfde072 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -168,6 +168,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_restore_breakpoint(cpu, >data);
 break;
 
+case DbgKdReadIoSpaceApi:
+kd_api_read_io_space(cpu, >data);
+break;
+
+case DbgKdWriteIoSpaceApi:
+kd_api_write_io_space(cpu, >data);
+break;
+
 case DbgKdContinueApi:
 case DbgKdContinueApi2:
 kd_api_continue(cpu, >data);




[Qemu-devel] [PATCH v4 30/46] windbg: implemented windbg_set_dr

2017-12-11 Thread Mihail Abakumov
Defined useful macros for breakpoints.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |   50 +-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 2a09cec9d8..cae827df50 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -14,6 +14,21 @@
 #ifndef TARGET_X86_64
 #include "exec/windbgstub-utils.h"
 
+#define IS_LOCAL_BP_ENABLED(dr7, index) (((dr7) >> ((index) * 2)) & 1)
+
+#define IS_GLOBAL_BP_ENABLED(dr7, index) (((dr7) >> ((index) * 2)) & 2)
+
+#define IS_BP_ENABLED(dr7, index) \
+(IS_LOCAL_BP_ENABLED(dr7, index) | IS_GLOBAL_BP_ENABLED(dr7, index))
+
+#define BP_TYPE(dr7, index) \
+((int) ((dr7) >> (DR7_TYPE_SHIFT + ((index) * 4))) & 3)
+
+#define BP_LEN(dr7, index) ({\
+int _len = (((dr7) >> (DR7_LEN_SHIFT + ((index) * 4))) & 3); \
+(_len == 2) ? 8 : _len + 1;  \
+})
+
 #ifdef TARGET_X86_64
 # define OFFSET_SELF_PCR 0x18
 # define OFFSET_VERS 0x108
@@ -273,9 +288,42 @@ typedef struct _CPU_KPROCESSOR_STATE {
 CPU_KSPECIAL_REGISTERS SpecialRegisters;
 } CPU_KPROCESSOR_STATE, *PCPU_KPROCESSOR_STATE;
 
-static void windbg_set_dr(CPUState *cpu, int index, target_ulong value)
+static int windbg_hw_breakpoint_insert(CPUState *cpu, int index)
+{
+return 0;
+}
+
+static int windbg_hw_breakpoint_remove(CPUState *cpu, int index)
+{
+return 0;
+}
+
+static void windbg_set_dr7(CPUState *cpu, target_ulong new_dr7)
 {}
 
+static void windbg_set_dr(CPUState *cpu, int index, target_ulong value)
+{
+CPUArchState *env = cpu->env_ptr;
+
+switch (index) {
+case 0 ... 3:
+if (IS_BP_ENABLED(env->dr[7], index) && env->dr[index] != value) {
+windbg_hw_breakpoint_remove(cpu, index);
+env->dr[index] = value;
+windbg_hw_breakpoint_insert(cpu, index);
+} else {
+env->dr[index] = value;
+}
+return;
+case 6:
+env->dr[6] = value | DR6_FIXED_1;
+return;
+case 7:
+windbg_set_dr7(cpu, value);
+return;
+}
+}
+
 static void windbg_set_sr(CPUState *cpu, int sr, uint16_t selector)
 {
 CPUArchState *env = cpu->env_ptr;




[Qemu-devel] [PATCH v4 27/46] windbg: implemented windbg_read_ks_regs

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |   39 +++
 1 file changed, 39 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 6272a1341d..da7d1eae0c 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -600,6 +600,45 @@ static int windbg_write_context(CPUState *cpu, uint8_t 
*buf, int buf_size,
 static int windbg_read_ks_regs(CPUState *cpu, uint8_t *buf, int buf_size,
int offset, int len)
 {
+CPUArchState *env = cpu->env_ptr;
+CPU_KSPECIAL_REGISTERS *ckr;
+bool new_mem;
+
+new_mem = (len != sizeof(CPU_KSPECIAL_REGISTERS) || offset != 0);
+if (new_mem) {
+ckr = g_new(CPU_KSPECIAL_REGISTERS, 1);
+} else {
+ckr = (CPU_KSPECIAL_REGISTERS *) buf;
+}
+
+memset(ckr, 0, len);
+
+ckr->Cr0 = ldl_p(>cr[0]);
+ckr->Cr2 = ldl_p(>cr[2]);
+ckr->Cr3 = ldl_p(>cr[3]);
+ckr->Cr4 = ldl_p(>cr[4]);
+
+ckr->KernelDr0 = ldtul_p(>dr[0]);
+ckr->KernelDr1 = ldtul_p(>dr[1]);
+ckr->KernelDr2 = ldtul_p(>dr[2]);
+ckr->KernelDr3 = ldtul_p(>dr[3]);
+ckr->KernelDr6 = ldtul_p(>dr[6]);
+ckr->KernelDr7 = ldtul_p(>dr[7]);
+
+ckr->Gdtr.Pad = lduw_p(>gdt.selector);
+ckr->Idtr.Pad = lduw_p(>idt.selector);
+
+ckr->Gdtr.Limit = lduw_p(>gdt.limit);
+ckr->Gdtr.Base  = ldtul_p(>gdt.base);
+ckr->Idtr.Limit = lduw_p(>idt.limit);
+ckr->Idtr.Base  = ldtul_p(>idt.base);
+ckr->Tr = lduw_p(>tr.selector);
+ckr->Ldtr   = lduw_p(>ldt.selector);
+
+if (new_mem) {
+memcpy(buf, (uint8_t *) ckr + offset, len);
+g_free(ckr);
+}
 return 0;
 }
 




[Qemu-devel] [PATCH v4 34/46] windbg: debug exception subscribing

2017-12-11 Thread Mihail Abakumov
Added handler registration of gdb debug exception. Its exception also can be 
used for windbg.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 cpus.c  |   19 ++-
 gdbstub.c   |4 
 include/sysemu/sysemu.h |2 ++
 windbgstub.c|   16 
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/cpus.c b/cpus.c
index 9bed61eefc..498b7e1dd9 100644
--- a/cpus.c
+++ b/cpus.c
@@ -77,6 +77,8 @@ int64_t max_advance;
 static QEMUTimer *throttle_timer;
 static unsigned int throttle_percentage;
 
+static void (*excp_debug_handler)(CPUState *cpu);
+
 #define CPU_THROTTLE_PCT_MIN 1
 #define CPU_THROTTLE_PCT_MAX 99
 #define CPU_THROTTLE_TIMESLICE_NS 1000
@@ -960,9 +962,24 @@ static bool cpu_can_run(CPUState *cpu)
 return true;
 }
 
+bool register_excp_debug_handler(void (*handler)(CPUState *cpu))
+{
+if (excp_debug_handler == NULL) {
+excp_debug_handler = handler;
+return true;
+} else {
+error_report("Something debugger is already in use. '-gdb' and "
+ "'-windbg' cannot be used at the same time");
+return false;
+}
+}
+
 static void cpu_handle_guest_debug(CPUState *cpu)
 {
-gdb_set_stop_cpu(cpu);
+if (excp_debug_handler != NULL) {
+excp_debug_handler(cpu);
+}
+
 qemu_system_debug_request();
 cpu->stopped = true;
 }
diff --git a/gdbstub.c b/gdbstub.c
index 2a94030d3b..8c76f54117 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2006,6 +2006,10 @@ int gdbserver_start(const char *device)
 s->mon_chr = mon_chr;
 s->current_syscall_cb = NULL;
 
+if (!register_excp_debug_handler(gdb_set_stop_cpu)) {
+exit(1);
+}
+
 return 0;
 }
 
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index b21369672a..34588c99b4 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -193,6 +193,8 @@ QemuOpts *qemu_get_machine_opts(void);
 
 bool defaults_enabled(void);
 
+bool register_excp_debug_handler(void (*handler)(CPUState *cpu));
+
 extern QemuOptsList qemu_legacy_drive_opts;
 extern QemuOptsList qemu_common_drive_opts;
 extern QemuOptsList qemu_drive_opts;
diff --git a/windbgstub.c b/windbgstub.c
index a534fe170b..d3c1317255 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -115,16 +115,20 @@ static void windbg_send_control_packet(uint16_t type)
 windbg_state->ctrl_packet_id ^= 1;
 }
 
-static void windbg_vm_stop(void)
+static void windbg_bp_handler(CPUState *cpu)
 {
-CPUState *cpu = qemu_get_cpu(0);
-vm_stop(RUN_STATE_PAUSED);
-
 SizedBuf buf = kd_gen_exception_sc(cpu);
 windbg_send_data_packet(buf.data, buf.size, PACKET_TYPE_KD_STATE_CHANGE64);
 g_free(buf.data);
 }
 
+static void windbg_vm_stop(void)
+{
+CPUState *cpu = qemu_get_cpu(0);
+vm_stop(RUN_STATE_PAUSED);
+windbg_bp_handler(cpu);
+}
+
 static void windbg_process_manipulate_packet(ParsingContext *ctx)
 {
 CPUState *cpu;
@@ -432,6 +436,10 @@ int windbg_server_start(const char *device)
 
 qemu_register_reset(windbg_handle_reset, NULL);
 
+if (!register_excp_debug_handler(windbg_bp_handler)) {
+exit(1);
+}
+
 atexit(windbg_exit);
 return 0;
 }




[Qemu-devel] [PATCH v4 31/46] windbg: implemented windbg_set_dr7

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |   27 ++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index cae827df50..6e167a7473 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -299,7 +299,32 @@ static int windbg_hw_breakpoint_remove(CPUState *cpu, int 
index)
 }
 
 static void windbg_set_dr7(CPUState *cpu, target_ulong new_dr7)
-{}
+{
+CPUArchState *env = cpu->env_ptr;
+target_ulong old_dr7 = env->dr[7];
+int iobpt = 0;
+int i;
+
+new_dr7 |= DR7_FIXED_1;
+if (new_dr7 == old_dr7) {
+return;
+}
+
+for (i = 0; i < DR7_MAX_BP; i++) {
+if (IS_BP_ENABLED(old_dr7, i) && !IS_BP_ENABLED(new_dr7, i)) {
+windbg_hw_breakpoint_remove(cpu, i);
+}
+}
+
+env->dr[7] = new_dr7;
+for (i = 0; i < DR7_MAX_BP; i++) {
+if (IS_BP_ENABLED(env->dr[7], i)) {
+iobpt |= windbg_hw_breakpoint_insert(cpu, i);
+}
+}
+
+env->hflags = (env->hflags & ~HF_IOBPT_MASK) | iobpt;
+}
 
 static void windbg_set_dr(CPUState *cpu, int index, target_ulong value)
 {




[Qemu-devel] [PATCH v4 18/46] windbg: implemented windbg_process_control_packet

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   26 +-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/windbgstub.c b/windbgstub.c
index 6eb9517e24..07a1815b79 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -129,7 +129,31 @@ static void windbg_process_data_packet(ParsingContext *ctx)
 {}
 
 static void windbg_process_control_packet(ParsingContext *ctx)
-{}
+{
+switch (ctx->packet.PacketType) {
+case PACKET_TYPE_KD_ACKNOWLEDGE:
+break;
+
+case PACKET_TYPE_KD_RESET:
+{
+SizedBuf buf = kd_gen_load_symbols_sc(qemu_get_cpu(0));
+windbg_send_data_packet(buf.data, buf.size,
+PACKET_TYPE_KD_STATE_CHANGE64);
+g_free(buf.data);
+
+windbg_send_control_packet(ctx->packet.PacketType);
+windbg_state->ctrl_packet_id = INITIAL_PACKET_ID;
+break;
+}
+default:
+WINDBG_ERROR("Caught unsupported control packet 0x%x",
+ ctx->packet.PacketType);
+
+windbg_state->ctrl_packet_id = 0;
+windbg_send_control_packet(PACKET_TYPE_KD_RESEND);
+break;
+}
+}
 
 static void windbg_ctx_handler(ParsingContext *ctx)
 {




[Qemu-devel] [PATCH v4 26/46] windbg: implemented windbg_write_context

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |  216 ++
 1 file changed, 216 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index de3ffd78b0..6272a1341d 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -273,6 +273,12 @@ typedef struct _CPU_KPROCESSOR_STATE {
 CPU_KSPECIAL_REGISTERS SpecialRegisters;
 } CPU_KPROCESSOR_STATE, *PCPU_KPROCESSOR_STATE;
 
+static void windbg_set_dr(CPUState *cpu, int index, target_ulong value)
+{}
+
+static void windbg_set_sr(CPUState *cpu, int sr, uint16_t selector)
+{}
+
 static int windbg_read_context(CPUState *cpu, uint8_t *buf, int buf_size,
int offset, int len)
 {
@@ -378,6 +384,216 @@ static int windbg_read_context(CPUState *cpu, uint8_t 
*buf, int buf_size,
 static int windbg_write_context(CPUState *cpu, uint8_t *buf, int buf_size,
 int offset, int len)
 {
+CPUArchState *env = cpu->env_ptr;
+int mem_size, i, tmp;
+uint8_t *mem_ptr = buf;
+
+if (len < 0 || len > buf_size) {
+WINDBG_ERROR("windbg_write_context: incorrect length %d", len);
+return 1;
+}
+
+if (offset < 0 || offset + len > sizeof(CPU_CONTEXT)) {
+WINDBG_ERROR("windbg_write_context: incorrect offset %d", offset);
+return 2;
+}
+
+while (len > 0 && offset < sizeof(CPU_CONTEXT)) {
+mem_size = 1;
+switch (offset) {
+
+case offsetof(CPU_CONTEXT, ContextFlags):
+mem_size = sizeof_field(CPU_CONTEXT, ContextFlags);
+break;
+
+case offsetof(CPU_CONTEXT, Dr0):
+mem_size = sizeof_field(CPU_CONTEXT, Dr0);
+windbg_set_dr(cpu, 0, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr1):
+mem_size = sizeof_field(CPU_CONTEXT, Dr1);
+windbg_set_dr(cpu, 1, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr2):
+mem_size = sizeof_field(CPU_CONTEXT, Dr2);
+windbg_set_dr(cpu, 2, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr3):
+mem_size = sizeof_field(CPU_CONTEXT, Dr3);
+windbg_set_dr(cpu, 3, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr6):
+mem_size = sizeof_field(CPU_CONTEXT, Dr6);
+windbg_set_dr(cpu, 6, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr7):
+mem_size = sizeof_field(CPU_CONTEXT, Dr7);
+windbg_set_dr(cpu, 7, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.ControlWord):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.ControlWord);
+cpu_set_fpuc(env, ldl_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.StatusWord):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.StatusWord);
+tmp = ldl_p(buf + offset);
+env->fpstt = (tmp >> 11) & 7;
+env->fpus = tmp & ~0x3800;
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.TagWord):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.TagWord);
+tmp = ldl_p(buf + offset);
+for (i = 0; i < 8; ++i) {
+env->fptags[i] = !((tmp >> i) & 1);
+}
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.ErrorOffset):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.ErrorOffset);
+env->fpip &= ~0xL;
+env->fpip |= ldl_p(buf + offset);
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.ErrorSelector):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.ErrorSelector);
+env->fpip &= 0xL;
+env->fpip |= ((uint64_t) ldl_p(buf + offset)) << 32;
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.DataOffset):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.DataOffset);
+env->fpdp &= ~0xL;
+env->fpdp |= ldl_p(buf + offset);
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.DataSelector):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.DataSelector);
+env->fpdp &= 0xL;
+env->fpdp |= ((uint64_t) ldl_p(buf + offset)) << 32;
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.RegisterArea):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.RegisterArea);
+for (i = 0; i < 8; ++i) {
+memcpy(PTR(

[Qemu-devel] [PATCH v4 32/46] windbg: implemented windbg_hw_breakpoint_insert and windbg_hw_breakpoint_remove

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |   56 ++
 1 file changed, 56 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 6e167a7473..5e094e81d7 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -290,11 +290,67 @@ typedef struct _CPU_KPROCESSOR_STATE {
 
 static int windbg_hw_breakpoint_insert(CPUState *cpu, int index)
 {
+CPUArchState *env = cpu->env_ptr;
+
+target_ulong addr = env->dr[index];
+int type = BP_TYPE(env->dr[7], index);
+int len = BP_LEN(env->dr[7], index);
+int err = 0;
+
+switch (type) {
+case DR7_TYPE_DATA_WR:
+err = cpu_watchpoint_insert(cpu, addr, len, BP_MEM_WRITE | BP_GDB,
+>cpu_watchpoint[index]);
+break;
+case DR7_TYPE_DATA_RW:
+err = cpu_watchpoint_insert(cpu, addr, len, BP_MEM_ACCESS | BP_GDB,
+>cpu_watchpoint[index]);
+break;
+case DR7_TYPE_BP_INST:
+err = cpu_breakpoint_insert(cpu, addr, BP_GDB,
+>cpu_breakpoint[index]);
+break;
+case DR7_TYPE_IO_RW:
+return HF_IOBPT_MASK;
+default:
+return 0;
+}
+
+if (!err) {
+WINDBG_DEBUG("hw_breakpoint_insert: index(%d), " FMT_ADDR,
+ index, addr);
+} else {
+env->cpu_breakpoint[index] = NULL;
+WINDBG_ERROR("hw_breakpoint_insert: index(%d), " FMT_ADDR ", " FMT_ERR,
+ index, addr, err);
+}
 return 0;
 }
 
 static int windbg_hw_breakpoint_remove(CPUState *cpu, int index)
 {
+CPUArchState *env = cpu->env_ptr;
+int type = BP_TYPE(env->dr[7], index);
+
+switch (type) {
+case DR7_TYPE_BP_INST:
+if (env->cpu_breakpoint[index]) {
+cpu_breakpoint_remove_by_ref(cpu, env->cpu_breakpoint[index]);
+}
+break;
+case DR7_TYPE_DATA_WR:
+case DR7_TYPE_DATA_RW:
+if (env->cpu_watchpoint[index]) {
+cpu_watchpoint_remove_by_ref(cpu, env->cpu_watchpoint[index]);
+}
+break;
+default:
+return 0;
+}
+
+env->cpu_breakpoint[index] = NULL;
+WINDBG_DEBUG("hw_breakpoint_remove: index(%d), " FMT_ADDR,
+ index, env->dr[index]);
 return 0;
 }
 




[Qemu-devel] [PATCH v4 20/46] windbg: implemented windbg_process_manipulate_packet

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 ++
 windbgstub-utils.c  |8 
 windbgstub.c|   26 +-
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index a7ec53555b..51977b46c7 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -74,6 +74,8 @@ typedef struct PacketData {
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
+void kd_api_unsupported(CPUState *cpu, PacketData *pd);
+
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
 SizedBuf kd_gen_load_symbols_sc(CPUState *cpu);
 
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 347c61553a..04a7e1cc7b 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -23,3 +23,11 @@ InitedAddr *windbg_get_version(void)
 {
 return 
 }
+
+void kd_api_unsupported(CPUState *cpu, PacketData *pd)
+{
+WINDBG_ERROR("Caught unimplemented api %s",
+ KD_API_NAME(pd->m64.ApiNumber));
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+pd->extra_size = 0;
+}
diff --git a/windbgstub.c b/windbgstub.c
index cd46649278..a798186930 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -126,7 +126,31 @@ static void windbg_vm_stop(void)
 }
 
 static void windbg_process_manipulate_packet(ParsingContext *ctx)
-{}
+{
+CPUState *cpu;
+
+ctx->data.extra_size = ctx->packet.ByteCount -
+   sizeof(DBGKD_MANIPULATE_STATE64);
+ctx->data.m64.ReturnStatus = STATUS_SUCCESS;
+
+cpu = qemu_get_cpu(ctx->data.m64.Processor);
+if (cpu == NULL) {
+cpu = qemu_get_cpu(0);
+}
+
+switch (ctx->data.m64.ApiNumber) {
+
+default:
+kd_api_unsupported(cpu, >data);
+break;
+}
+
+stl_p(>data.m64.ReturnStatus, ctx->data.m64.ReturnStatus);
+
+windbg_send_data_packet(ctx->data.buf, ctx->data.extra_size +
+sizeof(DBGKD_MANIPULATE_STATE64),
+ctx->packet.PacketType);
+}
 
 static void windbg_process_data_packet(ParsingContext *ctx)
 {




[Qemu-devel] [PATCH v4 15/46] windbg: generate ExceptionStateChange

2017-12-11 Thread Mihail Abakumov
Added function for generate ExceptionStateChange packet.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 ++
 target/i386/windbgstub.c|   21 -
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 830d01314e..d9dae4e902 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -74,6 +74,8 @@ typedef struct PacketData {
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
+SizedBuf kd_gen_exception_sc(CPUState *cpu);
+
 bool windbg_on_load(void);
 
 #endif
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index a3c433f756..5db6a5e3bc 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -70,7 +70,6 @@ bool windbg_on_load(void)
 return true;
 }
 
-__attribute__ ((unused)) /* unused yet */
 static void kd_init_state_change(CPUState *cpu,
  DBGKD_ANY_WAIT_STATE_CHANGE *sc)
 {
@@ -115,4 +114,24 @@ static void kd_init_state_change(CPUState *cpu,
 }
 }
 
+SizedBuf kd_gen_exception_sc(CPUState *cpu)
+{
+CPUArchState *env = cpu->env_ptr;
+DBGKD_ANY_WAIT_STATE_CHANGE *sc;
+DBGKM_EXCEPTION_RECORD64 *exc;
+SizedBuf buf;
+
+buf.size = sizeof(DBGKD_ANY_WAIT_STATE_CHANGE) + sizeof(int);
+buf.data = g_malloc0(buf.size);
+sc = (DBGKD_ANY_WAIT_STATE_CHANGE *) buf.data;
+exc = >u.Exception.ExceptionRecord;
+kd_init_state_change(cpu, sc);
+
+stl_p(>NewState, DbgKdExceptionStateChange);
+stl_p(>ExceptionCode, 0x8003);
+sttul_p(>ExceptionAddress, env->eip);
+
+return buf;
+}
+
 #endif




[Qemu-devel] [PATCH v4 24/46] windbg: implemented kd_api_read_control_space and kd_api_write_control_space

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 +
 target/i386/windbgstub.c|   89 +++
 windbgstub.c|8 
 3 files changed, 99 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index d4efabba0b..e04bd59d46 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -78,6 +78,8 @@ void kd_api_read_virtual_memory(CPUState *cpu, PacketData 
*pd);
 void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd);
 void kd_api_get_context(CPUState *cpu, PacketData *pd);
 void kd_api_set_context(CPUState *cpu, PacketData *pd);
+void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
+void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 7558349469..f72d164bb5 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -285,6 +285,18 @@ static int windbg_write_context(CPUState *cpu, uint8_t 
*buf, int buf_size,
 return 0;
 }
 
+static int windbg_read_ks_regs(CPUState *cpu, uint8_t *buf, int buf_size,
+   int offset, int len)
+{
+return 0;
+}
+
+static int windbg_write_ks_regs(CPUState *cpu, uint8_t *buf, int buf_size,
+int offset, int len)
+{
+return 0;
+}
+
 void kd_api_get_context(CPUState *cpu, PacketData *pd)
 {
 int err;
@@ -312,6 +324,83 @@ void kd_api_set_context(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_read_control_space(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_MEMORY64 *mem = >m64.u.ReadMemory;
+uint32_t len;
+uint32_t context_len;
+uint32_t ks_regs_len;
+target_ulong addr;
+int err = -1;
+
+len = MIN(ldl_p(>TransferCount),
+  PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+addr = ldtul_p(>TargetBaseAddress);
+
+if (addr < sizeof(CPU_KPROCESSOR_STATE)) {
+len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - addr);
+
+context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - addr));
+ks_regs_len = len - context_len;
+
+if (context_len > 0) {
+err = windbg_read_context(cpu, pd->extra, context_len, addr,
+  context_len);
+}
+if (ks_regs_len > 0) {
+addr = addr - sizeof(CPU_CONTEXT) + context_len;
+err = windbg_read_ks_regs(cpu, pd->extra + context_len,
+  ks_regs_len, addr, ks_regs_len);
+}
+}
+
+if (err) {
+len = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+
+pd->extra_size = len;
+stl_p(>ActualBytesRead, len);
+}
+
+void kd_api_write_control_space(CPUState *cpu, PacketData *pd)
+{
+DBGKD_WRITE_MEMORY64 *mem = >m64.u.WriteMemory;
+uint32_t len;
+uint32_t context_len;
+uint32_t ks_regs_len;
+target_ulong addr;
+int err = -1;
+
+len = MIN(ldl_p(>TransferCount), pd->extra_size);
+addr = ldtul_p(>TargetBaseAddress);
+
+if (addr < sizeof(CPU_KPROCESSOR_STATE)) {
+len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - addr);
+
+context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - addr));
+ks_regs_len = len - context_len;
+
+if (context_len > 0) {
+err = windbg_write_context(cpu, pd->extra, context_len, addr,
+   context_len);
+}
+if (ks_regs_len > 0) {
+addr = addr - sizeof(CPU_CONTEXT) + context_len;
+err = windbg_write_ks_regs(cpu, pd->extra + context_len,
+   ks_regs_len, addr, ks_regs_len);
+}
+}
+
+if (err) {
+mem->ActualBytesWritten = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+
+pd->extra_size = 0;
+stl_p(>ActualBytesWritten, len);
+}
+
 bool windbg_on_load(void)
 {
 CPUState *cpu = qemu_get_cpu(0);
diff --git a/windbgstub.c b/windbgstub.c
index be40e3e53b..53a7e75683 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -156,6 +156,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_set_context(cpu, >data);
 break;
 
+case DbgKdReadControlSpaceApi:
+kd_api_read_control_space(cpu, >data);
+break;
+
+case DbgKdWriteControlSpaceApi:
+kd_api_write_control_space(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v4 29/46] windbg: implemented windbg_set_sr

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |   17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 25a0ee8a66..2a09cec9d8 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -277,7 +277,22 @@ static void windbg_set_dr(CPUState *cpu, int index, 
target_ulong value)
 {}
 
 static void windbg_set_sr(CPUState *cpu, int sr, uint16_t selector)
-{}
+{
+CPUArchState *env = cpu->env_ptr;
+
+if (selector != env->segs[sr].selector &&
+(!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK))) {
+unsigned int limit, flags;
+target_ulong base;
+
+int dpl = (env->eflags & VM_MASK) ? 3 : 0;
+base = selector << 4;
+limit = 0x;
+flags = DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+DESC_A_MASK | (dpl << DESC_DPL_SHIFT);
+cpu_x86_load_seg_cache(env, sr, selector, base, limit, flags);
+}
+}
 
 static int windbg_read_context(CPUState *cpu, uint8_t *buf, int buf_size,
int offset, int len)




[Qemu-devel] [PATCH v4 14/46] windbg: init DBGKD_ANY_WAIT_STATE_CHANGE

2017-12-11 Thread Mihail Abakumov
Added function for init DBGKD_ANY_WAIT_STATE_CHANGE. It is a header of 'state 
change' packets.


Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |8 ++
 target/i386/windbgstub.c|   49 +++
 2 files changed, 57 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index b7e65faefe..830d01314e 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -42,6 +42,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 SizedBuf {
 uint8_t *data;
 size_t size;
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 47ee5840ef..a3c433f756 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -17,9 +17,13 @@
 #ifdef TARGET_X86_64
 # define OFFSET_SELF_PCR 0x18
 # define OFFSET_VERS 0x108
+# define OFFSET_KPRCB0x20
+# define OFFSET_KPRCB_CURRTHREAD 0x8
 #else
 # define OFFSET_SELF_PCR 0x1C
 # define OFFSET_VERS 0x34
+# define OFFSET_KPRCB0x20
+# define OFFSET_KPRCB_CURRTHREAD 0x4
 #endif
 
 bool windbg_on_load(void)
@@ -66,4 +70,49 @@ bool windbg_on_load(void)
 return true;
 }
 
+__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 = >ControlReport;
+InitedAddr *KPCR = windbg_get_KPCR();
+target_ulong KPRCB;
+int err = 0;
+
+/* T0D0: HEADER */
+
+sc->Processor = 0;
+
+sc->NumberProcessors = 0;
+CPUState *cpu_tmp;
+CPU_FOREACH(cpu_tmp) {
+sc->NumberProcessors++;
+}
+stl_p(>NumberProcessors, sc->NumberProcessors);
+
+KPRCB = READ_VMEM(cpu, KPCR->addr + OFFSET_KPRCB, target_ulong);
+sc->Thread = READ_VMEM(cpu, KPRCB + OFFSET_KPRCB_CURRTHREAD, target_ulong);
+sttul_p(>Thread, sc->Thread);
+sttul_p(>ProgramCounter, env->eip);
+
+/* T0D0: CONTROL REPORT */
+
+sttul_p(>Dr6, env->dr[6]);
+sttul_p(>Dr7, env->dr[7]);
+stw_p(>ReportFlags, REPORT_INCLUDES_SEGS | REPORT_STANDARD_CS);
+stw_p(>SegCs, env->segs[R_CS].selector);
+stw_p(>SegDs, env->segs[R_DS].selector);
+stw_p(>SegEs, env->segs[R_ES].selector);
+stw_p(>SegFs, env->segs[R_FS].selector);
+stl_p(>EFlags, env->eflags);
+
+err = cpu_memory_rw_debug(cpu, sc->ProgramCounter,
+  PTR(cr->InstructionStream[0]),
+  DBGKD_MAXSTREAM, 0);
+if (!err) {
+stw_p(>InstructionCount, DBGKD_MAXSTREAM);
+}
+}
+
 #endif




[Qemu-devel] [PATCH v4 19/46] windbg: implemented windbg_process_data_packet

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/windbgstub.c b/windbgstub.c
index 07a1815b79..cd46649278 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -125,9 +125,27 @@ static void windbg_vm_stop(void)
 g_free(buf.data);
 }
 
-static void windbg_process_data_packet(ParsingContext *ctx)
+static void windbg_process_manipulate_packet(ParsingContext *ctx)
 {}
 
+static void windbg_process_data_packet(ParsingContext *ctx)
+{
+switch (ctx->packet.PacketType) {
+case PACKET_TYPE_KD_STATE_MANIPULATE:
+windbg_send_control_packet(PACKET_TYPE_KD_ACKNOWLEDGE);
+windbg_process_manipulate_packet(ctx);
+break;
+
+default:
+WINDBG_ERROR("Caught unsupported data packet 0x%x",
+ ctx->packet.PacketType);
+
+windbg_state->ctrl_packet_id = 0;
+windbg_send_control_packet(PACKET_TYPE_KD_RESEND);
+break;
+}
+}
+
 static void windbg_process_control_packet(ParsingContext *ctx)
 {
 switch (ctx->packet.PacketType) {




[Qemu-devel] [PATCH v4 23/46] windbg: implemented kd_api_get_context and kd_api_set_context

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 ++
 target/i386/windbgstub.c|   39 +++
 windbgstub.c|8 
 3 files changed, 49 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 1cee2aed18..d4efabba0b 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -76,6 +76,8 @@ InitedAddr *windbg_get_version(void);
 
 void kd_api_read_virtual_memory(CPUState *cpu, PacketData *pd);
 void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd);
+void kd_api_get_context(CPUState *cpu, PacketData *pd);
+void kd_api_set_context(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 11c35a4207..7558349469 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -273,6 +273,45 @@ typedef struct _CPU_KPROCESSOR_STATE {
 CPU_KSPECIAL_REGISTERS SpecialRegisters;
 } CPU_KPROCESSOR_STATE, *PCPU_KPROCESSOR_STATE;
 
+static int windbg_read_context(CPUState *cpu, uint8_t *buf, int buf_size,
+   int offset, int len)
+{
+return 0;
+}
+
+static int windbg_write_context(CPUState *cpu, uint8_t *buf, int buf_size,
+int offset, int len)
+{
+return 0;
+}
+
+void kd_api_get_context(CPUState *cpu, PacketData *pd)
+{
+int err;
+
+pd->extra_size = sizeof(CPU_CONTEXT);
+err = windbg_read_context(cpu, pd->extra, pd->extra_size, 0,
+  pd->extra_size);
+
+if (err) {
+pd->extra_size = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+}
+
+void kd_api_set_context(CPUState *cpu, PacketData *pd)
+{
+int err;
+
+err = windbg_write_context(cpu, pd->extra, pd->extra_size, 0,
+   sizeof(CPU_CONTEXT));
+pd->extra_size = 0;
+
+if (err) {
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+}
+
 bool windbg_on_load(void)
 {
 CPUState *cpu = qemu_get_cpu(0);
diff --git a/windbgstub.c b/windbgstub.c
index 14caacef81..be40e3e53b 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -148,6 +148,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_write_virtual_memory(cpu, >data);
 break;
 
+case DbgKdGetContextApi:
+kd_api_get_context(cpu, >data);
+break;
+
+case DbgKdSetContextApi:
+kd_api_set_context(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v4 28/46] windbg: implemented windbg_write_ks_regs

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |  111 ++
 1 file changed, 111 insertions(+)

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;
 }
 




[Qemu-devel] [PATCH v4 21/46] windbg: implemented kd_api_read_virtual_memory and kd_api_write_virtual_memory

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 ++
 windbgstub-utils.c  |   47 +++
 windbgstub.c|8 +++
 3 files changed, 57 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 51977b46c7..1cee2aed18 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -74,6 +74,8 @@ typedef struct PacketData {
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
+void kd_api_read_virtual_memory(CPUState *cpu, PacketData *pd);
+void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 04a7e1cc7b..1e81c37501 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -24,6 +24,53 @@ InitedAddr *windbg_get_version(void)
 return 
 }
 
+void kd_api_read_virtual_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_MEMORY64 *mem = >m64.u.ReadMemory;
+uint32_t len;
+target_ulong addr;
+int err;
+
+len = MIN(ldl_p(>TransferCount),
+PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+addr = ldtul_p(>TargetBaseAddress);
+err = cpu_memory_rw_debug(cpu, addr, pd->extra, len, 0);
+
+if (err) {
+len = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+
+WINDBG_DEBUG("read_virtual_memory: No physical page mapped: " FMT_ADDR,
+ (target_ulong) mem->TargetBaseAddress);
+}
+
+pd->extra_size = len;
+stl_p(>ActualBytesRead, len);
+}
+
+void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_WRITE_MEMORY64 *mem = >m64.u.WriteMemory;
+uint32_t len;
+target_ulong addr;
+int err;
+
+len = MIN(ldl_p(>TransferCount), pd->extra_size);
+addr = ldtul_p(>TargetBaseAddress);
+err = cpu_memory_rw_debug(cpu, addr, pd->extra, len, 1);
+
+if (err) {
+len = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+
+WINDBG_DEBUG("read_write_memory: No physical page mapped: " FMT_ADDR,
+ (target_ulong) mem->TargetBaseAddress);
+}
+
+pd->extra_size = 0;
+stl_p(>ActualBytesWritten, len);
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index a798186930..14caacef81 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -140,6 +140,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 
 switch (ctx->data.m64.ApiNumber) {
 
+case DbgKdReadVirtualMemoryApi:
+kd_api_read_virtual_memory(cpu, >data);
+break;
+
+case DbgKdWriteVirtualMemoryApi:
+kd_api_write_virtual_memory(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v4 17/46] windbg: windbg_vm_stop

2017-12-11 Thread Mihail Abakumov
Added function for stop vm. Also, ExceptionStateChange data is generated and 
sent here.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/windbgstub.c b/windbgstub.c
index b71449e369..6eb9517e24 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -71,7 +71,6 @@ static uint32_t compute_checksum(uint8_t *data, uint16_t len)
 return checksum;
 }
 
-__attribute__ ((unused)) /* unused yet */
 static void windbg_send_data_packet(uint8_t *data, uint16_t byte_count,
 uint16_t type)
 {
@@ -116,6 +115,16 @@ static void windbg_send_control_packet(uint16_t type)
 windbg_state->ctrl_packet_id ^= 1;
 }
 
+static void windbg_vm_stop(void)
+{
+CPUState *cpu = qemu_get_cpu(0);
+vm_stop(RUN_STATE_PAUSED);
+
+SizedBuf buf = kd_gen_exception_sc(cpu);
+windbg_send_data_packet(buf.data, buf.size, PACKET_TYPE_KD_STATE_CHANGE64);
+g_free(buf.data);
+}
+
 static void windbg_process_data_packet(ParsingContext *ctx)
 {}
 
@@ -129,7 +138,7 @@ static void windbg_ctx_handler(ParsingContext *ctx)
 break;
 
 case RESULT_BREAKIN_BYTE:
-vm_stop(RUN_STATE_PAUSED);
+windbg_vm_stop();
 break;
 
 case RESULT_CONTROL_PACKET:




[Qemu-devel] [PATCH v4 12/46] windbg: send data and control packets

2017-12-11 Thread Mihail Abakumov
Added functions for send data and control packets to windbg.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   56 
 1 file changed, 56 insertions(+)

diff --git a/windbgstub.c b/windbgstub.c
index ace992e2cb..8c33e0de0a 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -60,6 +60,62 @@ typedef struct WindbgState {
 
 static WindbgState *windbg_state;
 
+static uint32_t compute_checksum(uint8_t *data, uint16_t len)
+{
+uint32_t checksum = 0;
+while (len) {
+--len;
+checksum += *data++;
+}
+return checksum;
+}
+
+__attribute__ ((unused)) /* unused yet */
+static void windbg_send_data_packet(uint8_t *data, uint16_t byte_count,
+uint16_t type)
+{
+uint8_t trailing_byte = PACKET_TRAILING_BYTE;
+
+KD_PACKET packet = {
+.PacketLeader = PACKET_LEADER,
+.PacketType = type,
+.ByteCount = byte_count,
+.PacketId = windbg_state->data_packet_id,
+.Checksum = compute_checksum(data, byte_count)
+};
+
+stw_p(, packet.PacketType);
+stw_p(, packet.ByteCount);
+stl_p(, packet.PacketId);
+stl_p(, packet.Checksum);
+
+qemu_chr_fe_write(_state->chr, PTR(packet), sizeof(packet));
+qemu_chr_fe_write(_state->chr, data, byte_count);
+qemu_chr_fe_write(_state->chr, _byte,
+  sizeof(trailing_byte));
+
+windbg_state->data_packet_id ^= 1;
+}
+
+__attribute__ ((unused)) /* unused yet */
+static void windbg_send_control_packet(uint16_t type)
+{
+KD_PACKET packet = {
+.PacketLeader = CONTROL_PACKET_LEADER,
+.PacketType = type,
+.ByteCount = 0,
+.PacketId = windbg_state->ctrl_packet_id,
+.Checksum = 0
+};
+
+stw_p(, packet.PacketType);
+stl_p(, packet.PacketId);
+
+qemu_chr_fe_write(_state->chr, PTR(packet), sizeof(packet));
+
+windbg_state->ctrl_packet_id ^= 1;
+}
+
 static void windbg_ctx_handler(ParsingContext *ctx)
 {}
 




[Qemu-devel] [PATCH v4 25/46] windbg: implemented windbg_read_context

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |   96 ++
 1 file changed, 96 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index f72d164bb5..de3ffd78b0 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -276,6 +276,102 @@ typedef struct _CPU_KPROCESSOR_STATE {
 static int windbg_read_context(CPUState *cpu, uint8_t *buf, int buf_size,
int offset, int len)
 {
+CPUArchState *env = cpu->env_ptr;
+CPU_CONTEXT *cc;
+bool new_mem;
+
+if (len < 0 || len > buf_size) {
+WINDBG_ERROR("windbg_read_context: incorrect length %d", len);
+return 1;
+}
+
+if (offset < 0 || offset + len > sizeof(CPU_CONTEXT)) {
+WINDBG_ERROR("windbg_read_context: incorrect offset %d", offset);
+return 2;
+}
+
+new_mem = len != sizeof(CPU_CONTEXT) || offset != 0;
+if (new_mem) {
+cc = g_new0(CPU_CONTEXT, 1);
+} else {
+cc = (CPU_CONTEXT *) buf;
+memset(cc, 0, sizeof(CPU_CONTEXT));
+}
+
+cc->ContextFlags = CPU_CONTEXT_ALL;
+
+if (cc->ContextFlags & CPU_CONTEXT_SEGMENTS) {
+stw_p(>SegCs, env->segs[R_CS].selector);
+stw_p(>SegDs, env->segs[R_DS].selector);
+stw_p(>SegEs, env->segs[R_ES].selector);
+stw_p(>SegFs, env->segs[R_FS].selector);
+stw_p(>SegGs, env->segs[R_GS].selector);
+stw_p(>SegSs, env->segs[R_SS].selector);
+}
+
+if (cc->ContextFlags & CPU_CONTEXT_DEBUG_REGISTERS) {
+sttul_p(>Dr0, env->dr[0]);
+sttul_p(>Dr1, env->dr[1]);
+sttul_p(>Dr2, env->dr[2]);
+sttul_p(>Dr3, env->dr[3]);
+sttul_p(>Dr6, env->dr[6]);
+sttul_p(>Dr7, env->dr[7]);
+}
+
+if (cc->ContextFlags & CPU_CONTEXT_INTEGER) {
+stl_p(>Edi, env->regs[R_EDI]);
+stl_p(>Esi, env->regs[R_ESI]);
+stl_p(>Ebx, env->regs[R_EBX]);
+stl_p(>Edx, env->regs[R_EDX]);
+stl_p(>Ecx, env->regs[R_ECX]);
+stl_p(>Eax, env->regs[R_EAX]);
+stl_p(>Ebp, env->regs[R_EBP]);
+stl_p(>Esp, env->regs[R_ESP]);
+stl_p(>Eip, env->eip);
+stl_p(>EFlags, env->eflags);
+}
+
+if (cc->ContextFlags & CPU_CONTEXT_FLOATING_POINT) {
+uint32_t swd = 0, twd = 0;
+swd = env->fpus & ~(7 << 11);
+swd |= (env->fpstt & 7) << 11;
+int i;
+for (i = 0; i < 8; ++i) {
+twd |= (!env->fptags[i]) << i;
+}
+
+stl_p(>FloatSave.ControlWord, env->fpuc);
+stl_p(>FloatSave.StatusWord, swd);
+stl_p(>FloatSave.TagWord, twd);
+stl_p(>FloatSave.ErrorOffset, env->fpip & 0x);
+stl_p(>FloatSave.ErrorSelector, (env->fpip >> 32) & 0x);
+stl_p(>FloatSave.DataOffset, env->fpdp & 0x);
+stl_p(>FloatSave.DataSelector, (env->fpdp >> 32) & 0x);
+stl_p(>FloatSave.Cr0NpxState, env->xcr0);
+
+for (i = 0; i < 8; ++i) {
+memcpy(PTR(cc->FloatSave.RegisterArea[i * 10]),
+   PTR(env->fpregs[i]), 10);
+}
+}
+
+if (cc->ContextFlags & CPU_CONTEXT_EXTENDED_REGISTERS) {
+uint8_t *ptr = cc->ExtendedRegisters + 160;
+int i;
+for (i = 0; i < 8; ++i, ptr += 16) {
+stq_p(ptr, env->xmm_regs[i].ZMM_Q(0));
+stq_p(ptr + 8, env->xmm_regs[i].ZMM_Q(1));
+}
+
+stl_p(cc->ExtendedRegisters + 24, env->mxcsr);
+}
+
+stl_p(>ContextFlags, cc->ContextFlags);
+
+if (new_mem) {
+memcpy(buf, (uint8_t *) cc + offset, len);
+g_free(cc);
+}
 return 0;
 }
 




[Qemu-devel] [PATCH v4 11/46] windbg: parsing data stream

2017-12-11 Thread Mihail Abakumov
Added function of parsing data stream from windbg to packet.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |  111 +-
 1 file changed, 110 insertions(+), 1 deletion(-)

diff --git a/windbgstub.c b/windbgstub.c
index 395f244d4f..ace992e2cb 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -60,6 +60,105 @@ typedef struct WindbgState {
 
 static WindbgState *windbg_state;
 
+static void windbg_ctx_handler(ParsingContext *ctx)
+{}
+
+static void windbg_read_byte(ParsingContext *ctx, uint8_t byte)
+{
+switch (ctx->state) {
+case STATE_LEADER:
+ctx->result = RESULT_NONE;
+if (byte == PACKET_LEADER_BYTE || byte == CONTROL_PACKET_LEADER_BYTE) {
+if (ctx->index > 0 && byte != PTR(ctx->packet.PacketLeader)[0]) {
+ctx->index = 0;
+}
+PTR(ctx->packet.PacketLeader)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.PacketLeader)) {
+ctx->state = STATE_PACKET_TYPE;
+ctx->index = 0;
+}
+} else if (byte == BREAKIN_PACKET_BYTE) {
+ctx->result = RESULT_BREAKIN_BYTE;
+ctx->index = 0;
+} else {
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_TYPE:
+PTR(ctx->packet.PacketType)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.PacketType)) {
+ctx->packet.PacketType = lduw_p(>packet.PacketType);
+if (ctx->packet.PacketType >= PACKET_TYPE_MAX) {
+ctx->state = STATE_LEADER;
+ctx->result = RESULT_UNKNOWN_PACKET;
+} else {
+ctx->state = STATE_PACKET_BYTE_COUNT;
+}
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_BYTE_COUNT:
+PTR(ctx->packet.ByteCount)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.ByteCount)) {
+ctx->packet.ByteCount = lduw_p(>packet.ByteCount);
+ctx->state = STATE_PACKET_ID;
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_ID:
+PTR(ctx->packet.PacketId)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.PacketId)) {
+ctx->packet.PacketId = ldl_p(>packet.PacketId);
+ctx->state = STATE_PACKET_CHECKSUM;
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_CHECKSUM:
+PTR(ctx->packet.Checksum)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.Checksum)) {
+ctx->packet.Checksum = ldl_p(>packet.Checksum);
+if (ctx->packet.PacketLeader == CONTROL_PACKET_LEADER) {
+ctx->state = STATE_LEADER;
+ctx->result = RESULT_CONTROL_PACKET;
+} else if (ctx->packet.ByteCount > PACKET_MAX_SIZE) {
+ctx->state = STATE_LEADER;
+ctx->result = RESULT_ERROR;
+} else {
+ctx->state = STATE_PACKET_DATA;
+}
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_DATA:
+ctx->data.buf[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == ctx->packet.ByteCount) {
+ctx->state = STATE_TRAILING_BYTE;
+ctx->index = 0;
+}
+break;
+
+case STATE_TRAILING_BYTE:
+if (byte == PACKET_TRAILING_BYTE) {
+ctx->result = RESULT_DATA_PACKET;
+} else {
+ctx->result = RESULT_ERROR;
+}
+ctx->state = STATE_LEADER;
+break;
+}
+}
+
 static int windbg_chr_can_receive(void *opaque)
 {
 return PACKET_MAX_SIZE;
@@ -67,8 +166,18 @@ static int windbg_chr_can_receive(void *opaque)
 
 static void windbg_chr_receive(void *opaque, const uint8_t *buf, int size)
 {
+static ParsingContext ctx = {
+.state = STATE_LEADER,
+.result = RESULT_NONE,
+.name = ""
+};
+
 if (windbg_state->is_loaded) {
-/* T0D0: parse data */
+int i;
+for (i = 0; i < size; i++) {
+windbg_read_byte(, buf[i]);
+windbg_ctx_handler();
+}
 }
 }
 




[Qemu-devel] [PATCH v4 08/46] windbg: hook to wrmsr operation

2017-12-11 Thread Mihail Abakumov
Inserted hook to wrmsr operation. Windows Kernel put address on KPCR struct to 
fs/gs (x32/x64) register. Needs catch this moment and allow windbg server 
handle packets.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 ++
 include/exec/windbgstub.h   |1 +
 stubs/windbgstub.c  |3 +++
 target/i386/misc_helper.c   |3 +++
 target/i386/windbgstub.c|   10 ++
 windbgstub.c|   13 +
 6 files changed, 32 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 4c747fa23e..a181e172e9 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -47,4 +47,6 @@ typedef struct SizedBuf {
 size_t size;
 } SizedBuf;
 
+bool windbg_on_load(void);
+
 #endif
diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
index 21bc552e58..309f692383 100755
--- a/include/exec/windbgstub.h
+++ b/include/exec/windbgstub.h
@@ -18,6 +18,7 @@
 #define WINDBG_DEBUG_ON false
 #endif
 
+void windbg_try_load(void);
 int windbg_server_start(const char *device);
 
 #endif
diff --git a/stubs/windbgstub.c b/stubs/windbgstub.c
index 4951f59203..bd7e2dccd1 100755
--- a/stubs/windbgstub.c
+++ b/stubs/windbgstub.c
@@ -12,6 +12,9 @@
 #include "qemu/osdep.h"
 #include "exec/windbgstub.h"
 
+void windbg_try_load(void)
+{}
+
 int windbg_server_start(const char *device)
 {
 return 0;
diff --git a/target/i386/misc_helper.c b/target/i386/misc_helper.c
index 628f64aad5..ec1fcd2899 100644
--- a/target/i386/misc_helper.c
+++ b/target/i386/misc_helper.c
@@ -24,6 +24,7 @@
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "exec/address-spaces.h"
+#include "exec/windbgstub.h"
 
 void helper_outb(CPUX86State *env, uint32_t port, uint32_t data)
 {
@@ -385,6 +386,8 @@ void helper_wrmsr(CPUX86State *env)
 /* XXX: exception? */
 break;
 }
+
+windbg_try_load();
 }
 
 void helper_rdmsr(CPUX86State *env)
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index df89e1edd8..0938f738e6 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -10,3 +10,13 @@
  */
 
 #include "qemu/osdep.h"
+
+#ifndef TARGET_X86_64
+#include "exec/windbgstub-utils.h"
+
+bool windbg_on_load(void)
+{
+return false;
+}
+
+#endif
diff --git a/windbgstub.c b/windbgstub.c
index e30b8500e0..a2a6eb81b4 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -16,6 +16,7 @@
 #include "qemu/cutils.h"
 #include "exec/windbgstub.h"
 #include "exec/windbgstub-utils.h"
+#include "sysemu/kvm.h"
 
 typedef struct WindbgState {
 bool is_loaded;
@@ -45,6 +46,13 @@ static void windbg_exit(void)
 g_free(windbg_state);
 }
 
+void windbg_try_load(void)
+{
+if (windbg_state && !windbg_state->is_loaded) {
+windbg_state->is_loaded = windbg_on_load();
+}
+}
+
 int windbg_server_start(const char *device)
 {
 Chardev *chr = NULL;
@@ -54,6 +62,11 @@ int windbg_server_start(const char *device)
 exit(1);
 }
 
+if (kvm_enabled()) {
+WINDBG_ERROR("KVM is not supported.");
+exit(1);
+}
+
 if (!strstart(device, "pipe:", NULL)) {
 WINDBG_ERROR("Unsupported device. Supported only pipe.");
 exit(1);




[Qemu-devel] [PATCH v4 16/46] windbg: generate LoadSymbolsStateChange

2017-12-11 Thread Mihail Abakumov
Added function for generate LoadSymbolsStateChange packet.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 target/i386/windbgstub.c|   16 
 2 files changed, 17 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index d9dae4e902..a7ec53555b 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -75,6 +75,7 @@ InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
+SizedBuf kd_gen_load_symbols_sc(CPUState *cpu);
 
 bool windbg_on_load(void);
 
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 5db6a5e3bc..28d4f5bb10 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -134,4 +134,20 @@ SizedBuf kd_gen_exception_sc(CPUState *cpu)
 return buf;
 }
 
+SizedBuf kd_gen_load_symbols_sc(CPUState *cpu)
+{
+DBGKD_ANY_WAIT_STATE_CHANGE *sc;
+SizedBuf buf;
+
+buf.size = sizeof(DBGKD_ANY_WAIT_STATE_CHANGE);
+buf.data = g_malloc0(buf.size);
+sc = (DBGKD_ANY_WAIT_STATE_CHANGE *) buf.data;
+kd_init_state_change(cpu, sc);
+
+stl_p(>NewState, DbgKdLoadSymbolsStateChange);
+stl_p(>u.LoadSymbols.PathNameLength, 0);
+
+return buf;
+}
+
 #endif




[Qemu-devel] [PATCH v4 22/46] windbg: kernel's structures

2017-12-11 Thread Mihail Abakumov
Defined Windows kernel's structures (CPU_CONTEXT and CPU_KSPECIAL_REGISTERS) 
for i386 and x64_86.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |  247 ++
 1 file changed, 247 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 28d4f5bb10..11c35a4207 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -26,6 +26,253 @@
 # define OFFSET_KPRCB_CURRTHREAD 0x4
 #endif
 
+/*
+ * Next code copied from winnt.h
+ */
+#ifdef TARGET_X86_64
+
+#define CPU_CONTEXT_AMD64 0x10
+
+#define CPU_CONTEXT_CONTROL (CPU_CONTEXT_AMD64 | 0x1)
+#define CPU_CONTEXT_INTEGER (CPU_CONTEXT_AMD64 | 0x2)
+#define CPU_CONTEXT_SEGMENTS(CPU_CONTEXT_AMD64 | 0x4)
+#define CPU_CONTEXT_FLOATING_POINT  (CPU_CONTEXT_AMD64 | 0x8)
+#define CPU_CONTEXT_DEBUG_REGISTERS (CPU_CONTEXT_AMD64 | 0x10)
+
+#define CPU_CONTEXT_FULL \
+(CPU_CONTEXT_CONTROL | CPU_CONTEXT_INTEGER | CPU_CONTEXT_FLOATING_POINT)
+#define CPU_CONTEXT_ALL \
+(CPU_CONTEXT_FULL | CPU_CONTEXT_SEGMENTS | CPU_CONTEXT_DEBUG_REGISTERS)
+
+typedef struct _CPU_DESCRIPTOR {
+uint16_t Pad[3];
+uint16_t Limit;
+uint64_t Base;
+} CPU_DESCRIPTOR, *PCPU_DESCRIPTOR;
+
+typedef struct _CPU_KSPECIAL_REGISTERS {
+uint64_t Cr0;
+uint64_t Cr2;
+uint64_t Cr3;
+uint64_t Cr4;
+uint64_t KernelDr0;
+uint64_t KernelDr1;
+uint64_t KernelDr2;
+uint64_t KernelDr3;
+uint64_t KernelDr6;
+uint64_t KernelDr7;
+CPU_DESCRIPTOR Gdtr;
+CPU_DESCRIPTOR Idtr;
+uint16_t Tr;
+uint16_t Ldtr;
+uint32_t MxCsr;
+uint64_t DebugControl;
+uint64_t LastBranchToRip;
+uint64_t LastBranchFromRip;
+uint64_t LastExceptionToRip;
+uint64_t LastExceptionFromRip;
+uint64_t Cr8;
+uint64_t MsrGsBase;
+uint64_t MsrGsSwap;
+uint64_t MsrStar;
+uint64_t MsrLStar;
+uint64_t MsrCStar;
+uint64_t MsrSyscallMask;
+uint64_t Xcr0;
+} CPU_KSPECIAL_REGISTERS, *PCPU_KSPECIAL_REGISTERS;
+
+#pragma pack(push, 2)
+typedef struct _CPU_M128A {
+uint64_t Low;
+int64_t High;
+} CPU_M128A, *PCPU_M128A;
+#pragma pack(pop)
+
+typedef struct _CPU_XMM_SAVE_AREA32 {
+uint16_t ControlWord;
+uint16_t StatusWord;
+uint8_t TagWord;
+uint8_t Reserved1;
+uint16_t ErrorOpcode;
+uint32_t ErrorOffset;
+uint16_t ErrorSelector;
+uint16_t Reserved2;
+uint32_t DataOffset;
+uint16_t DataSelector;
+uint16_t Reserved3;
+uint32_t MxCsr;
+uint32_t MxCsr_Mask;
+CPU_M128A FloatRegisters[8];
+CPU_M128A XmmRegisters[16];
+uint8_t Reserved4[96];
+} CPU_XMM_SAVE_AREA32, *PCPU_XMM_SAVE_AREA32;
+
+#pragma pack(push, 2)
+typedef struct _CPU_CONTEXT { /* sizeof = 1232 */
+uint64_t P1Home;
+uint64_t P2Home;
+uint64_t P3Home;
+uint64_t P4Home;
+uint64_t P5Home;
+uint64_t P6Home;
+uint32_t ContextFlags;
+uint32_t MxCsr;
+uint16_t SegCs;
+uint16_t SegDs;
+uint16_t SegEs;
+uint16_t SegFs;
+uint16_t SegGs;
+uint16_t SegSs;
+uint32_t EFlags;
+uint64_t Dr0;
+uint64_t Dr1;
+uint64_t Dr2;
+uint64_t Dr3;
+uint64_t Dr6;
+uint64_t Dr7;
+uint64_t Rax;
+uint64_t Rcx;
+uint64_t Rdx;
+uint64_t Rbx;
+uint64_t Rsp;
+uint64_t Rbp;
+uint64_t Rsi;
+uint64_t Rdi;
+uint64_t R8;
+uint64_t R9;
+uint64_t R10;
+uint64_t R11;
+uint64_t R12;
+uint64_t R13;
+uint64_t R14;
+uint64_t R15;
+uint64_t Rip;
+union {
+CPU_XMM_SAVE_AREA32 FltSave;
+CPU_XMM_SAVE_AREA32 FloatSave;
+struct {
+CPU_M128A Header[2];
+CPU_M128A Legacy[8];
+CPU_M128A Xmm0;
+CPU_M128A Xmm1;
+CPU_M128A Xmm2;
+CPU_M128A Xmm3;
+CPU_M128A Xmm4;
+CPU_M128A Xmm5;
+CPU_M128A Xmm6;
+CPU_M128A Xmm7;
+CPU_M128A Xmm8;
+CPU_M128A Xmm9;
+CPU_M128A Xmm10;
+CPU_M128A Xmm11;
+CPU_M128A Xmm12;
+CPU_M128A Xmm13;
+CPU_M128A Xmm14;
+CPU_M128A Xmm15;
+};
+};
+CPU_M128A VectorRegister[26];
+uint64_t VectorControl;
+uint64_t DebugControl;
+uint64_t LastBranchToRip;
+uint64_t LastBranchFromRip;
+uint64_t LastExceptionToRip;
+uint64_t LastExceptionFromRip;
+} CPU_CONTEXT, *PCPU_CONTEXT;
+#pragma pack(pop)
+
+#else
+
+#define SIZE_OF_X86_REG 80
+#define MAX_SUP_EXT 512
+
+#define CPU_CONTEXT_i386 0x1
+
+#define CPU_CONTEXT_CONTROL(CPU_CONTEXT_i386 | 0x1)
+#define CPU_CONTEXT_INTEGER(CPU_CONTEXT_i386 | 0x2)
+#define CPU_CONTEXT_SEGMENTS   (CPU_CONTEXT_i386 | 0x4)
+#define CPU_CONTEXT_FLOATING_POINT (CPU_CONTEXT_i3

[Qemu-devel] [PATCH v4 13/46] windbg: handler of parsing context

2017-12-11 Thread Mihail Abakumov
Implemented handler of parsing context.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   36 ++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/windbgstub.c b/windbgstub.c
index 8c33e0de0a..b71449e369 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -11,6 +11,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "sysemu/sysemu.h"
 #include "chardev/char.h"
 #include "chardev/char-fe.h"
 #include "qemu/cutils.h"
@@ -97,7 +98,6 @@ static void windbg_send_data_packet(uint8_t *data, uint16_t 
byte_count,
 windbg_state->data_packet_id ^= 1;
 }
 
-__attribute__ ((unused)) /* unused yet */
 static void windbg_send_control_packet(uint16_t type)
 {
 KD_PACKET packet = {
@@ -116,9 +116,41 @@ static void windbg_send_control_packet(uint16_t type)
 windbg_state->ctrl_packet_id ^= 1;
 }
 
-static void windbg_ctx_handler(ParsingContext *ctx)
+static void windbg_process_data_packet(ParsingContext *ctx)
 {}
 
+static void windbg_process_control_packet(ParsingContext *ctx)
+{}
+
+static void windbg_ctx_handler(ParsingContext *ctx)
+{
+switch (ctx->result) {
+case RESULT_NONE:
+break;
+
+case RESULT_BREAKIN_BYTE:
+vm_stop(RUN_STATE_PAUSED);
+break;
+
+case RESULT_CONTROL_PACKET:
+windbg_process_control_packet(ctx);
+break;
+
+case RESULT_DATA_PACKET:
+windbg_process_data_packet(ctx);
+break;
+
+case RESULT_UNKNOWN_PACKET:
+case RESULT_ERROR:
+windbg_state->ctrl_packet_id = 0;
+windbg_send_control_packet(PACKET_TYPE_KD_RESEND);
+break;
+
+default:
+break;
+}
+}
+
 static void windbg_read_byte(ParsingContext *ctx, uint8_t byte)
 {
 switch (ctx->state) {




[Qemu-devel] [PATCH v4 03/46] windbg: modified windbgkd.h

2017-12-11 Thread Mihail Abakumov
Added useful name arrays of some defines. Not used yet. Needs for the future.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgkd.h |   83 +++
 1 file changed, 83 insertions(+)

diff --git a/include/exec/windbgkd.h b/include/exec/windbgkd.h
index b8f98925e7..5008cbb729 100755
--- a/include/exec/windbgkd.h
+++ b/include/exec/windbgkd.h
@@ -870,4 +870,87 @@ typedef struct _DBGKD_TRACE_IO {
} u;
 } DBGKD_TRACE_IO, *PDBGKD_TRACE_IO;
 
+__attribute__ ((unused)) /* maybe unused */
+static const char *kd_api_names[] = {
+"DbgKdReadVirtualMemoryApi",
+"DbgKdWriteVirtualMemoryApi",
+"DbgKdGetContextApi",
+"DbgKdSetContextApi",
+"DbgKdWriteBreakPointApi",
+"DbgKdRestoreBreakPointApi",
+"DbgKdContinueApi",
+"DbgKdReadControlSpaceApi",
+"DbgKdWriteControlSpaceApi",
+"DbgKdReadIoSpaceApi",
+"DbgKdWriteIoSpaceApi",
+"DbgKdRebootApi",
+"DbgKdContinueApi2",
+"DbgKdReadPhysicalMemoryApi",
+"DbgKdWritePhysicalMemoryApi",
+"DbgKdQuerySpecialCallsApi",
+"DbgKdSetSpecialCallApi",
+"DbgKdClearSpecialCallsApi",
+"DbgKdSetInternalBreakPointApi",
+"DbgKdGetInternalBreakPointApi",
+"DbgKdReadIoSpaceExtendedApi",
+"DbgKdWriteIoSpaceExtendedApi",
+"DbgKdGetVersionApi",
+"DbgKdWriteBreakPointExApi",
+"DbgKdRestoreBreakPointExApi",
+"DbgKdCauseBugCheckApi",
+"",
+"",
+"",
+"",
+"",
+"",
+"DbgKdSwitchProcessor",
+"DbgKdPageInApi",
+"DbgKdReadMachineSpecificRegister",
+"DbgKdWriteMachineSpecificRegister",
+"OldVlm1",
+"OldVlm2",
+"DbgKdSearchMemoryApi",
+"DbgKdGetBusDataApi",
+"DbgKdSetBusDataApi",
+"DbgKdCheckLowMemoryApi",
+"DbgKdClearAllInternalBreakpointsApi",
+"DbgKdFillMemoryApi",
+"DbgKdQueryMemoryApi",
+"DbgKdSwitchPartition",
+"DbgKdUnknownApi"
+};
+
+__attribute__ ((unused)) /* maybe unused */
+static const char *kd_packet_type_names[] = {
+"PACKET_TYPE_UNUSED",
+"PACKET_TYPE_KD_STATE_CHANGE32",
+"PACKET_TYPE_KD_STATE_MANIPULATE",
+"PACKET_TYPE_KD_DEBUG_IO",
+"PACKET_TYPE_KD_ACKNOWLEDGE",
+"PACKET_TYPE_KD_RESEND",
+"PACKET_TYPE_KD_RESET",
+"PACKET_TYPE_KD_STATE_CHANGE64",
+"PACKET_TYPE_KD_POLL_BREAKIN",
+"PACKET_TYPE_KD_TRACE_IO",
+"PACKET_TYPE_KD_CONTROL_REQUEST",
+"PACKET_TYPE_KD_FILE_IO",
+"PACKET_TYPE_MAX"
+};
+
+#define KD_API_NAME(id) ({  \
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(kd_api_names) ==   \
+  DbgKdMaximumManipulate - DbgKdMinimumManipulate + 2); \
+(id >= DbgKdMinimumManipulate && id < DbgKdMaximumManipulate) ? \
+kd_api_names[id - DbgKdMinimumManipulate] : \
+kd_api_names[DbgKdMaximumManipulate - DbgKdMinimumManipulate];  \
+})
+
+#define KD_PKT_TYPE_NAME(id) ({ \
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(kd_packet_type_names) == PACKET_TYPE_MAX); \
+(id >= 0 && id < PACKET_TYPE_MAX) ? \
+kd_packet_type_names[id] :  \
+kd_packet_type_names[PACKET_TYPE_MAX - 1];  \
+})
+
 #endif




[Qemu-devel] [PATCH v4 10/46] windbg: structures for parsing data stream

2017-12-11 Thread Mihail Abakumov
Added structures for parsing data stream from windbg to packet.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |   11 +++
 windbgstub.c|   30 ++
 2 files changed, 41 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index ced03b0663..b7e65faefe 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -52,6 +52,17 @@ typedef struct InitedAddr {
 bool is_init;
 } InitedAddr;
 
+typedef struct PacketData {
+union {
+struct {
+DBGKD_MANIPULATE_STATE64 m64;
+uint8_t extra[0];
+};
+uint8_t buf[PACKET_MAX_SIZE];
+};
+uint16_t extra_size;
+} PacketData;
+
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
diff --git a/windbgstub.c b/windbgstub.c
index e9aabd807b..395f244d4f 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -19,6 +19,36 @@
 #include "sysemu/kvm.h"
 #include "sysemu/reset.h"
 
+typedef enum ParsingState {
+STATE_LEADER,
+STATE_PACKET_TYPE,
+STATE_PACKET_BYTE_COUNT,
+STATE_PACKET_ID,
+STATE_PACKET_CHECKSUM,
+STATE_PACKET_DATA,
+STATE_TRAILING_BYTE,
+} ParsingState;
+
+typedef enum ParsingResult {
+RESULT_NONE,
+RESULT_BREAKIN_BYTE,
+RESULT_UNKNOWN_PACKET,
+RESULT_CONTROL_PACKET,
+RESULT_DATA_PACKET,
+RESULT_ERROR,
+} ParsingResult;
+
+typedef struct ParsingContext {
+/* index in the current buffer,
+   which depends on the current state */
+int index;
+ParsingState state;
+ParsingResult result;
+KD_PACKET packet;
+PacketData data;
+const char *name;
+} ParsingContext;
+
 typedef struct WindbgState {
 bool is_loaded;
 




[Qemu-devel] [PATCH v4 09/46] windbg: handler of fs/gs register

2017-12-11 Thread Mihail Abakumov
Added handler of fs/gs register. It tries to find and check KPCR and version 
address.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |8 ++
 target/i386/windbgstub.c|   49 ++-
 windbgstub-utils.c  |   13 ++
 windbgstub.c|   10 
 4 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index a181e172e9..ced03b0663 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -47,6 +47,14 @@ typedef struct SizedBuf {
 size_t size;
 } SizedBuf;
 
+typedef struct InitedAddr {
+target_ulong addr;
+bool is_init;
+} InitedAddr;
+
+InitedAddr *windbg_get_KPCR(void);
+InitedAddr *windbg_get_version(void);
+
 bool windbg_on_load(void);
 
 #endif
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 0938f738e6..47ee5840ef 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -14,9 +14,56 @@
 #ifndef TARGET_X86_64
 #include "exec/windbgstub-utils.h"
 
+#ifdef TARGET_X86_64
+# define OFFSET_SELF_PCR 0x18
+# define OFFSET_VERS 0x108
+#else
+# define OFFSET_SELF_PCR 0x1C
+# define OFFSET_VERS 0x34
+#endif
+
 bool windbg_on_load(void)
 {
-return false;
+CPUState *cpu = qemu_get_cpu(0);
+CPUArchState *env = cpu->env_ptr;
+InitedAddr *KPCR = windbg_get_KPCR();
+InitedAddr *version = windbg_get_version();
+
+if (!KPCR->is_init) {
+
+ #ifdef TARGET_X86_64
+KPCR->addr = env->segs[R_GS].base;
+ #else
+KPCR->addr = env->segs[R_FS].base;
+ #endif
+
+static target_ulong prev_KPCR;
+if (!KPCR->addr || prev_KPCR == KPCR->addr) {
+return false;
+}
+prev_KPCR = KPCR->addr;
+
+if (KPCR->addr != READ_VMEM(cpu, KPCR->addr + OFFSET_SELF_PCR,
+target_ulong)) {
+return false;
+}
+
+KPCR->is_init = true;
+}
+
+if (!version->is_init && KPCR->is_init) {
+version->addr = READ_VMEM(cpu, KPCR->addr + OFFSET_VERS,
+  target_ulong);
+if (!version->addr) {
+return false;
+}
+version->is_init = true;
+}
+
+WINDBG_DEBUG("windbg_on_load: KPCR " FMT_ADDR, KPCR->addr);
+WINDBG_DEBUG("windbg_on_load: version " FMT_ADDR, version->addr);
+
+return true;
 }
 
 #endif
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index dc5e505c63..347c61553a 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -10,3 +10,16 @@
  */
 
 #include "exec/windbgstub-utils.h"
+
+static InitedAddr KPCR;
+static InitedAddr version;
+
+InitedAddr *windbg_get_KPCR(void)
+{
+return 
+}
+
+InitedAddr *windbg_get_version(void)
+{
+return 
+}
diff --git a/windbgstub.c b/windbgstub.c
index a2a6eb81b4..e9aabd807b 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -17,6 +17,7 @@
 #include "exec/windbgstub.h"
 #include "exec/windbgstub-utils.h"
 #include "sysemu/kvm.h"
+#include "sysemu/reset.h"
 
 typedef struct WindbgState {
 bool is_loaded;
@@ -46,6 +47,13 @@ static void windbg_exit(void)
 g_free(windbg_state);
 }
 
+static void windbg_handle_reset(void *opaque)
+{
+windbg_state->is_loaded = false;
+windbg_get_KPCR()->is_init = false;
+windbg_get_version()->is_init = false;
+}
+
 void windbg_try_load(void)
 {
 if (windbg_state && !windbg_state->is_loaded) {
@@ -85,6 +93,8 @@ int windbg_server_start(const char *device)
 qemu_chr_fe_set_handlers(_state->chr, windbg_chr_can_receive,
  windbg_chr_receive, NULL, NULL, NULL, NULL, true);
 
+qemu_register_reset(windbg_handle_reset, NULL);
+
 atexit(windbg_exit);
 return 0;
 }




[Qemu-devel] [PATCH v4 05/46] windbg: added helper features

2017-12-11 Thread Mihail Abakumov
Added some helper features for windbgstub.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |   31 +++
 include/exec/windbgstub.h   |6 ++
 2 files changed, 37 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 2390597f1f..4c747fa23e 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -13,7 +13,38 @@
 #define WINDBGSTUB_UTILS_H
 
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "log.h"
+#include "cpu.h"
 #include "exec/windbgstub.h"
 #include "exec/windbgkd.h"
 
+#define WINDBG_DEBUG(...) do { \
+if (WINDBG_DEBUG_ON) { \
+qemu_log(WINDBG ": " __VA_ARGS__); \
+qemu_log("\n");\
+}  \
+} while (false)
+
+#define WINDBG_ERROR(...) error_report(WINDBG ": " __VA_ARGS__)
+
+#define FMT_ADDR "addr:0x" TARGET_FMT_lx
+#define FMT_ERR  "Error:%d"
+
+#define UINT8_P(ptr) ((uint8_t *) (ptr))
+#define PTR(var) UINT8_P()
+
+#define sizeof_field(type, field) sizeof(((type *) NULL)->field)
+
+#define READ_VMEM(cpu, addr, type) ({ \
+type _t;  \
+cpu_memory_rw_debug(cpu, addr, PTR(_t), sizeof(type), 0); \
+_t;   \
+})
+
+typedef struct SizedBuf {
+uint8_t *data;
+size_t size;
+} SizedBuf;
+
 #endif
diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
index 1a6e1cc6e5..21bc552e58 100755
--- a/include/exec/windbgstub.h
+++ b/include/exec/windbgstub.h
@@ -12,6 +12,12 @@
 #ifndef WINDBGSTUB_H
 #define WINDBGSTUB_H
 
+#define WINDBG "windbg"
+
+#ifndef WINDBG_DEBUG_ON
+#define WINDBG_DEBUG_ON false
+#endif
+
 int windbg_server_start(const char *device);
 
 #endif




[Qemu-devel] [PATCH v4 02/46] windbg: added windbg's KD header file

2017-12-11 Thread Mihail Abakumov
Header file from windbg's source code describing the main structures.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgkd.h |  873 +++
 include/exec/windbgstub-utils.h |1 
 2 files changed, 874 insertions(+)
 create mode 100755 include/exec/windbgkd.h

diff --git a/include/exec/windbgkd.h b/include/exec/windbgkd.h
new file mode 100755
index 00..b8f98925e7
--- /dev/null
+++ b/include/exec/windbgkd.h
@@ -0,0 +1,873 @@
+/*
+ * windbgkd.h
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef WINDBGKD_H
+#define WINDBGKD_H
+
+/*
+ * Packet Size and Control Stream Size
+ */
+#define PACKET_MAX_SIZE 4096
+#define DBGKD_MAXSTREAM 16
+
+/*
+ * Magic Packet IDs
+ */
+#define INITIAL_PACKET_ID   0x8080
+#define SYNC_PACKET_ID  0x0800
+#define RESET_PACKET_ID 0x0018359b
+
+/*
+ * Magic Packet bytes
+ */
+#define BREAKIN_PACKET  0x62626262
+#define BREAKIN_PACKET_BYTE 0x62
+#define PACKET_LEADER   0x30303030
+#define PACKET_LEADER_BYTE  0x30
+#define CONTROL_PACKET_LEADER   0x69696969
+#define CONTROL_PACKET_LEADER_BYTE  0x69
+#define PACKET_TRAILING_BYTE0xaa
+
+/*
+ * Packet Types
+ */
+#define PACKET_TYPE_UNUSED  0
+#define PACKET_TYPE_KD_STATE_CHANGE32   1
+#define PACKET_TYPE_KD_STATE_MANIPULATE 2
+#define PACKET_TYPE_KD_DEBUG_IO 3
+#define PACKET_TYPE_KD_ACKNOWLEDGE  4
+#define PACKET_TYPE_KD_RESEND   5
+#define PACKET_TYPE_KD_RESET6
+#define PACKET_TYPE_KD_STATE_CHANGE64   7
+#define PACKET_TYPE_KD_POLL_BREAKIN 8
+#define PACKET_TYPE_KD_TRACE_IO 9
+#define PACKET_TYPE_KD_CONTROL_REQUEST  10
+#define PACKET_TYPE_KD_FILE_IO  11
+#define PACKET_TYPE_MAX 12
+
+/*
+ * Wait State Change Types
+ */
+#define DbgKdMinimumStateChange 0x3030
+#define DbgKdExceptionStateChange   0x3030
+#define DbgKdLoadSymbolsStateChange 0x3031
+#define DbgKdCommandStringStateChange   0x3032
+#define DbgKdMaximumStateChange 0x3033
+
+/*
+ * This is combined with the basic state change code
+ * if the state is from an alternate source
+ */
+#define DbgKdAlternateStateChange   0x0001
+
+/*
+ * Manipulate Types
+ */
+#define DbgKdMinimumManipulate  0x3130
+#define DbgKdReadVirtualMemoryApi   0x3130
+#define DbgKdWriteVirtualMemoryApi  0x3131
+#define DbgKdGetContextApi  0x3132
+#define DbgKdSetContextApi  0x3133
+#define DbgKdWriteBreakPointApi 0x3134
+#define DbgKdRestoreBreakPointApi   0x3135
+#define DbgKdContinueApi0x3136
+#define DbgKdReadControlSpaceApi0x3137
+#define DbgKdWriteControlSpaceApi   0x3138
+#define DbgKdReadIoSpaceApi 0x3139
+#define DbgKdWriteIoSpaceApi0x313a
+#define DbgKdRebootApi  0x313b
+#define DbgKdContinueApi2   0x313c
+#define DbgKdReadPhysicalMemoryApi  0x313d
+#define DbgKdWritePhysicalMemoryApi 0x313e
+#define DbgKdQuerySpecialCallsApi   0x313f
+#define DbgKdSetSpecialCallApi  0x3140
+#define DbgKdClearSpecialCallsApi   0x3141
+#define DbgKdSetInternalBreakPointApi   0x3142
+#define DbgKdGetInternalBreakPointApi   0x3143
+#define DbgKdReadIoSpaceExtendedApi 0x3144
+#define DbgKdWriteIoSpaceExtendedApi0x3145
+#define DbgKdGetVersionApi  0x3146
+#define DbgKdWriteBreakPointExApi   0x3147
+#define DbgKdRestoreBreakPointExApi 0x3148
+#define DbgKdCauseBugCheckApi   0x3149
+#define DbgKdSwitchProcessor0x3150
+#define DbgKdPageInApi  0x3151
+#define DbgKdReadMachineSpecificRegister0x3152
+#define DbgKdWriteMachineSpecificRegister   0x3153
+#define OldVlm1 0x3154
+#define OldVlm2 0x3155
+#define DbgKdSearchMemoryApi0x3156
+#define DbgKdGetBusDataApi  0x3157
+#define DbgKdSetBusDataApi  0x3158
+#define DbgKdCheckLowMemoryApi  0x3159
+#define DbgKdClearAllInternalBreakpointsApi 0

[Qemu-devel] [PATCH v4 07/46] windbg: added chardev

2017-12-11 Thread Mihail Abakumov
Added chardev for listening to windbg. Target device is a parameter in the 
'-windbg' option.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Acked-by: Alistair Francis <alistair.fran...@xilinx.com>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   30 ++
 1 file changed, 30 insertions(+)

diff --git a/windbgstub.c b/windbgstub.c
index 0863da73fd..e30b8500e0 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -20,12 +20,26 @@
 typedef struct WindbgState {
 bool is_loaded;
 
+CharBackend chr;
+
 uint32_t ctrl_packet_id;
 uint32_t data_packet_id;
 } WindbgState;
 
 static WindbgState *windbg_state;
 
+static int windbg_chr_can_receive(void *opaque)
+{
+return PACKET_MAX_SIZE;
+}
+
+static void windbg_chr_receive(void *opaque, const uint8_t *buf, int size)
+{
+if (windbg_state->is_loaded) {
+/* T0D0: parse data */
+}
+}
+
 static void windbg_exit(void)
 {
 g_free(windbg_state);
@@ -33,15 +47,31 @@ static void windbg_exit(void)
 
 int windbg_server_start(const char *device)
 {
+Chardev *chr = NULL;
+
 if (windbg_state) {
 WINDBG_ERROR("Multiple instances of windbg are not supported.");
 exit(1);
 }
 
+if (!strstart(device, "pipe:", NULL)) {
+WINDBG_ERROR("Unsupported device. Supported only pipe.");
+exit(1);
+}
+
 windbg_state = g_new0(WindbgState, 1);
 windbg_state->ctrl_packet_id = RESET_PACKET_ID;
 windbg_state->data_packet_id = INITIAL_PACKET_ID;
 
+chr = qemu_chr_new_noreplay(WINDBG, device);
+if (!chr) {
+return -1;
+}
+
+qemu_chr_fe_init(_state->chr, chr, _abort);
+qemu_chr_fe_set_handlers(_state->chr, windbg_chr_can_receive,
+ windbg_chr_receive, NULL, NULL, NULL, NULL, true);
+
 atexit(windbg_exit);
 return 0;
 }




[Qemu-devel] [PATCH v4 01/46] windbg: added empty windbgstub files

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 Makefile.target |5 +
 include/exec/windbgstub-utils.h |   18 ++
 include/exec/windbgstub.h   |   17 +
 stubs/Makefile.objs |1 +
 stubs/windbgstub.c  |   18 ++
 target/i386/Makefile.objs   |2 +-
 target/i386/windbgstub.c|   12 
 windbgstub-utils.c  |   12 
 windbgstub.c|   19 +++
 9 files changed, 103 insertions(+), 1 deletion(-)
 create mode 100755 include/exec/windbgstub-utils.h
 create mode 100755 include/exec/windbgstub.h
 create mode 100755 stubs/windbgstub.c
 create mode 100755 target/i386/windbgstub.c
 create mode 100755 windbgstub-utils.c
 create mode 100755 windbgstub.c

diff --git a/Makefile.target b/Makefile.target
index 7f42c45db8..0272b5e0ab 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -148,6 +148,11 @@ obj-y += dump.o
 obj-y += migration/ram.o
 LIBS := $(libs_softmmu) $(LIBS)
 
+# WinDbg support
+ifeq ($(TARGET_NAME), i386)
+obj-y += windbgstub.o windbgstub-utils.o
+endif
+
 # Hardware support
 ifeq ($(TARGET_NAME), sparc64)
 obj-y += hw/sparc64/
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
new file mode 100755
index 00..67d190bf6c
--- /dev/null
+++ b/include/exec/windbgstub-utils.h
@@ -0,0 +1,18 @@
+/*
+ * windbgstub-utils.h
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef WINDBGSTUB_UTILS_H
+#define WINDBGSTUB_UTILS_H
+
+#include "qemu/osdep.h"
+#include "exec/windbgstub.h"
+
+#endif
diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
new file mode 100755
index 00..1a6e1cc6e5
--- /dev/null
+++ b/include/exec/windbgstub.h
@@ -0,0 +1,17 @@
+/*
+ * windbgstub.h
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef WINDBGSTUB_H
+#define WINDBGSTUB_H
+
+int windbg_server_start(const char *device);
+
+#endif
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index e69c217aff..5c25a53c15 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -12,6 +12,7 @@ stub-obj-y += dump.o
 stub-obj-y += error-printf.o
 stub-obj-y += fdset.o
 stub-obj-y += gdbstub.o
+stub-obj-y += windbgstub.o
 stub-obj-y += get-vm-name.o
 stub-obj-y += iothread.o
 stub-obj-y += iothread-lock.o
diff --git a/stubs/windbgstub.c b/stubs/windbgstub.c
new file mode 100755
index 00..4951f59203
--- /dev/null
+++ b/stubs/windbgstub.c
@@ -0,0 +1,18 @@
+/*
+ * windbgstub.c
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "exec/windbgstub.h"
+
+int windbg_server_start(const char *device)
+{
+return 0;
+}
diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs
index 6a26e9d9f0..730ee04e27 100644
--- a/target/i386/Makefile.objs
+++ b/target/i386/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += helper.o cpu.o gdbstub.o xsave_helper.o
+obj-y += helper.o cpu.o gdbstub.o windbgstub.o xsave_helper.o
 obj-$(CONFIG_TCG) += translate.o
 obj-$(CONFIG_TCG) += bpt_helper.o cc_helper.o excp_helper.o fpu_helper.o
 obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o mpx_helper.o
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
new file mode 100755
index 00..df89e1edd8
--- /dev/null
+++ b/target/i386/windbgstub.c
@@ -0,0 +1,12 @@
+/*
+ * windbgstub.c
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
new file mode 100755
index 00..dc5e505c63
--- /dev/null
+++ b/windbgstub-utils.c
@@ -0,0 +1,12 @@
+/*
+ * windbgstub-utils.c
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *

[Qemu-devel] [PATCH v4 06/46] windbg: added WindbgState

2017-12-11 Thread Mihail Abakumov
Added definition of the WindbgState struct and its initialization.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   28 
 1 file changed, 28 insertions(+)

diff --git a/windbgstub.c b/windbgstub.c
index 3830446988..0863da73fd 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -10,10 +10,38 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "chardev/char.h"
+#include "chardev/char-fe.h"
+#include "qemu/cutils.h"
 #include "exec/windbgstub.h"
 #include "exec/windbgstub-utils.h"
 
+typedef struct WindbgState {
+bool is_loaded;
+
+uint32_t ctrl_packet_id;
+uint32_t data_packet_id;
+} WindbgState;
+
+static WindbgState *windbg_state;
+
+static void windbg_exit(void)
+{
+g_free(windbg_state);
+}
+
 int windbg_server_start(const char *device)
 {
+if (windbg_state) {
+WINDBG_ERROR("Multiple instances of windbg are not supported.");
+exit(1);
+}
+
+windbg_state = g_new0(WindbgState, 1);
+windbg_state->ctrl_packet_id = RESET_PACKET_ID;
+windbg_state->data_packet_id = INITIAL_PACKET_ID;
+
+atexit(windbg_exit);
 return 0;
 }




[Qemu-devel] [PATCH v4 04/46] windbg: added '-windbg' option

2017-12-11 Thread Mihail Abakumov
This option starts windbg server.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Acked-by: Alistair Francis <alistair.fran...@xilinx.com>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 qemu-options.hx |8 
 vl.c|8 
 2 files changed, 16 insertions(+)

diff --git a/qemu-options.hx b/qemu-options.hx
index 9f6e2adfff..1c84eb56d9 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3544,6 +3544,14 @@ Shorthand for -gdb tcp::1234, i.e. open a gdbserver on 
TCP port 1234
 (@pxref{gdb_usage}).
 ETEXI
 
+DEF("windbg", HAS_ARG, QEMU_OPTION_windbg, \
+"-windbg wait for windbg connection\n", QEMU_ARCH_I386)
+STEXI
+@item -windbg
+@findex -windbg
+Wait for windbg connection.
+ETEXI
+
 DEF("d", HAS_ARG, QEMU_OPTION_d, \
 "-d item1,...enable logging of specified items (use '-d help' for a 
list of log items)\n",
 QEMU_ARCH_ALL)
diff --git a/vl.c b/vl.c
index 8e247cc2a2..d6378cf03f 100644
--- a/vl.c
+++ b/vl.c
@@ -80,6 +80,7 @@ int main(int argc, char **argv)
 #include "sysemu/sysemu.h"
 #include "sysemu/numa.h"
 #include "exec/gdbstub.h"
+#include "exec/windbgstub.h"
 #include "qemu/timer.h"
 #include "chardev/char.h"
 #include "qemu/bitmap.h"
@@ -2436,6 +2437,7 @@ struct device_config {
 DEV_VIRTCON,   /* -virtioconsole */
 DEV_DEBUGCON,  /* -debugcon */
 DEV_GDB,   /* -gdb, -s */
+DEV_WINDBG,/* -windbg */
 DEV_SCLP,  /* s390 sclp */
 } type;
 const char *cmdline;
@@ -3445,6 +3447,9 @@ int main(int argc, char **argv, char **envp)
 case QEMU_OPTION_gdb:
 add_device_config(DEV_GDB, optarg);
 break;
+case QEMU_OPTION_windbg:
+add_device_config(DEV_WINDBG, optarg);
+break;
 case QEMU_OPTION_L:
 if (is_help_option(optarg)) {
 list_data_dirs = true;
@@ -4586,6 +4591,9 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 }
 
+if (foreach_device_config(DEV_WINDBG, windbg_server_start) < 0) {
+exit(1);
+}
 if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
 exit(1);
 if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)




[Qemu-devel] [PATCH v4 00/46] Windbg supporting

2017-12-11 Thread Mihail Abakumov
An update of:

v1: 
https://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07092.html

We made the debugger module WinDbg (like GDB) for QEMU. This is the replacement
of the remote stub in Windows kernel. Used for remote Windows kernel debugging
without debugging mode.

WinDbg is a multipurpose debugger for the Microsoft Windows computer operating
system, distributed by Microsoft. Recent versions of WinDbg have been and are
being distributed as part of the free Debugging Tools for Windows suite.

How to start debugging QEMU using WinDbg:
  Run QEMU with next option:
-windbg pipe:
  QEMU will start and pause for waiting WinDbg connection.
  Run WinDbg with next options:
-b -k com:pipe,baud=115200,port=\\.\pipe\,resets=0
  Wait for debugger connect to kernel.

Note: You can add Symbol Search Path in WinDbg such as
srv*c:\tmp*http://msdl.microsoft.com/download/symbols.

How it works:
The WinDbg debugger has the possibility of connecting to a remote debug service
(Kdsrv.exe) in the Windows kernel. Therefore, it is possible to connect to the
guest system running in the QEMU emulator. Kernel debugging is possible only
with the enabled debugging mode, may change at the same time. Our module of
WinDbg debugger for QEMU is an alternative of the remote debugging service in
the kernel. Thus, the debugger connects to the debugging module, not to the
kernel of the operating system. The module obtains all the necessary information
answering debugger requests from the QEMU emulator. At the same time for
debugging there is no need to enable debugging mode in the kernel. This leads to
hidden debugging. Our module supports all features of WinDbg regarding remote
debugging, besides interception of events and exceptions. Only i386 is supported
now.

Changed in v4:

 - Add WinDbg stub to the MAINTAINERS file.
 - Increase size of the search buffer in 'kd_api_search_memory'. (Ladi Prosek)
 - Add sub functions for helper_wrmsr and helper_rdmsr: cpu_x86_write_msr and
   cpu_x86_read_msr. Also they are used in packet handlers, i.e. duplication of
   code is removed. (Ladi Prosek)
 - Add a more user-friendly error when try to use -windbg and -gdb at the same
   time. (Ladi Prosek)
 - Remove macros for SizedBuf. (Ladi Prosek)
 - Add runtime assert to KD_API_NAME and KD_PKT_TYPE_NAME. (Ladi Prosek)
 - Remove 'ifneq ($(TARGET_NAME), x86_64)' from the 'Makefile.target' file.
   (Ladi Prosek)
 - Remove incorrect macro UINT32_P. Replace it by bit shifts. (Ladi Prosek)

Changed in v3:

 - Add a support of the new api functions from the WinDbg v10.

Changed in v2:

 - Move target specific code in the 'target/' directory. (Alistair Francis)
 - Change 'kd_api_fill_memory'. Made a fill of memory by line segments. Before
   that, a full array was immediately collected and written in RAM. (Ladi 
Prosek)
 - Change 'kd_api_search_memory'. Made a search for memory by line segments.
   (Ladi Prosek)
 - Change ld* to st* where it needs. (Ladi Prosek)
 - Add a additional check of input arguments in 'windbg_read_context' and
   'windbg_read_ks_regs'. (Ladi Prosek)
 - Fix typos. (Ladi Prosek)
 - Add a fliping back 'windbg_state->is_loaded' after reset VM.
 - Add a check to disabled kvm. It is supported yet. (Ladi Prosek)
 - Add a check to device in windbg option. Only pipe is supporting now.
   (Alistair Francis)
 - Add a check to 'ifdef' WINDBG_DEBUG_ON before define it. (Alistair Francis)
 - Replace printf to qemu_log. (Alistair Francis)
 - Fix build on s390x host. (patchew)
 - Fix code style error. (patchew)

---

Mihail Abakumov (46):
  windbg: added empty windbgstub files
  windbg: added windbg's KD header file
  windbg: modified windbgkd.h
  windbg: added '-windbg' option
  windbg: added helper features
  windbg: added WindbgState
  windbg: added chardev
  windbg: hook to wrmsr operation
  windbg: handler of fs/gs register
  windbg: structures for parsing data stream
  windbg: parsing data stream
  windbg: send data and control packets
  windbg: handler of parsing context
  windbg: init DBGKD_ANY_WAIT_STATE_CHANGE
  windbg: generate ExceptionStateChange
  windbg: generate LoadSymbolsStateChange
  windbg: windbg_vm_stop
  windbg: implemented windbg_process_control_packet
  windbg: implemented windbg_process_data_packet
  windbg: implemented windbg_process_manipulate_packet
  windbg: implemented kd_api_read_virtual_memory and 
kd_api_write_virtual_memory
  windbg: kernel's structures
  windbg: implemented kd_api_get_context and kd_api_set_context
  windbg: implemented kd_api_read_control_space and 
kd_api_write_control_space
  windbg: implemented windbg_read_context
  windbg: implemented windbg_write_context
  windbg: implemented windbg_read_ks_regs
  windbg: implemented windbg_write_ks_regs
  windbg: implemented windbg_set_sr
  windbg: implemented windbg_set_dr
  windbg: implemented windbg_set_

Re: [Qemu-devel] [PATCH v3 00/45] Windbg supporting

2017-12-06 Thread Mihail Abakumov

Ladi Prosek писал 2017-11-29 11:23:

On Tue, Nov 21, 2017 at 3:07 PM, Mihail Abakumov
<mikhail.abaku...@ispras.ru> wrote:

An update of:

v1: 
https://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07092.html


We made the debugger module WinDbg (like GDB) for QEMU. This is the 
replacement of the remote stub in Windows kernel. Used for remote 
Windows kernel debugging without debugging mode.


WinDbg is a multipurpose debugger for the Microsoft Windows computer 
operating system, distributed by Microsoft. Recent versions of WinDbg 
have been and are being distributed as part of the free Debugging 
Tools for Windows suite.


How to start debugging QEMU using WinDbg:
  Run QEMU with next option:
-windbg pipe:
  QEMU will start and pause for waiting WinDbg connection.
  Run WinDbg with next options:
-b -k com:pipe,baud=115200,port=\\.\pipe\,resets=0
  Wait for debugger connect to kernel.

Note: You can add Symbol Search Path in WinDbg such as 
srv*c:\tmp*http://msdl.microsoft.com/download/symbols.


How it works:
The WinDbg debugger has the possibility of connecting to a remote 
debug service (Kdsrv.exe) in the Windows kernel. Therefore, it is 
possible to connect to the guest system running in the QEMU emulator. 
Kernel debugging is possible only with the enabled debugging mode, may 
change at the same time. Our module of WinDbg debugger for QEMU is an 
alternative of the remote debugging service in the kernel. Thus, the 
debugger connects to the debugging module, not to the kernel of the 
operating system. The module obtains all the necessary information 
answering debugger requests from the QEMU emulator. At the same time 
for debugging there is no need to enable debugging mode in the kernel. 
This leads to hidden debugging. Our module supports all features of 
WinDbg regarding remote debugging, besides interception of events and 
exceptions. Only i386 is supported now.


Changed in v3:

 - Add a support of the new api functions from the WinDbg v10.

Changed in v2:

 - Move target specific code in the 'target/' directory. (Alistair 
Francis)
 - Change 'kd_api_fill_memory'. Made a fill of memory by line 
segments. Before that, a full array was immediately collected and 
written in RAM. (Ladi Prosek)
 - Change 'kd_api_search_memory'. Made a search for memory by line 
segments. (Ladi Prosek)

 - Change ld* to st* where it needs. (Ladi Prosek)
 - Add a additional check of input arguments in 'windbg_read_context' 
and 'windbg_read_ks_regs'. (Ladi Prosek)

 - Fix typos. (Ladi Prosek)
 - Add a fliping back 'windbg_state->is_loaded' after reset VM.
 - Add a check to disabled kvm. It is supported yet. (Ladi Prosek)
 - Add a check to device in windbg option. Only pipe is supporting 
now. (Alistair Francis)
 - Add a check to 'ifdef' WINDBG_DEBUG_ON before define it. (Alistair 
Francis)

 - Replace printf to qemu_log. (Alistair Francis)
 - Fix build on s390x host. (patchew)
 - Fix code style error. (patchew)



Thanks, v3 is working with a Win10 windbg for me!

A few things I noticed during my testing (Win7 32-bit guest):

* Windbg prints:

  ReadVirtual: 827403d0 not properly sign extended

after connecting. That's likely a bug hiding somewhere.



This is due to the fact that the cpu_memory_rw_debug function cannot
return the required memory region. No physical page mapped.


* lm prints only nt and a bunch of unloaded crash dump modules. This
doesn't look expected and blocks what I believe is the most common way
of initiating debugging which is setting a breakpoint on a specific
driver function. Additionally, after rebooting the guest, lm prints
only nt, nothing else. Do you see the same thing?


Yes, the same.



  kd> lm
  startendmodule name
  8260b000 82a1d000   nt (pdb symbols)  C:\Program
Files (x86)\Windows
Kits\10\Debuggers\x64\sym\ntkrpamp.pdb\684DA42A30CC450F81C535B4D18944B12\ntkrpamp.pdb

  Unloaded modules:
  869da000 869e7000   crashdmp.sys
  869e7000 869f2000   dump_ataport.sys
  869f2000 869fb000   dump_atapi.sys
  8680 86811000   dump_dumpfve.sys

* It seems to work on a Linux host as well! Still ok to keep it
limited to pipe: for now, especially if you don't test on Linux.

* Wondering about the legal aspects of copying code from winnt.h. I'll
let others confirm that it's ok.

I have replied to some of the patches with comments.

Thank you!
Ladi


--
Thanks,
Mihail



Re: [Qemu-devel] [PATCH v3 39/45] windbg: implemented kd_api_get_version

2017-12-06 Thread Mihail Abakumov

Ladi Prosek писал 2017-11-29 11:14:

On Tue, Nov 21, 2017 at 3:10 PM, Mihail Abakumov
<mikhail.abaku...@ispras.ru> wrote:

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   22 ++
 windbgstub.c|4 
 3 files changed, 27 insertions(+)

diff --git a/include/exec/windbgstub-utils.h 
b/include/exec/windbgstub-utils.h

index be48f69f40..bc5b6a8468 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -99,6 +99,7 @@ void kd_api_read_io_space(CPUState *cpu, PacketData 
*pd);

 void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd);
+void kd_api_get_version(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);

 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 6708e62798..7ef301bac7 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -239,6 +239,28 @@ void kd_api_write_physical_memory(CPUState *cpu, 
PacketData *pd)

 stl_p(>ActualBytesWritten, len);
 }

+void kd_api_get_version(CPUState *cpu, PacketData *pd)
+{
+DBGKD_GET_VERSION64 *kdver;
+int err = cpu_memory_rw_debug(cpu, version.addr, PTR(pd->m64) + 
0x10,
+  sizeof(DBGKD_MANIPULATE_STATE64) - 
0x10, 0);

+if (!err) {
+kdver = (DBGKD_GET_VERSION64 *) (PTR(pd->m64) + 0x10);
+
+stw_p(>MajorVersion, kdver->MajorVersion);
+stw_p(>MinorVersion, kdver->MinorVersion);
+stw_p(>Flags, kdver->Flags);
+stw_p(>MachineType, kdver->MachineType);
+stw_p(>Unused[0], kdver->Unused[0]);
+sttul_p(>KernBase, kdver->KernBase);
+sttul_p(>PsLoadedModuleList, 
kdver->PsLoadedModuleList);

+sttul_p(>DebuggerDataList, kdver->DebuggerDataList);
+} else {
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;


The ReturnStatus field must be written using st* as well. You have
this direct write in many functions.



I'm doing stl_p for status before sending of packet in the 
'windbg_process_manipulate_packet',

because this is a global field of structure. Is that bad?


+WINDBG_ERROR("get_version: " FMT_ERR, err);
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index 72324ae53d..ddca290694 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -197,6 +197,10 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)

 kd_api_write_physical_memory(cpu, >data);
 break;

+case DbgKdGetVersionApi:
+kd_api_get_version(cpu, >data);
+break;
+
 case DbgKdClearAllInternalBreakpointsApi:
 return;






Re: [Qemu-devel] [PATCH v3 35/45] windbg: debug exception subscribing

2017-12-05 Thread Mihail Abakumov

Ladi Prosek писал 2017-11-29 10:13:

On Tue, Nov 21, 2017 at 3:10 PM, Mihail Abakumov
<mikhail.abaku...@ispras.ru> wrote:
Added handler registration of gdb debug exception. Its exception also 
can be used for windbg.


Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 cpus.c  |   18 +-
 gdbstub.c   |4 
 include/sysemu/sysemu.h |2 ++
 windbgstub.c|   16 
 4 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/cpus.c b/cpus.c
index 9bed61eefc..212553b7e3 100644
--- a/cpus.c
+++ b/cpus.c
@@ -77,6 +77,8 @@ int64_t max_advance;
 static QEMUTimer *throttle_timer;
 static unsigned int throttle_percentage;

+static void (*excp_debug_handler)(CPUState *cpu);
+
 #define CPU_THROTTLE_PCT_MIN 1
 #define CPU_THROTTLE_PCT_MAX 99
 #define CPU_THROTTLE_TIMESLICE_NS 1000
@@ -960,9 +962,23 @@ static bool cpu_can_run(CPUState *cpu)
 return true;
 }

+bool register_excp_debug_handler(void (*handler)(CPUState *cpu))
+{
+if (excp_debug_handler == NULL) {
+excp_debug_handler = handler;
+return true;
+} else {
+error_report("ERROR: Something debugger already using");


So I take it that -windbg and -gdb cannot be used at the same time.
Should it be handled in a more explicit way with a more user-friendly
error?

Right now I get this error, which is more like an implementation
detail (could the debug handler be refactored into a multicast event
in the future?) and does not even make sense as a sentence.


Yes. I have added a more user-friendly error. "Something debugger is
already in use. '-gdb' and '-windbg' cannot be used at the same time".
Or what do you mean under the explicit way? How to do it better?




+return false;
+}
+}
+
 static void cpu_handle_guest_debug(CPUState *cpu)
 {
-gdb_set_stop_cpu(cpu);
+if (excp_debug_handler != NULL) {
+excp_debug_handler(cpu);
+}
+
 qemu_system_debug_request();
 cpu->stopped = true;
 }
diff --git a/gdbstub.c b/gdbstub.c
index 2a94030d3b..8c76f54117 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2006,6 +2006,10 @@ int gdbserver_start(const char *device)
 s->mon_chr = mon_chr;
 s->current_syscall_cb = NULL;

+if (!register_excp_debug_handler(gdb_set_stop_cpu)) {
+exit(1);
+}
+
 return 0;
 }

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index b21369672a..34588c99b4 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -193,6 +193,8 @@ QemuOpts *qemu_get_machine_opts(void);

 bool defaults_enabled(void);

+bool register_excp_debug_handler(void (*handler)(CPUState *cpu));
+
 extern QemuOptsList qemu_legacy_drive_opts;
 extern QemuOptsList qemu_common_drive_opts;
 extern QemuOptsList qemu_drive_opts;
diff --git a/windbgstub.c b/windbgstub.c
index 489abe6d6c..b33f412659 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -115,16 +115,20 @@ static void windbg_send_control_packet(uint16_t 
type)

 windbg_state->ctrl_packet_id ^= 1;
 }

-static void windbg_vm_stop(void)
+static void windbg_bp_handler(CPUState *cpu)
 {
-CPUState *cpu = qemu_get_cpu(0);
-vm_stop(RUN_STATE_PAUSED);
-
 SizedBuf buf = kd_gen_exception_sc(cpu);
 windbg_send_data_packet(buf.data, buf.size, 
PACKET_TYPE_KD_STATE_CHANGE64);

 SBUF_FREE(buf);
 }

+static void windbg_vm_stop(void)
+{
+CPUState *cpu = qemu_get_cpu(0);
+vm_stop(RUN_STATE_PAUSED);
+windbg_bp_handler(cpu);
+}
+
 static void windbg_process_manipulate_packet(ParsingContext *ctx)
 {
 CPUState *cpu;
@@ -432,6 +436,10 @@ int windbg_server_start(const char *device)

 qemu_register_reset(windbg_handle_reset, NULL);

+if (!register_excp_debug_handler(windbg_bp_handler)) {
+exit(1);
+}
+
 atexit(windbg_exit);
 return 0;
 }





Re: [Qemu-devel] [PATCH v3 45/45] windbg: implemented kd_api_get_context_ex and kd_api_set_context_ex

2017-12-05 Thread Mihail Abakumov

Ladi Prosek писал 2017-11-28 15:44:

On Tue, Nov 21, 2017 at 3:11 PM, Mihail Abakumov
<mikhail.abaku...@ispras.ru> wrote:
[...]

diff --git a/windbgstub.c b/windbgstub.c
index 36372c0ea5..3bcf6a8cbb 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -224,6 +224,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)

 kd_api_query_memory(cpu, >data);
 break;

+case DbgKdGetContextExApi:
+kd_api_get_context_ex(cpu, >data);
+break;
+
+case DbgKdSetContextExApi:
+kd_api_set_context_ex(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;
@@ -262,12 +270,12 @@ static void 
windbg_process_control_packet(ParsingContext *ctx)


 case PACKET_TYPE_KD_RESET:
 {
-SizedBuf buf = kd_gen_load_symbols_sc(qemu_get_cpu(0));
+windbg_send_control_packet(ctx->packet.PacketType);
+windbg_state->ctrl_packet_id = INITIAL_PACKET_ID;


You didn't mention it in the cover email so I'd like to be sure. This
is what fixed the initial handshake so it works without -b now, is
that correct? Thanks!

Yes. It seems for me more logical to send a response first, then a state 
packet.
Apparently, before that I made a typo. Now Windbg connects immediately, 
and
for stopping it is necessary to press ctrl+break. But now the option 
'-b' does

not work in the old version.


+SizedBuf buf = kd_gen_load_symbols_sc(qemu_get_cpu(0));
 windbg_send_data_packet(buf.data, buf.size,
 PACKET_TYPE_KD_STATE_CHANGE64);
-windbg_send_control_packet(ctx->packet.PacketType);
-windbg_state->ctrl_packet_id = INITIAL_PACKET_ID;
 SBUF_FREE(buf);
 break;
 }







[Qemu-devel] [PATCH v3 45/45] windbg: implemented kd_api_get_context_ex and kd_api_set_context_ex

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 +
 target/i386/windbgstub.c|  129 ---
 windbgstub.c|   14 +++-
 3 files changed, 105 insertions(+), 40 deletions(-)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index fa1ebbb6d2..ea6828b973 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -106,6 +106,8 @@ void kd_api_search_memory(CPUState *cpu, PacketData *pd);
 void kd_api_fill_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 void kd_api_query_memory(CPUState *cpu, PacketData *pd);
+void kd_api_get_context_ex(CPUState *cpu, PacketData *pd);
+void kd_api_set_context_ex(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
 SizedBuf kd_gen_load_symbols_sc(CPUState *cpu);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 735b2edd5f..aca4bfedec 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -899,6 +899,52 @@ static int windbg_write_ks_regs(CPUState *cpu, uint8_t 
*buf, int buf_size,
 return 0;
 }
 
+static int windbg_rw_context_ex(CPUState *cpu, uint8_t *buf, int buf_size,
+int offset, int len, bool is_read)
+{
+uint32_t context_len;
+uint32_t ks_regs_len;
+int err = -1;
+
+if (offset < sizeof(CPU_KPROCESSOR_STATE)) {
+len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - offset);
+
+context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - offset));
+ks_regs_len = len - context_len;
+
+if (context_len > 0) {
+if (is_read) {
+err = windbg_read_context(cpu, buf, context_len, offset,
+  context_len);
+} else {
+err = windbg_write_context(cpu, buf, context_len, offset,
+   context_len);
+}
+
+if (err) {
+return err;
+}
+}
+
+if (ks_regs_len > 0) {
+offset += context_len - sizeof(CPU_CONTEXT);
+if (is_read) {
+err = windbg_read_ks_regs(cpu, buf + context_len, ks_regs_len,
+  offset, ks_regs_len);
+} else {
+err = windbg_write_ks_regs(cpu, buf + context_len, ks_regs_len,
+   offset, ks_regs_len);
+}
+
+if (err) {
+return err;
+}
+}
+}
+
+return err;
+}
+
 void kd_api_get_context(CPUState *cpu, PacketData *pd)
 {
 int err;
@@ -930,31 +976,14 @@ void kd_api_read_control_space(CPUState *cpu, PacketData 
*pd)
 {
 DBGKD_READ_MEMORY64 *mem = >m64.u.ReadMemory;
 uint32_t len;
-uint32_t context_len;
-uint32_t ks_regs_len;
 target_ulong addr;
-int err = -1;
+int err;
 
 len = MIN(ldl_p(>TransferCount),
   PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
 addr = ldtul_p(>TargetBaseAddress);
 
-if (addr < sizeof(CPU_KPROCESSOR_STATE)) {
-len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - addr);
-
-context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - addr));
-ks_regs_len = len - context_len;
-
-if (context_len > 0) {
-err = windbg_read_context(cpu, pd->extra, context_len, addr,
-  context_len);
-}
-if (ks_regs_len > 0) {
-addr = addr - sizeof(CPU_CONTEXT) + context_len;
-err = windbg_read_ks_regs(cpu, pd->extra + context_len,
-  ks_regs_len, addr, ks_regs_len);
-}
-}
+err = windbg_rw_context_ex(cpu, pd->extra, len, addr, len, true);
 
 if (err) {
 len = 0;
@@ -969,38 +998,64 @@ void kd_api_write_control_space(CPUState *cpu, PacketData 
*pd)
 {
 DBGKD_WRITE_MEMORY64 *mem = >m64.u.WriteMemory;
 uint32_t len;
-uint32_t context_len;
-uint32_t ks_regs_len;
 target_ulong addr;
-int err = -1;
+int err;
 
 len = MIN(ldl_p(>TransferCount), pd->extra_size);
 addr = ldtul_p(>TargetBaseAddress);
 
-if (addr < sizeof(CPU_KPROCESSOR_STATE)) {
-len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - addr);
+err = windbg_rw_context_ex(cpu, pd->extra, len, addr, len, false);
 
-context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - addr));
-ks_regs_len = len - context_len;
+if (err) {
+len = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
 
-if (context_len > 0) {
-err = windbg_write_context(cpu, pd->extra, context_len, addr,
-   

[Qemu-devel] [PATCH v3 43/45] windbg: implemented kd_api_query_memory

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   12 
 windbgstub.c|4 
 3 files changed, 17 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index e144294b51..fa1ebbb6d2 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -105,6 +105,7 @@ void kd_api_write_msr(CPUState *cpu, PacketData *pd);
 void kd_api_search_memory(CPUState *cpu, PacketData *pd);
 void kd_api_fill_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
+void kd_api_query_memory(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
 SizedBuf kd_gen_load_symbols_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index fb2c378460..edd23c1971 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -333,6 +333,18 @@ void kd_api_fill_memory(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_query_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_QUERY_MEMORY *mem = >m64.u.QueryMemory;
+
+mem->AddressSpace = DBGKD_QUERY_MEMORY_PROCESS;
+mem->Flags = DBGKD_QUERY_MEMORY_READ |
+ DBGKD_QUERY_MEMORY_WRITE |
+ DBGKD_QUERY_MEMORY_EXECUTE;
+mem->AddressSpace = ldl_p(>AddressSpace);
+mem->Flags = ldl_p(>Flags);
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index b348028dfd..36372c0ea5 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -220,6 +220,10 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_fill_memory(cpu, >data);
 break;
 
+case DbgKdQueryMemoryApi:
+kd_api_query_memory(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v3 41/45] windbg: implemented kd_api_search_memory

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   33 +
 windbgstub.c|4 
 3 files changed, 38 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 73d49b774d..c2eb8a75a7 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -102,6 +102,7 @@ void kd_api_write_physical_memory(CPUState *cpu, PacketData 
*pd);
 void kd_api_get_version(CPUState *cpu, PacketData *pd);
 void kd_api_read_msr(CPUState *cpu, PacketData *pd);
 void kd_api_write_msr(CPUState *cpu, PacketData *pd);
+void kd_api_search_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 7ef301bac7..1f4590f338 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -261,6 +261,39 @@ void kd_api_get_version(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_search_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_SEARCH_MEMORY *m64c = >m64.u.SearchMemory;
+int s_len = MAX(ldq_p(>SearchLength), 1);
+int p_len = MIN(ldl_p(>PatternLength), pd->extra_size);
+target_ulong addr = ldq_p(>SearchAddress);
+int size = MIN(s_len, 10);
+uint8_t mem[size + p_len];
+int i, err;
+
+pd->extra_size = 0;
+pd->m64.ReturnStatus = STATUS_NO_MORE_ENTRIES;
+
+while (s_len) {
+err = cpu_memory_rw_debug(cpu, addr, mem, size + p_len, 0);
+if (!err) {
+for (i = 0; i < size; ++i) {
+if (memcmp(mem + i, pd->extra, p_len) == 0) {
+stl_p(>FoundAddress, addr + i);
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+return;
+}
+}
+} else {
+WINDBG_DEBUG("search_memory: No physical page mapped: " FMT_ADDR,
+ addr);
+}
+s_len -= size;
+addr += size;
+size = MIN(s_len, 10);
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index 0268d0818e..d35ff6ba96 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -212,6 +212,10 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 case DbgKdClearAllInternalBreakpointsApi:
 return;
 
+case DbgKdSearchMemoryApi:
+kd_api_search_memory(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v3 39/45] windbg: implemented kd_api_get_version

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   22 ++
 windbgstub.c|4 
 3 files changed, 27 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index be48f69f40..bc5b6a8468 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -99,6 +99,7 @@ void kd_api_read_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd);
+void kd_api_get_version(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 6708e62798..7ef301bac7 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -239,6 +239,28 @@ void kd_api_write_physical_memory(CPUState *cpu, 
PacketData *pd)
 stl_p(>ActualBytesWritten, len);
 }
 
+void kd_api_get_version(CPUState *cpu, PacketData *pd)
+{
+DBGKD_GET_VERSION64 *kdver;
+int err = cpu_memory_rw_debug(cpu, version.addr, PTR(pd->m64) + 0x10,
+  sizeof(DBGKD_MANIPULATE_STATE64) - 0x10, 0);
+if (!err) {
+kdver = (DBGKD_GET_VERSION64 *) (PTR(pd->m64) + 0x10);
+
+stw_p(>MajorVersion, kdver->MajorVersion);
+stw_p(>MinorVersion, kdver->MinorVersion);
+stw_p(>Flags, kdver->Flags);
+stw_p(>MachineType, kdver->MachineType);
+stw_p(>Unused[0], kdver->Unused[0]);
+sttul_p(>KernBase, kdver->KernBase);
+sttul_p(>PsLoadedModuleList, kdver->PsLoadedModuleList);
+sttul_p(>DebuggerDataList, kdver->DebuggerDataList);
+} else {
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+WINDBG_ERROR("get_version: " FMT_ERR, err);
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index 72324ae53d..ddca290694 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -197,6 +197,10 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_write_physical_memory(cpu, >data);
 break;
 
+case DbgKdGetVersionApi:
+kd_api_get_version(cpu, >data);
+break;
+
 case DbgKdClearAllInternalBreakpointsApi:
 return;
 




[Qemu-devel] [PATCH v3 38/45] windbg: implemented kd_api_read_physical_memory and kd_api_write_physical_memory

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 ++
 windbgstub-utils.c  |   29 +
 windbgstub.c|8 
 3 files changed, 39 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 7f52acbae3..be48f69f40 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -97,6 +97,8 @@ void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_read_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
+void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd);
+void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 3f8ce1f8be..6708e62798 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -210,6 +210,35 @@ void kd_api_write_io_space(CPUState *cpu, PacketData *pd)
 pd->m64.ReturnStatus = STATUS_SUCCESS;
 }
 
+void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_MEMORY64 *mem = >m64.u.ReadMemory;
+uint32_t len;
+target_ulong addr;
+
+len = MIN(ldl_p(>TransferCount),
+  PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+addr = ldtul_p(>TargetBaseAddress);
+
+cpu_physical_memory_rw(addr, pd->extra, len, 0);
+pd->extra_size = len;
+stl_p(>ActualBytesRead, len);
+}
+
+void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_WRITE_MEMORY64 *mem = >m64.u.WriteMemory;
+uint32_t len;
+target_ulong addr;
+
+len = MIN(ldl_p(>TransferCount), pd->extra_size);
+addr = ldtul_p(>TargetBaseAddress);
+
+cpu_physical_memory_rw(addr, pd->extra, len, 1);
+pd->extra_size = 0;
+stl_p(>ActualBytesWritten, len);
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index 397dedd9d1..72324ae53d 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -189,6 +189,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_write_control_space(cpu, >data);
 break;
 
+case DbgKdReadPhysicalMemoryApi:
+kd_api_read_physical_memory(cpu, >data);
+break;
+
+case DbgKdWritePhysicalMemoryApi:
+kd_api_write_physical_memory(cpu, >data);
+break;
+
 case DbgKdClearAllInternalBreakpointsApi:
 return;
 




[Qemu-devel] [PATCH v3 36/45] windbg: implemented kd_api_continue

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   15 +++
 windbgstub.c|5 +
 3 files changed, 21 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 0d9ccf9801..2cfca92183 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -92,6 +92,7 @@ void kd_api_get_context(CPUState *cpu, PacketData *pd);
 void kd_api_set_context(CPUState *cpu, PacketData *pd);
 void kd_api_write_breakpoint(CPUState *cpu, PacketData *pd);
 void kd_api_restore_breakpoint(CPUState *cpu, PacketData *pd);
+void kd_api_continue(CPUState *cpu, PacketData *pd);
 void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index f00dab2a9d..fe3adb0b88 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -10,6 +10,7 @@
  */
 
 #include "exec/windbgstub-utils.h"
+#include "sysemu/sysemu.h"
 
 static InitedAddr KPCR;
 static InitedAddr version;
@@ -133,6 +134,20 @@ void kd_api_restore_breakpoint(CPUState *cpu, PacketData 
*pd)
 }
 }
 
+void kd_api_continue(CPUState *cpu, PacketData *pd)
+{
+uint32_t status = ldl_p(>m64.u.Continue2.ContinueStatus);
+uint32_t trace = ldl_p(>m64.u.Continue2.ControlSet.TraceFlag);
+int ssFlag = trace ? SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER : 0;
+
+if (NT_SUCCESS(status)) {
+cpu_single_step(cpu, ssFlag);
+if (!runstate_needs_reset()) {
+vm_start();
+}
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index b33f412659..a04698b003 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -168,6 +168,11 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_restore_breakpoint(cpu, >data);
 break;
 
+case DbgKdContinueApi:
+case DbgKdContinueApi2:
+kd_api_continue(cpu, >data);
+return;
+
 case DbgKdReadControlSpaceApi:
 kd_api_read_control_space(cpu, >data);
 break;




[Qemu-devel] [PATCH v3 37/45] windbg: implemented kd_api_read_io_space and kd_api_write_io_space

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 +
 windbgstub-utils.c  |   62 +++
 windbgstub.c|8 +
 3 files changed, 72 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 2cfca92183..7f52acbae3 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -95,6 +95,8 @@ void kd_api_restore_breakpoint(CPUState *cpu, PacketData *pd);
 void kd_api_continue(CPUState *cpu, PacketData *pd);
 void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
+void kd_api_read_io_space(CPUState *cpu, PacketData *pd);
+void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index fe3adb0b88..3f8ce1f8be 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -11,6 +11,7 @@
 
 #include "exec/windbgstub-utils.h"
 #include "sysemu/sysemu.h"
+#include "exec/address-spaces.h"
 
 static InitedAddr KPCR;
 static InitedAddr version;
@@ -148,6 +149,67 @@ void kd_api_continue(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_read_io_space(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_WRITE_IO64 *io = >m64.u.ReadWriteIo;
+CPUArchState *env = cpu->env_ptr;
+
+target_ulong addr = ldtul_p(>IoAddress);
+uint32_t value = 0;
+
+switch (io->DataSize) {
+case 1:
+value = address_space_ldub(_space_io, addr,
+   cpu_get_mem_attrs(env), NULL);
+stl_p(>DataValue, value);
+break;
+case 2:
+value = address_space_lduw(_space_io, addr,
+   cpu_get_mem_attrs(env), NULL);
+stl_p(>DataValue, value);
+break;
+case 4:
+value = address_space_ldl(_space_io, addr,
+  cpu_get_mem_attrs(env), NULL);
+stl_p(>DataValue, value);
+break;
+default:
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+return;
+}
+
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+}
+
+void kd_api_write_io_space(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_WRITE_IO64 *io = >m64.u.ReadWriteIo;
+CPUArchState *env = cpu->env_ptr;
+
+target_ulong addr = ldtul_p(>IoAddress);
+uint32_t value = ldl_p(>DataValue);
+
+switch (io->DataSize) {
+case 1:
+address_space_stb(_space_io, addr, value,
+  cpu_get_mem_attrs(env), NULL);
+break;
+case 2:
+address_space_stw(_space_io, addr, value,
+  cpu_get_mem_attrs(env), NULL);
+break;
+case 4:
+address_space_stl(_space_io, addr, value,
+  cpu_get_mem_attrs(env), NULL);
+break;
+default:
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+return;
+}
+
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index a04698b003..397dedd9d1 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -168,6 +168,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_restore_breakpoint(cpu, >data);
 break;
 
+case DbgKdReadIoSpaceApi:
+kd_api_read_io_space(cpu, >data);
+break;
+
+case DbgKdWriteIoSpaceApi:
+kd_api_write_io_space(cpu, >data);
+break;
+
 case DbgKdContinueApi:
 case DbgKdContinueApi2:
 kd_api_continue(cpu, >data);




[Qemu-devel] [PATCH v3 35/45] windbg: debug exception subscribing

2017-11-21 Thread Mihail Abakumov
Added handler registration of gdb debug exception. Its exception also can be 
used for windbg.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 cpus.c  |   18 +-
 gdbstub.c   |4 
 include/sysemu/sysemu.h |2 ++
 windbgstub.c|   16 
 4 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/cpus.c b/cpus.c
index 9bed61eefc..212553b7e3 100644
--- a/cpus.c
+++ b/cpus.c
@@ -77,6 +77,8 @@ int64_t max_advance;
 static QEMUTimer *throttle_timer;
 static unsigned int throttle_percentage;
 
+static void (*excp_debug_handler)(CPUState *cpu);
+
 #define CPU_THROTTLE_PCT_MIN 1
 #define CPU_THROTTLE_PCT_MAX 99
 #define CPU_THROTTLE_TIMESLICE_NS 1000
@@ -960,9 +962,23 @@ static bool cpu_can_run(CPUState *cpu)
 return true;
 }
 
+bool register_excp_debug_handler(void (*handler)(CPUState *cpu))
+{
+if (excp_debug_handler == NULL) {
+excp_debug_handler = handler;
+return true;
+} else {
+error_report("ERROR: Something debugger already using");
+return false;
+}
+}
+
 static void cpu_handle_guest_debug(CPUState *cpu)
 {
-gdb_set_stop_cpu(cpu);
+if (excp_debug_handler != NULL) {
+excp_debug_handler(cpu);
+}
+
 qemu_system_debug_request();
 cpu->stopped = true;
 }
diff --git a/gdbstub.c b/gdbstub.c
index 2a94030d3b..8c76f54117 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2006,6 +2006,10 @@ int gdbserver_start(const char *device)
 s->mon_chr = mon_chr;
 s->current_syscall_cb = NULL;
 
+if (!register_excp_debug_handler(gdb_set_stop_cpu)) {
+exit(1);
+}
+
 return 0;
 }
 
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index b21369672a..34588c99b4 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -193,6 +193,8 @@ QemuOpts *qemu_get_machine_opts(void);
 
 bool defaults_enabled(void);
 
+bool register_excp_debug_handler(void (*handler)(CPUState *cpu));
+
 extern QemuOptsList qemu_legacy_drive_opts;
 extern QemuOptsList qemu_common_drive_opts;
 extern QemuOptsList qemu_drive_opts;
diff --git a/windbgstub.c b/windbgstub.c
index 489abe6d6c..b33f412659 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -115,16 +115,20 @@ static void windbg_send_control_packet(uint16_t type)
 windbg_state->ctrl_packet_id ^= 1;
 }
 
-static void windbg_vm_stop(void)
+static void windbg_bp_handler(CPUState *cpu)
 {
-CPUState *cpu = qemu_get_cpu(0);
-vm_stop(RUN_STATE_PAUSED);
-
 SizedBuf buf = kd_gen_exception_sc(cpu);
 windbg_send_data_packet(buf.data, buf.size, PACKET_TYPE_KD_STATE_CHANGE64);
 SBUF_FREE(buf);
 }
 
+static void windbg_vm_stop(void)
+{
+CPUState *cpu = qemu_get_cpu(0);
+vm_stop(RUN_STATE_PAUSED);
+windbg_bp_handler(cpu);
+}
+
 static void windbg_process_manipulate_packet(ParsingContext *ctx)
 {
 CPUState *cpu;
@@ -432,6 +436,10 @@ int windbg_server_start(const char *device)
 
 qemu_register_reset(windbg_handle_reset, NULL);
 
+if (!register_excp_debug_handler(windbg_bp_handler)) {
+exit(1);
+}
+
 atexit(windbg_exit);
 return 0;
 }




[Qemu-devel] [PATCH v3 34/45] windbg: implemented kd_api_write_breakpoint and kd_api_restore_breakpoint

2017-11-21 Thread Mihail Abakumov
Added supporting of windbg breakpoints.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 +
 windbgstub-utils.c  |   62 +++
 windbgstub.c|   11 +++
 3 files changed, 75 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 5e5893bac8..0d9ccf9801 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -90,6 +90,8 @@ void kd_api_read_virtual_memory(CPUState *cpu, PacketData 
*pd);
 void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd);
 void kd_api_get_context(CPUState *cpu, PacketData *pd);
 void kd_api_set_context(CPUState *cpu, PacketData *pd);
+void kd_api_write_breakpoint(CPUState *cpu, PacketData *pd);
+void kd_api_restore_breakpoint(CPUState *cpu, PacketData *pd);
 void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 1e81c37501..f00dab2a9d 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -14,6 +14,8 @@
 static InitedAddr KPCR;
 static InitedAddr version;
 
+static InitedAddr bps[KD_BREAKPOINT_MAX];
+
 InitedAddr *windbg_get_KPCR(void)
 {
 return 
@@ -71,6 +73,66 @@ void kd_api_write_virtual_memory(CPUState *cpu, PacketData 
*pd)
 stl_p(>ActualBytesWritten, len);
 }
 
+void kd_api_write_breakpoint(CPUState *cpu, PacketData *pd)
+{
+DBGKD_WRITE_BREAKPOINT64 *m64c = >m64.u.WriteBreakPoint;
+target_ulong addr;
+int i, err = 0;
+
+addr = ldtul_p(>BreakPointAddress);
+
+for (i = 0; i < KD_BREAKPOINT_MAX; ++i) {
+if (!bps[i].is_init) {
+err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
+if (!err) {
+bps[i].addr = addr;
+bps[i].is_init = true;
+WINDBG_DEBUG("write_breakpoint: " FMT_ADDR, addr);
+break;
+} else {
+WINDBG_ERROR("write_breakpoint: " FMT_ADDR ", " FMT_ERR,
+ addr, err);
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+return;
+}
+} else if (addr == bps[i].addr) {
+break;
+}
+}
+
+if (!err) {
+stl_p(>BreakPointHandle, i + 1);
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+} else {
+WINDBG_ERROR("write_breakpoint: All breakpoints occupied");
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+}
+
+void kd_api_restore_breakpoint(CPUState *cpu, PacketData *pd)
+{
+DBGKD_RESTORE_BREAKPOINT *m64c = >m64.u.RestoreBreakPoint;
+uint8_t index;
+int err = -1;
+
+index = ldtul_p(>BreakPointHandle) - 1;
+
+if (bps[index].is_init) {
+err = cpu_breakpoint_remove(cpu, bps[index].addr, BP_GDB);
+if (!err) {
+WINDBG_DEBUG("restore_breakpoint: " FMT_ADDR ", index(%d)",
+ bps[index].addr, index);
+} else {
+WINDBG_ERROR("restore_breakpoint: " FMT_ADDR ", index(%d), "
+ FMT_ERR, bps[index].addr, index, err);
+}
+bps[index].is_init = false;
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+} else {
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index 5b0a15ea4e..489abe6d6c 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -156,6 +156,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_set_context(cpu, >data);
 break;
 
+case DbgKdWriteBreakPointApi:
+kd_api_write_breakpoint(cpu, >data);
+break;
+
+case DbgKdRestoreBreakPointApi:
+kd_api_restore_breakpoint(cpu, >data);
+break;
+
 case DbgKdReadControlSpaceApi:
 kd_api_read_control_space(cpu, >data);
 break;
@@ -164,6 +172,9 @@ static void windbg_process_manipulate_packet(ParsingContext 
*ctx)
 kd_api_write_control_space(cpu, >data);
 break;
 
+case DbgKdClearAllInternalBreakpointsApi:
+return;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v3 33/45] windbg: implemented windbg_hw_breakpoint_insert and windbg_hw_breakpoint_remove

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |   56 ++
 1 file changed, 56 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index deb0e728e0..43e6d45df9 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -290,11 +290,67 @@ typedef struct _CPU_KPROCESSOR_STATE {
 
 static int windbg_hw_breakpoint_insert(CPUState *cpu, int index)
 {
+CPUArchState *env = cpu->env_ptr;
+
+target_ulong addr = env->dr[index];
+int type = BP_TYPE(env->dr[7], index);
+int len = BP_LEN(env->dr[7], index);
+int err = 0;
+
+switch (type) {
+case DR7_TYPE_DATA_WR:
+err = cpu_watchpoint_insert(cpu, addr, len, BP_MEM_WRITE | BP_GDB,
+>cpu_watchpoint[index]);
+break;
+case DR7_TYPE_DATA_RW:
+err = cpu_watchpoint_insert(cpu, addr, len, BP_MEM_ACCESS | BP_GDB,
+>cpu_watchpoint[index]);
+break;
+case DR7_TYPE_BP_INST:
+err = cpu_breakpoint_insert(cpu, addr, BP_GDB,
+>cpu_breakpoint[index]);
+break;
+case DR7_TYPE_IO_RW:
+return HF_IOBPT_MASK;
+default:
+return 0;
+}
+
+if (!err) {
+WINDBG_DEBUG("hw_breakpoint_insert: index(%d), " FMT_ADDR,
+ index, addr);
+} else {
+env->cpu_breakpoint[index] = NULL;
+WINDBG_ERROR("hw_breakpoint_insert: index(%d), " FMT_ADDR ", " FMT_ERR,
+ index, addr, err);
+}
 return 0;
 }
 
 static int windbg_hw_breakpoint_remove(CPUState *cpu, int index)
 {
+CPUArchState *env = cpu->env_ptr;
+int type = BP_TYPE(env->dr[7], index);
+
+switch (type) {
+case DR7_TYPE_BP_INST:
+if (env->cpu_breakpoint[index]) {
+cpu_breakpoint_remove_by_ref(cpu, env->cpu_breakpoint[index]);
+}
+break;
+case DR7_TYPE_DATA_WR:
+case DR7_TYPE_DATA_RW:
+if (env->cpu_watchpoint[index]) {
+cpu_watchpoint_remove_by_ref(cpu, env->cpu_watchpoint[index]);
+}
+break;
+default:
+return 0;
+}
+
+env->cpu_breakpoint[index] = NULL;
+WINDBG_DEBUG("hw_breakpoint_remove: index(%d), " FMT_ADDR,
+ index, env->dr[index]);
 return 0;
 }
 




[Qemu-devel] [PATCH v3 32/45] windbg: implemented windbg_set_dr7

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |   27 ++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 14ad195107..deb0e728e0 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -299,7 +299,32 @@ static int windbg_hw_breakpoint_remove(CPUState *cpu, int 
index)
 }
 
 static void windbg_set_dr7(CPUState *cpu, target_ulong new_dr7)
-{}
+{
+CPUArchState *env = cpu->env_ptr;
+target_ulong old_dr7 = env->dr[7];
+int iobpt = 0;
+int i;
+
+new_dr7 |= DR7_FIXED_1;
+if (new_dr7 == old_dr7) {
+return;
+}
+
+for (i = 0; i < DR7_MAX_BP; i++) {
+if (IS_BP_ENABLED(old_dr7, i) && !IS_BP_ENABLED(new_dr7, i)) {
+windbg_hw_breakpoint_remove(cpu, i);
+}
+}
+
+env->dr[7] = new_dr7;
+for (i = 0; i < DR7_MAX_BP; i++) {
+if (IS_BP_ENABLED(env->dr[7], i)) {
+iobpt |= windbg_hw_breakpoint_insert(cpu, i);
+}
+}
+
+env->hflags = (env->hflags & ~HF_IOBPT_MASK) | iobpt;
+}
 
 static void windbg_set_dr(CPUState *cpu, int index, target_ulong value)
 {




[Qemu-devel] [PATCH v3 30/45] windbg: implemented windbg_set_sr

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |   17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 63962b48dd..c59d1401ad 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -277,7 +277,22 @@ static void windbg_set_dr(CPUState *cpu, int index, 
target_ulong value)
 {}
 
 static void windbg_set_sr(CPUState *cpu, int sr, uint16_t selector)
-{}
+{
+CPUArchState *env = cpu->env_ptr;
+
+if (selector != env->segs[sr].selector &&
+(!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK))) {
+unsigned int limit, flags;
+target_ulong base;
+
+int dpl = (env->eflags & VM_MASK) ? 3 : 0;
+base = selector << 4;
+limit = 0x;
+flags = DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+DESC_A_MASK | (dpl << DESC_DPL_SHIFT);
+cpu_x86_load_seg_cache(env, sr, selector, base, limit, flags);
+}
+}
 
 static int windbg_read_context(CPUState *cpu, uint8_t *buf, int buf_size,
int offset, int len)




[Qemu-devel] [PATCH v3 29/45] windbg: implemented windbg_write_ks_regs

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |  111 ++
 1 file changed, 111 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index c492ee58d8..63962b48dd 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -641,6 +641,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;
 }
 




[Qemu-devel] [PATCH v3 40/45] windbg: implemented kd_api_read_msr and kd_api_write_msr

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 
 target/i386/windbgstub.c|  319 +++
 windbgstub.c|8 +
 3 files changed, 329 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index bc5b6a8468..73d49b774d 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -100,6 +100,8 @@ void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_get_version(CPUState *cpu, PacketData *pd);
+void kd_api_read_msr(CPUState *cpu, PacketData *pd);
+void kd_api_write_msr(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 43e6d45df9..735b2edd5f 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -1003,6 +1003,325 @@ void kd_api_write_control_space(CPUState *cpu, 
PacketData *pd)
 stl_p(>ActualBytesWritten, len);
 }
 
+void kd_api_read_msr(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_WRITE_MSR *m64c = >m64.u.ReadWriteMsr;
+CPUArchState *env = cpu->env_ptr;
+
+uint64_t val;
+
+cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, 0);
+
+switch ((uint32_t)env->regs[R_ECX]) {
+case MSR_IA32_SYSENTER_CS:
+val = env->sysenter_cs;
+break;
+case MSR_IA32_SYSENTER_ESP:
+val = env->sysenter_esp;
+break;
+case MSR_IA32_SYSENTER_EIP:
+val = env->sysenter_eip;
+break;
+case MSR_IA32_APICBASE:
+val = cpu_get_apic_base(x86_env_get_cpu(env)->apic_state);
+break;
+case MSR_EFER:
+val = env->efer;
+break;
+case MSR_STAR:
+val = env->star;
+break;
+case MSR_PAT:
+val = env->pat;
+break;
+case MSR_VM_HSAVE_PA:
+val = env->vm_hsave;
+break;
+case MSR_IA32_PERF_STATUS:
+/* tsc_increment_by_tick */
+val = 1000ULL;
+/* CPU multiplier */
+val |= (((uint64_t)4ULL) << 40);
+break;
+#ifdef TARGET_X86_64
+case MSR_LSTAR:
+val = env->lstar;
+break;
+case MSR_CSTAR:
+val = env->cstar;
+break;
+case MSR_FMASK:
+val = env->fmask;
+break;
+case MSR_FSBASE:
+val = env->segs[R_FS].base;
+break;
+case MSR_GSBASE:
+val = env->segs[R_GS].base;
+break;
+case MSR_KERNELGSBASE:
+val = env->kernelgsbase;
+break;
+case MSR_TSC_AUX:
+val = env->tsc_aux;
+break;
+#endif
+case MSR_MTRRphysBase(0):
+case MSR_MTRRphysBase(1):
+case MSR_MTRRphysBase(2):
+case MSR_MTRRphysBase(3):
+case MSR_MTRRphysBase(4):
+case MSR_MTRRphysBase(5):
+case MSR_MTRRphysBase(6):
+case MSR_MTRRphysBase(7):
+val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+ MSR_MTRRphysBase(0)) / 2].base;
+break;
+case MSR_MTRRphysMask(0):
+case MSR_MTRRphysMask(1):
+case MSR_MTRRphysMask(2):
+case MSR_MTRRphysMask(3):
+case MSR_MTRRphysMask(4):
+case MSR_MTRRphysMask(5):
+case MSR_MTRRphysMask(6):
+case MSR_MTRRphysMask(7):
+val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+ MSR_MTRRphysMask(0)) / 2].mask;
+break;
+case MSR_MTRRfix64K_0:
+val = env->mtrr_fixed[0];
+break;
+case MSR_MTRRfix16K_8:
+case MSR_MTRRfix16K_A:
+val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+  MSR_MTRRfix16K_8 + 1];
+break;
+case MSR_MTRRfix4K_C:
+case MSR_MTRRfix4K_C8000:
+case MSR_MTRRfix4K_D:
+case MSR_MTRRfix4K_D8000:
+case MSR_MTRRfix4K_E:
+case MSR_MTRRfix4K_E8000:
+case MSR_MTRRfix4K_F:
+case MSR_MTRRfix4K_F8000:
+val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+  MSR_MTRRfix4K_C + 3];
+break;
+case MSR_MTRRdefType:
+val = env->mtrr_deftype;
+break;
+case MSR_MTRRcap:
+if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
+val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT |
+MSR_MTRRcap_WC_SUPPORTED;
+} else {
+/* XXX: exception? */
+val = 0;
+}
+break;
+case MSR_MCG_CAP:
+val = env->mcg_cap;
+break;
+case MSR_MCG_CTL:
+if (env->mcg_cap & MCG_CTL_P

[Qemu-devel] [PATCH v3 24/45] windbg: implemented kd_api_get_context and kd_api_set_context

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 ++
 target/i386/windbgstub.c|   39 +++
 windbgstub.c|8 
 3 files changed, 49 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 827aabb6d3..65be4793d3 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -88,6 +88,8 @@ InitedAddr *windbg_get_version(void);
 
 void kd_api_read_virtual_memory(CPUState *cpu, PacketData *pd);
 void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd);
+void kd_api_get_context(CPUState *cpu, PacketData *pd);
+void kd_api_set_context(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 43efb47471..be8fc21374 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -273,6 +273,45 @@ typedef struct _CPU_KPROCESSOR_STATE {
 CPU_KSPECIAL_REGISTERS SpecialRegisters;
 } CPU_KPROCESSOR_STATE, *PCPU_KPROCESSOR_STATE;
 
+static int windbg_read_context(CPUState *cpu, uint8_t *buf, int buf_size,
+   int offset, int len)
+{
+return 0;
+}
+
+static int windbg_write_context(CPUState *cpu, uint8_t *buf, int buf_size,
+int offset, int len)
+{
+return 0;
+}
+
+void kd_api_get_context(CPUState *cpu, PacketData *pd)
+{
+int err;
+
+pd->extra_size = sizeof(CPU_CONTEXT);
+err = windbg_read_context(cpu, pd->extra, pd->extra_size, 0,
+  pd->extra_size);
+
+if (err) {
+pd->extra_size = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+}
+
+void kd_api_set_context(CPUState *cpu, PacketData *pd)
+{
+int err;
+
+err = windbg_write_context(cpu, pd->extra, pd->extra_size, 0,
+   sizeof(CPU_CONTEXT));
+pd->extra_size = 0;
+
+if (err) {
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+}
+
 bool windbg_on_load(void)
 {
 CPUState *cpu = qemu_get_cpu(0);
diff --git a/windbgstub.c b/windbgstub.c
index 1725107722..ad8638b793 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -148,6 +148,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_write_virtual_memory(cpu, >data);
 break;
 
+case DbgKdGetContextApi:
+kd_api_get_context(cpu, >data);
+break;
+
+case DbgKdSetContextApi:
+kd_api_set_context(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v3 28/45] windbg: implemented windbg_read_ks_regs

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |   39 +++
 1 file changed, 39 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index dc2a10f8e6..c492ee58d8 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -596,6 +596,45 @@ static int windbg_write_context(CPUState *cpu, uint8_t 
*buf, int buf_size,
 static int windbg_read_ks_regs(CPUState *cpu, uint8_t *buf, int buf_size,
int offset, int len)
 {
+CPUArchState *env = cpu->env_ptr;
+CPU_KSPECIAL_REGISTERS *ckr;
+bool new_mem;
+
+new_mem = (len != sizeof(CPU_KSPECIAL_REGISTERS) || offset != 0);
+if (new_mem) {
+ckr = g_new(CPU_KSPECIAL_REGISTERS, 1);
+} else {
+ckr = (CPU_KSPECIAL_REGISTERS *) buf;
+}
+
+memset(ckr, 0, len);
+
+ckr->Cr0 = ldl_p(>cr[0]);
+ckr->Cr2 = ldl_p(>cr[2]);
+ckr->Cr3 = ldl_p(>cr[3]);
+ckr->Cr4 = ldl_p(>cr[4]);
+
+ckr->KernelDr0 = ldtul_p(>dr[0]);
+ckr->KernelDr1 = ldtul_p(>dr[1]);
+ckr->KernelDr2 = ldtul_p(>dr[2]);
+ckr->KernelDr3 = ldtul_p(>dr[3]);
+ckr->KernelDr6 = ldtul_p(>dr[6]);
+ckr->KernelDr7 = ldtul_p(>dr[7]);
+
+ckr->Gdtr.Pad = lduw_p(>gdt.selector);
+ckr->Idtr.Pad = lduw_p(>idt.selector);
+
+ckr->Gdtr.Limit = lduw_p(>gdt.limit);
+ckr->Gdtr.Base  = ldtul_p(>gdt.base);
+ckr->Idtr.Limit = lduw_p(>idt.limit);
+ckr->Idtr.Base  = ldtul_p(>idt.base);
+ckr->Tr = lduw_p(>tr.selector);
+ckr->Ldtr   = lduw_p(>ldt.selector);
+
+if (new_mem) {
+memcpy(buf, (uint8_t *) ckr + offset, len);
+g_free(ckr);
+}
 return 0;
 }
 




[Qemu-devel] [PATCH v3 18/45] windbg: windbg_vm_stop

2017-11-21 Thread Mihail Abakumov
Added function for stop vm. Also, ExceptionStateChange data is generated and 
sent here.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/windbgstub.c b/windbgstub.c
index b71449e369..dc9eba3e3c 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -71,7 +71,6 @@ static uint32_t compute_checksum(uint8_t *data, uint16_t len)
 return checksum;
 }
 
-__attribute__ ((unused)) /* unused yet */
 static void windbg_send_data_packet(uint8_t *data, uint16_t byte_count,
 uint16_t type)
 {
@@ -116,6 +115,16 @@ static void windbg_send_control_packet(uint16_t type)
 windbg_state->ctrl_packet_id ^= 1;
 }
 
+static void windbg_vm_stop(void)
+{
+CPUState *cpu = qemu_get_cpu(0);
+vm_stop(RUN_STATE_PAUSED);
+
+SizedBuf buf = kd_gen_exception_sc(cpu);
+windbg_send_data_packet(buf.data, buf.size, PACKET_TYPE_KD_STATE_CHANGE64);
+SBUF_FREE(buf);
+}
+
 static void windbg_process_data_packet(ParsingContext *ctx)
 {}
 
@@ -129,7 +138,7 @@ static void windbg_ctx_handler(ParsingContext *ctx)
 break;
 
 case RESULT_BREAKIN_BYTE:
-vm_stop(RUN_STATE_PAUSED);
+windbg_vm_stop();
 break;
 
 case RESULT_CONTROL_PACKET:




[Qemu-devel] [PATCH v3 27/45] windbg: implemented windbg_write_context

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |  212 ++
 1 file changed, 212 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 1fccd8eee7..dc2a10f8e6 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -273,6 +273,12 @@ typedef struct _CPU_KPROCESSOR_STATE {
 CPU_KSPECIAL_REGISTERS SpecialRegisters;
 } CPU_KPROCESSOR_STATE, *PCPU_KPROCESSOR_STATE;
 
+static void windbg_set_dr(CPUState *cpu, int index, target_ulong value)
+{}
+
+static void windbg_set_sr(CPUState *cpu, int sr, uint16_t selector)
+{}
+
 static int windbg_read_context(CPUState *cpu, uint8_t *buf, int buf_size,
int offset, int len)
 {
@@ -378,6 +384,212 @@ static int windbg_read_context(CPUState *cpu, uint8_t 
*buf, int buf_size,
 static int windbg_write_context(CPUState *cpu, uint8_t *buf, int buf_size,
 int offset, int len)
 {
+CPUArchState *env = cpu->env_ptr;
+int mem_size, i, tmp;
+uint8_t *mem_ptr = buf;
+
+if (len < 0 || len > buf_size) {
+WINDBG_ERROR("windbg_write_context: incorrect length %d", len);
+return 1;
+}
+
+if (offset < 0 || offset + len > sizeof(CPU_CONTEXT)) {
+WINDBG_ERROR("windbg_write_context: incorrect offset %d", offset);
+return 2;
+}
+
+while (len > 0 && offset < sizeof(CPU_CONTEXT)) {
+mem_size = 1;
+switch (offset) {
+
+case offsetof(CPU_CONTEXT, ContextFlags):
+mem_size = sizeof_field(CPU_CONTEXT, ContextFlags);
+break;
+
+case offsetof(CPU_CONTEXT, Dr0):
+mem_size = sizeof_field(CPU_CONTEXT, Dr0);
+windbg_set_dr(cpu, 0, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr1):
+mem_size = sizeof_field(CPU_CONTEXT, Dr1);
+windbg_set_dr(cpu, 1, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr2):
+mem_size = sizeof_field(CPU_CONTEXT, Dr2);
+windbg_set_dr(cpu, 2, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr3):
+mem_size = sizeof_field(CPU_CONTEXT, Dr3);
+windbg_set_dr(cpu, 3, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr6):
+mem_size = sizeof_field(CPU_CONTEXT, Dr6);
+windbg_set_dr(cpu, 6, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr7):
+mem_size = sizeof_field(CPU_CONTEXT, Dr7);
+windbg_set_dr(cpu, 7, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.ControlWord):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.ControlWord);
+cpu_set_fpuc(env, ldl_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.StatusWord):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.StatusWord);
+tmp = ldl_p(buf + offset);
+env->fpstt = (tmp >> 11) & 7;
+env->fpus = tmp & ~0x3800;
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.TagWord):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.TagWord);
+tmp = ldl_p(buf + offset);
+for (i = 0; i < 8; ++i) {
+env->fptags[i] = !((tmp >> i) & 1);
+}
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.ErrorOffset):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.ErrorOffset);
+UINT32_P(>fpip)[0] = ldl_p(buf + offset);
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.ErrorSelector):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.ErrorSelector);
+UINT32_P(>fpip)[1] = ldl_p(buf + offset);
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.DataOffset):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.DataOffset);
+UINT32_P(>fpdp)[0] = ldl_p(buf + offset);
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.DataSelector):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.DataSelector);
+UINT32_P(>fpdp)[1] = ldl_p(buf + offset);
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.RegisterArea):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.RegisterArea);
+for (i = 0; i < 8; ++i) {
+memcpy(PTR(env->fpregs[i]), mem_ptr + i * 10, 10);
+}
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.Cr0NpxState):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.Cr

[Qemu-devel] [PATCH v3 23/45] windbg: kernel's structures

2017-11-21 Thread Mihail Abakumov
Defined Windows kernel's structures (CPU_CONTEXT and CPU_KSPECIAL_REGISTERS) 
for i386 and x64_86.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |  247 ++
 1 file changed, 247 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 261e441db1..43efb47471 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -26,6 +26,253 @@
 # define OFFSET_KPRCB_CURRTHREAD 0x4
 #endif
 
+/*
+ * Next code copied from winnt.h
+ */
+#ifdef TARGET_X86_64
+
+#define CPU_CONTEXT_AMD64 0x10
+
+#define CPU_CONTEXT_CONTROL (CPU_CONTEXT_AMD64 | 0x1)
+#define CPU_CONTEXT_INTEGER (CPU_CONTEXT_AMD64 | 0x2)
+#define CPU_CONTEXT_SEGMENTS(CPU_CONTEXT_AMD64 | 0x4)
+#define CPU_CONTEXT_FLOATING_POINT  (CPU_CONTEXT_AMD64 | 0x8)
+#define CPU_CONTEXT_DEBUG_REGISTERS (CPU_CONTEXT_AMD64 | 0x10)
+
+#define CPU_CONTEXT_FULL \
+(CPU_CONTEXT_CONTROL | CPU_CONTEXT_INTEGER | CPU_CONTEXT_FLOATING_POINT)
+#define CPU_CONTEXT_ALL \
+(CPU_CONTEXT_FULL | CPU_CONTEXT_SEGMENTS | CPU_CONTEXT_DEBUG_REGISTERS)
+
+typedef struct _CPU_DESCRIPTOR {
+uint16_t Pad[3];
+uint16_t Limit;
+uint64_t Base;
+} CPU_DESCRIPTOR, *PCPU_DESCRIPTOR;
+
+typedef struct _CPU_KSPECIAL_REGISTERS {
+uint64_t Cr0;
+uint64_t Cr2;
+uint64_t Cr3;
+uint64_t Cr4;
+uint64_t KernelDr0;
+uint64_t KernelDr1;
+uint64_t KernelDr2;
+uint64_t KernelDr3;
+uint64_t KernelDr6;
+uint64_t KernelDr7;
+CPU_DESCRIPTOR Gdtr;
+CPU_DESCRIPTOR Idtr;
+uint16_t Tr;
+uint16_t Ldtr;
+uint32_t MxCsr;
+uint64_t DebugControl;
+uint64_t LastBranchToRip;
+uint64_t LastBranchFromRip;
+uint64_t LastExceptionToRip;
+uint64_t LastExceptionFromRip;
+uint64_t Cr8;
+uint64_t MsrGsBase;
+uint64_t MsrGsSwap;
+uint64_t MsrStar;
+uint64_t MsrLStar;
+uint64_t MsrCStar;
+uint64_t MsrSyscallMask;
+uint64_t Xcr0;
+} CPU_KSPECIAL_REGISTERS, *PCPU_KSPECIAL_REGISTERS;
+
+#pragma pack(push, 2)
+typedef struct _CPU_M128A {
+uint64_t Low;
+int64_t High;
+} CPU_M128A, *PCPU_M128A;
+#pragma pack(pop)
+
+typedef struct _CPU_XMM_SAVE_AREA32 {
+uint16_t ControlWord;
+uint16_t StatusWord;
+uint8_t TagWord;
+uint8_t Reserved1;
+uint16_t ErrorOpcode;
+uint32_t ErrorOffset;
+uint16_t ErrorSelector;
+uint16_t Reserved2;
+uint32_t DataOffset;
+uint16_t DataSelector;
+uint16_t Reserved3;
+uint32_t MxCsr;
+uint32_t MxCsr_Mask;
+CPU_M128A FloatRegisters[8];
+CPU_M128A XmmRegisters[16];
+uint8_t Reserved4[96];
+} CPU_XMM_SAVE_AREA32, *PCPU_XMM_SAVE_AREA32;
+
+#pragma pack(push, 2)
+typedef struct _CPU_CONTEXT { /* sizeof = 1232 */
+uint64_t P1Home;
+uint64_t P2Home;
+uint64_t P3Home;
+uint64_t P4Home;
+uint64_t P5Home;
+uint64_t P6Home;
+uint32_t ContextFlags;
+uint32_t MxCsr;
+uint16_t SegCs;
+uint16_t SegDs;
+uint16_t SegEs;
+uint16_t SegFs;
+uint16_t SegGs;
+uint16_t SegSs;
+uint32_t EFlags;
+uint64_t Dr0;
+uint64_t Dr1;
+uint64_t Dr2;
+uint64_t Dr3;
+uint64_t Dr6;
+uint64_t Dr7;
+uint64_t Rax;
+uint64_t Rcx;
+uint64_t Rdx;
+uint64_t Rbx;
+uint64_t Rsp;
+uint64_t Rbp;
+uint64_t Rsi;
+uint64_t Rdi;
+uint64_t R8;
+uint64_t R9;
+uint64_t R10;
+uint64_t R11;
+uint64_t R12;
+uint64_t R13;
+uint64_t R14;
+uint64_t R15;
+uint64_t Rip;
+union {
+CPU_XMM_SAVE_AREA32 FltSave;
+CPU_XMM_SAVE_AREA32 FloatSave;
+struct {
+CPU_M128A Header[2];
+CPU_M128A Legacy[8];
+CPU_M128A Xmm0;
+CPU_M128A Xmm1;
+CPU_M128A Xmm2;
+CPU_M128A Xmm3;
+CPU_M128A Xmm4;
+CPU_M128A Xmm5;
+CPU_M128A Xmm6;
+CPU_M128A Xmm7;
+CPU_M128A Xmm8;
+CPU_M128A Xmm9;
+CPU_M128A Xmm10;
+CPU_M128A Xmm11;
+CPU_M128A Xmm12;
+CPU_M128A Xmm13;
+CPU_M128A Xmm14;
+CPU_M128A Xmm15;
+};
+};
+CPU_M128A VectorRegister[26];
+uint64_t VectorControl;
+uint64_t DebugControl;
+uint64_t LastBranchToRip;
+uint64_t LastBranchFromRip;
+uint64_t LastExceptionToRip;
+uint64_t LastExceptionFromRip;
+} CPU_CONTEXT, *PCPU_CONTEXT;
+#pragma pack(pop)
+
+#else
+
+#define SIZE_OF_X86_REG 80
+#define MAX_SUP_EXT 512
+
+#define CPU_CONTEXT_i386 0x1
+
+#define CPU_CONTEXT_CONTROL(CPU_CONTEXT_i386 | 0x1)
+#define CPU_CONTEXT_INTEGER(CPU_CONTEXT_i386 | 0x2)
+#define CPU_CONTEXT_SEGMENTS   (CPU_CONTEXT_i386 | 0x4)
+#define CPU_CONTEXT_FLOATING_POINT (CPU_CONTEXT_i3

[Qemu-devel] [PATCH v3 14/45] windbg: init DBGKD_ANY_WAIT_STATE_CHANGE

2017-11-21 Thread Mihail Abakumov
Added function for init DBGKD_ANY_WAIT_STATE_CHANGE. It is a header of 'state 
change' packets.


Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |8 ++
 target/i386/windbgstub.c|   49 +++
 2 files changed, 57 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 2d74fb847a..6ce870beb1 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -43,6 +43,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/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 47ee5840ef..a3c433f756 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -17,9 +17,13 @@
 #ifdef TARGET_X86_64
 # define OFFSET_SELF_PCR 0x18
 # define OFFSET_VERS 0x108
+# define OFFSET_KPRCB0x20
+# define OFFSET_KPRCB_CURRTHREAD 0x8
 #else
 # define OFFSET_SELF_PCR 0x1C
 # define OFFSET_VERS 0x34
+# define OFFSET_KPRCB0x20
+# define OFFSET_KPRCB_CURRTHREAD 0x4
 #endif
 
 bool windbg_on_load(void)
@@ -66,4 +70,49 @@ bool windbg_on_load(void)
 return true;
 }
 
+__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 = >ControlReport;
+InitedAddr *KPCR = windbg_get_KPCR();
+target_ulong KPRCB;
+int err = 0;
+
+/* T0D0: HEADER */
+
+sc->Processor = 0;
+
+sc->NumberProcessors = 0;
+CPUState *cpu_tmp;
+CPU_FOREACH(cpu_tmp) {
+sc->NumberProcessors++;
+}
+stl_p(>NumberProcessors, sc->NumberProcessors);
+
+KPRCB = READ_VMEM(cpu, KPCR->addr + OFFSET_KPRCB, target_ulong);
+sc->Thread = READ_VMEM(cpu, KPRCB + OFFSET_KPRCB_CURRTHREAD, target_ulong);
+sttul_p(>Thread, sc->Thread);
+sttul_p(>ProgramCounter, env->eip);
+
+/* T0D0: CONTROL REPORT */
+
+sttul_p(>Dr6, env->dr[6]);
+sttul_p(>Dr7, env->dr[7]);
+stw_p(>ReportFlags, REPORT_INCLUDES_SEGS | REPORT_STANDARD_CS);
+stw_p(>SegCs, env->segs[R_CS].selector);
+stw_p(>SegDs, env->segs[R_DS].selector);
+stw_p(>SegEs, env->segs[R_ES].selector);
+stw_p(>SegFs, env->segs[R_FS].selector);
+stl_p(>EFlags, env->eflags);
+
+err = cpu_memory_rw_debug(cpu, sc->ProgramCounter,
+  PTR(cr->InstructionStream[0]),
+  DBGKD_MAXSTREAM, 0);
+if (!err) {
+stw_p(>InstructionCount, DBGKD_MAXSTREAM);
+}
+}
+
 #endif




[Qemu-devel] [PATCH v3 25/45] windbg: implemented kd_api_read_control_space and kd_api_write_control_space

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 +
 target/i386/windbgstub.c|   89 +++
 windbgstub.c|8 
 3 files changed, 99 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 65be4793d3..5e5893bac8 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -90,6 +90,8 @@ void kd_api_read_virtual_memory(CPUState *cpu, PacketData 
*pd);
 void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd);
 void kd_api_get_context(CPUState *cpu, PacketData *pd);
 void kd_api_set_context(CPUState *cpu, PacketData *pd);
+void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
+void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index be8fc21374..bf1afab1f8 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -285,6 +285,18 @@ static int windbg_write_context(CPUState *cpu, uint8_t 
*buf, int buf_size,
 return 0;
 }
 
+static int windbg_read_ks_regs(CPUState *cpu, uint8_t *buf, int buf_size,
+   int offset, int len)
+{
+return 0;
+}
+
+static int windbg_write_ks_regs(CPUState *cpu, uint8_t *buf, int buf_size,
+int offset, int len)
+{
+return 0;
+}
+
 void kd_api_get_context(CPUState *cpu, PacketData *pd)
 {
 int err;
@@ -312,6 +324,83 @@ void kd_api_set_context(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_read_control_space(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_MEMORY64 *mem = >m64.u.ReadMemory;
+uint32_t len;
+uint32_t context_len;
+uint32_t ks_regs_len;
+target_ulong addr;
+int err = -1;
+
+len = MIN(ldl_p(>TransferCount),
+  PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+addr = ldtul_p(>TargetBaseAddress);
+
+if (addr < sizeof(CPU_KPROCESSOR_STATE)) {
+len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - addr);
+
+context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - addr));
+ks_regs_len = len - context_len;
+
+if (context_len > 0) {
+err = windbg_read_context(cpu, pd->extra, context_len, addr,
+  context_len);
+}
+if (ks_regs_len > 0) {
+addr = addr - sizeof(CPU_CONTEXT) + context_len;
+err = windbg_read_ks_regs(cpu, pd->extra + context_len,
+  ks_regs_len, addr, ks_regs_len);
+}
+}
+
+if (err) {
+len = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+
+pd->extra_size = len;
+stl_p(>ActualBytesRead, len);
+}
+
+void kd_api_write_control_space(CPUState *cpu, PacketData *pd)
+{
+DBGKD_WRITE_MEMORY64 *mem = >m64.u.WriteMemory;
+uint32_t len;
+uint32_t context_len;
+uint32_t ks_regs_len;
+target_ulong addr;
+int err = -1;
+
+len = MIN(ldl_p(>TransferCount), pd->extra_size);
+addr = ldtul_p(>TargetBaseAddress);
+
+if (addr < sizeof(CPU_KPROCESSOR_STATE)) {
+len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - addr);
+
+context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - addr));
+ks_regs_len = len - context_len;
+
+if (context_len > 0) {
+err = windbg_write_context(cpu, pd->extra, context_len, addr,
+   context_len);
+}
+if (ks_regs_len > 0) {
+addr = addr - sizeof(CPU_CONTEXT) + context_len;
+err = windbg_write_ks_regs(cpu, pd->extra + context_len,
+   ks_regs_len, addr, ks_regs_len);
+}
+}
+
+if (err) {
+mem->ActualBytesWritten = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+
+pd->extra_size = 0;
+stl_p(>ActualBytesWritten, len);
+}
+
 bool windbg_on_load(void)
 {
 CPUState *cpu = qemu_get_cpu(0);
diff --git a/windbgstub.c b/windbgstub.c
index ad8638b793..5b0a15ea4e 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -156,6 +156,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_set_context(cpu, >data);
 break;
 
+case DbgKdReadControlSpaceApi:
+kd_api_read_control_space(cpu, >data);
+break;
+
+case DbgKdWriteControlSpaceApi:
+kd_api_write_control_space(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v3 44/45] windbg: added new api functions

2017-11-21 Thread Mihail Abakumov
Added some definitions for new windbg.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgkd.h |   21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/include/exec/windbgkd.h b/include/exec/windbgkd.h
index 40a23f8cd0..e5b9bb3b37 100755
--- a/include/exec/windbgkd.h
+++ b/include/exec/windbgkd.h
@@ -112,7 +112,10 @@
 #define DbgKdFillMemoryApi  0x315b
 #define DbgKdQueryMemoryApi 0x315c
 #define DbgKdSwitchPartition0x315d
-#define DbgKdMaximumManipulate  0x315e
+#define DbgKdWriteCustomBreakpointApi   0x315e
+#define DbgKdGetContextExApi0x315f
+#define DbgKdSetContextExApi0x3160
+#define DbgKdMaximumManipulate  0x3161
 
 /*
  * Debug I/O Types
@@ -723,6 +726,20 @@ typedef struct _DBGKD_SWITCH_PARTITION {
 uint32_t Partition;
 } DBGKD_SWITCH_PARTITION;
 
+typedef struct _DBGKD_CONTEXT_EX {
+   uint32_t Offset;
+   uint32_t ByteCount;
+   uint32_t BytesCopied;
+} DBGKD_CONTEXT_EX, *PDBGKD_CONTEXT_EX;
+
+typedef struct _DBGKD_WRITE_CUSTOM_BREAKPOINT {
+   uint64_t BreakPointAddress;
+   uint64_t BreakPointInstruction;
+   uint32_t BreakPointHandle;
+   uint16_t BreakPointInstructionSize;
+   uint16_t BreakPointInstructionAlignment;
+} DBGKD_WRITE_CUSTOM_BREAKPOINT, *PDBGKD_WRITE_CUSTOM_BREAKPOINT;
+
 /*
  * DBGKD Structure for Manipulate
  */
@@ -787,6 +804,8 @@ typedef struct _DBGKD_MANIPULATE_STATE64 {
 DBGKD_FILL_MEMORY FillMemory;
 DBGKD_QUERY_MEMORY QueryMemory;
 DBGKD_SWITCH_PARTITION SwitchPartition;
+DBGKD_WRITE_CUSTOM_BREAKPOINT WriteCustomBreakpoint;
+DBGKD_CONTEXT_EX ContextEx;
 } u;
 } DBGKD_MANIPULATE_STATE64, *PDBGKD_MANIPULATE_STATE64;
 




[Qemu-devel] [PATCH v3 20/45] windbg: implemented windbg_process_data_packet

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/windbgstub.c b/windbgstub.c
index b2d4881ee8..8058972dc7 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -125,9 +125,27 @@ static void windbg_vm_stop(void)
 SBUF_FREE(buf);
 }
 
-static void windbg_process_data_packet(ParsingContext *ctx)
+static void windbg_process_manipulate_packet(ParsingContext *ctx)
 {}
 
+static void windbg_process_data_packet(ParsingContext *ctx)
+{
+switch (ctx->packet.PacketType) {
+case PACKET_TYPE_KD_STATE_MANIPULATE:
+windbg_send_control_packet(PACKET_TYPE_KD_ACKNOWLEDGE);
+windbg_process_manipulate_packet(ctx);
+break;
+
+default:
+WINDBG_ERROR("Caught unsupported data packet 0x%x",
+ ctx->packet.PacketType);
+
+windbg_state->ctrl_packet_id = 0;
+windbg_send_control_packet(PACKET_TYPE_KD_RESEND);
+break;
+}
+}
+
 static void windbg_process_control_packet(ParsingContext *ctx)
 {
 switch (ctx->packet.PacketType) {




[Qemu-devel] [PATCH v3 09/45] windbg: handler of fs/gs register

2017-11-21 Thread Mihail Abakumov
Added handler of fs/gs register. It tries to find and check KPCR and version 
address.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |8 ++
 target/i386/windbgstub.c|   49 ++-
 windbgstub-utils.c  |   13 ++
 windbgstub.c|   10 
 4 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 4232aeb59d..42dbca1e22 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -43,6 +43,14 @@
 _t;   \
 })
 
+typedef struct InitedAddr {
+target_ulong addr;
+bool is_init;
+} InitedAddr;
+
+InitedAddr *windbg_get_KPCR(void);
+InitedAddr *windbg_get_version(void);
+
 bool windbg_on_load(void);
 
 #endif
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 0938f738e6..47ee5840ef 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -14,9 +14,56 @@
 #ifndef TARGET_X86_64
 #include "exec/windbgstub-utils.h"
 
+#ifdef TARGET_X86_64
+# define OFFSET_SELF_PCR 0x18
+# define OFFSET_VERS 0x108
+#else
+# define OFFSET_SELF_PCR 0x1C
+# define OFFSET_VERS 0x34
+#endif
+
 bool windbg_on_load(void)
 {
-return false;
+CPUState *cpu = qemu_get_cpu(0);
+CPUArchState *env = cpu->env_ptr;
+InitedAddr *KPCR = windbg_get_KPCR();
+InitedAddr *version = windbg_get_version();
+
+if (!KPCR->is_init) {
+
+ #ifdef TARGET_X86_64
+KPCR->addr = env->segs[R_GS].base;
+ #else
+KPCR->addr = env->segs[R_FS].base;
+ #endif
+
+static target_ulong prev_KPCR;
+if (!KPCR->addr || prev_KPCR == KPCR->addr) {
+return false;
+}
+prev_KPCR = KPCR->addr;
+
+if (KPCR->addr != READ_VMEM(cpu, KPCR->addr + OFFSET_SELF_PCR,
+target_ulong)) {
+return false;
+}
+
+KPCR->is_init = true;
+}
+
+if (!version->is_init && KPCR->is_init) {
+version->addr = READ_VMEM(cpu, KPCR->addr + OFFSET_VERS,
+  target_ulong);
+if (!version->addr) {
+return false;
+}
+version->is_init = true;
+}
+
+WINDBG_DEBUG("windbg_on_load: KPCR " FMT_ADDR, KPCR->addr);
+WINDBG_DEBUG("windbg_on_load: version " FMT_ADDR, version->addr);
+
+return true;
 }
 
 #endif
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index dc5e505c63..347c61553a 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -10,3 +10,16 @@
  */
 
 #include "exec/windbgstub-utils.h"
+
+static InitedAddr KPCR;
+static InitedAddr version;
+
+InitedAddr *windbg_get_KPCR(void)
+{
+return 
+}
+
+InitedAddr *windbg_get_version(void)
+{
+return 
+}
diff --git a/windbgstub.c b/windbgstub.c
index a2a6eb81b4..e9aabd807b 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -17,6 +17,7 @@
 #include "exec/windbgstub.h"
 #include "exec/windbgstub-utils.h"
 #include "sysemu/kvm.h"
+#include "sysemu/reset.h"
 
 typedef struct WindbgState {
 bool is_loaded;
@@ -46,6 +47,13 @@ static void windbg_exit(void)
 g_free(windbg_state);
 }
 
+static void windbg_handle_reset(void *opaque)
+{
+windbg_state->is_loaded = false;
+windbg_get_KPCR()->is_init = false;
+windbg_get_version()->is_init = false;
+}
+
 void windbg_try_load(void)
 {
 if (windbg_state && !windbg_state->is_loaded) {
@@ -85,6 +93,8 @@ int windbg_server_start(const char *device)
 qemu_chr_fe_set_handlers(_state->chr, windbg_chr_can_receive,
  windbg_chr_receive, NULL, NULL, NULL, NULL, true);
 
+qemu_register_reset(windbg_handle_reset, NULL);
+
 atexit(windbg_exit);
 return 0;
 }




[Qemu-devel] [PATCH v3 26/45] windbg: implemented windbg_read_context

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |   96 ++
 1 file changed, 96 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index bf1afab1f8..1fccd8eee7 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -276,6 +276,102 @@ typedef struct _CPU_KPROCESSOR_STATE {
 static int windbg_read_context(CPUState *cpu, uint8_t *buf, int buf_size,
int offset, int len)
 {
+CPUArchState *env = cpu->env_ptr;
+CPU_CONTEXT *cc;
+bool new_mem;
+
+if (len < 0 || len > buf_size) {
+WINDBG_ERROR("windbg_read_context: incorrect length %d", len);
+return 1;
+}
+
+if (offset < 0 || offset + len > sizeof(CPU_CONTEXT)) {
+WINDBG_ERROR("windbg_read_context: incorrect offset %d", offset);
+return 2;
+}
+
+new_mem = len != sizeof(CPU_CONTEXT) || offset != 0;
+if (new_mem) {
+cc = g_new0(CPU_CONTEXT, 1);
+} else {
+cc = (CPU_CONTEXT *) buf;
+memset(cc, 0, sizeof(CPU_CONTEXT));
+}
+
+cc->ContextFlags = CPU_CONTEXT_ALL;
+
+if (cc->ContextFlags & CPU_CONTEXT_SEGMENTS) {
+stw_p(>SegCs, env->segs[R_CS].selector);
+stw_p(>SegDs, env->segs[R_DS].selector);
+stw_p(>SegEs, env->segs[R_ES].selector);
+stw_p(>SegFs, env->segs[R_FS].selector);
+stw_p(>SegGs, env->segs[R_GS].selector);
+stw_p(>SegSs, env->segs[R_SS].selector);
+}
+
+if (cc->ContextFlags & CPU_CONTEXT_DEBUG_REGISTERS) {
+sttul_p(>Dr0, env->dr[0]);
+sttul_p(>Dr1, env->dr[1]);
+sttul_p(>Dr2, env->dr[2]);
+sttul_p(>Dr3, env->dr[3]);
+sttul_p(>Dr6, env->dr[6]);
+sttul_p(>Dr7, env->dr[7]);
+}
+
+if (cc->ContextFlags & CPU_CONTEXT_INTEGER) {
+stl_p(>Edi, env->regs[R_EDI]);
+stl_p(>Esi, env->regs[R_ESI]);
+stl_p(>Ebx, env->regs[R_EBX]);
+stl_p(>Edx, env->regs[R_EDX]);
+stl_p(>Ecx, env->regs[R_ECX]);
+stl_p(>Eax, env->regs[R_EAX]);
+stl_p(>Ebp, env->regs[R_EBP]);
+stl_p(>Esp, env->regs[R_ESP]);
+stl_p(>Eip, env->eip);
+stl_p(>EFlags, env->eflags);
+}
+
+if (cc->ContextFlags & CPU_CONTEXT_FLOATING_POINT) {
+uint32_t swd = 0, twd = 0;
+swd = env->fpus & ~(7 << 11);
+swd |= (env->fpstt & 7) << 11;
+int i;
+for (i = 0; i < 8; ++i) {
+twd |= (!env->fptags[i]) << i;
+}
+
+stl_p(>FloatSave.ControlWord, env->fpuc);
+stl_p(>FloatSave.StatusWord, swd);
+stl_p(>FloatSave.TagWord, twd);
+stl_p(>FloatSave.ErrorOffset, UINT32_P(>fpip)[0]);
+stl_p(>FloatSave.ErrorSelector, UINT32_P(>fpip)[1]);
+stl_p(>FloatSave.DataOffset, UINT32_P(>fpdp)[0]);
+stl_p(>FloatSave.DataSelector, UINT32_P(>fpdp)[1]);
+stl_p(>FloatSave.Cr0NpxState, env->xcr0);
+
+for (i = 0; i < 8; ++i) {
+memcpy(PTR(cc->FloatSave.RegisterArea[i * 10]),
+   PTR(env->fpregs[i]), 10);
+}
+}
+
+if (cc->ContextFlags & CPU_CONTEXT_EXTENDED_REGISTERS) {
+uint8_t *ptr = cc->ExtendedRegisters + 160;
+int i;
+for (i = 0; i < 8; ++i, ptr += 16) {
+stq_p(ptr, env->xmm_regs[i].ZMM_Q(0));
+stq_p(ptr + 8, env->xmm_regs[i].ZMM_Q(1));
+}
+
+stl_p(cc->ExtendedRegisters + 24, env->mxcsr);
+}
+
+stl_p(>ContextFlags, cc->ContextFlags);
+
+if (new_mem) {
+memcpy(buf, (uint8_t *) cc + offset, len);
+g_free(cc);
+}
 return 0;
 }
 




[Qemu-devel] [PATCH v3 42/45] windbg: implemented kd_api_fill_memory

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   39 +++
 windbgstub.c|4 
 3 files changed, 44 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index c2eb8a75a7..e144294b51 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -103,6 +103,7 @@ void kd_api_get_version(CPUState *cpu, PacketData *pd);
 void kd_api_read_msr(CPUState *cpu, PacketData *pd);
 void kd_api_write_msr(CPUState *cpu, PacketData *pd);
 void kd_api_search_memory(CPUState *cpu, PacketData *pd);
+void kd_api_fill_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 1f4590f338..fb2c378460 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -294,6 +294,45 @@ void kd_api_search_memory(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_fill_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_FILL_MEMORY *m64c = >m64.u.FillMemory;
+uint32_t len = ldl_p(>Length);
+target_ulong addr = ldq_p(>Address);
+uint16_t pattern = ldl_p(>PatternLength);
+uint16_t flags = ldl_p(>Flags);
+int err, offset = 0;
+
+uint8_t mem[pattern];
+memcpy(mem, pd->extra, pattern);
+
+pd->extra_size = 0;
+
+switch (flags) {
+case DBGKD_FILL_MEMORY_VIRTUAL:
+while (offset < len) {
+err = cpu_memory_rw_debug(cpu, addr + offset, mem,
+  MIN(pattern, len - offset), 1);
+offset += pattern;
+if (err) {
+WINDBG_DEBUG("fill_memory: No physical page mapped: " FMT_ADDR,
+ addr);
+}
+}
+break;
+
+case DBGKD_FILL_MEMORY_PHYSICAL:
+while (offset < len) {
+cpu_physical_memory_rw(addr, mem, MIN(pattern, len - offset), 1);
+offset += pattern;
+}
+break;
+
+default:
+break;
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index d35ff6ba96..b348028dfd 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -216,6 +216,10 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_search_memory(cpu, >data);
 break;
 
+case DbgKdFillMemoryApi:
+kd_api_fill_memory(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v3 10/45] windbg: structures for parsing data stream

2017-11-21 Thread Mihail Abakumov
Added structures for parsing data stream from windbg to packet.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |   11 +++
 windbgstub.c|   30 ++
 2 files changed, 41 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 42dbca1e22..2d74fb847a 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -48,6 +48,17 @@ typedef struct InitedAddr {
 bool is_init;
 } InitedAddr;
 
+typedef struct PacketData {
+union {
+struct {
+DBGKD_MANIPULATE_STATE64 m64;
+uint8_t extra[PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)];
+};
+uint8_t buf[PACKET_MAX_SIZE];
+};
+uint16_t extra_size;
+} PacketData;
+
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
diff --git a/windbgstub.c b/windbgstub.c
index e9aabd807b..395f244d4f 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -19,6 +19,36 @@
 #include "sysemu/kvm.h"
 #include "sysemu/reset.h"
 
+typedef enum ParsingState {
+STATE_LEADER,
+STATE_PACKET_TYPE,
+STATE_PACKET_BYTE_COUNT,
+STATE_PACKET_ID,
+STATE_PACKET_CHECKSUM,
+STATE_PACKET_DATA,
+STATE_TRAILING_BYTE,
+} ParsingState;
+
+typedef enum ParsingResult {
+RESULT_NONE,
+RESULT_BREAKIN_BYTE,
+RESULT_UNKNOWN_PACKET,
+RESULT_CONTROL_PACKET,
+RESULT_DATA_PACKET,
+RESULT_ERROR,
+} ParsingResult;
+
+typedef struct ParsingContext {
+/* index in the current buffer,
+   which depends on the current state */
+int index;
+ParsingState state;
+ParsingResult result;
+KD_PACKET packet;
+PacketData data;
+const char *name;
+} ParsingContext;
+
 typedef struct WindbgState {
 bool is_loaded;
 




[Qemu-devel] [PATCH v3 17/45] windbg: generate LoadSymbolsStateChange

2017-11-21 Thread Mihail Abakumov
Added function for generate LoadSymbolsStateChange packet.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |1 +
 target/i386/windbgstub.c|   15 +++
 2 files changed, 16 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index f35873eca0..8558bc6c8a 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -87,6 +87,7 @@ InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
+SizedBuf kd_gen_load_symbols_sc(CPUState *cpu);
 
 bool windbg_on_load(void);
 
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index f0edd94dde..261e441db1 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -133,4 +133,19 @@ SizedBuf kd_gen_exception_sc(CPUState *cpu)
 return buf;
 }
 
+SizedBuf kd_gen_load_symbols_sc(CPUState *cpu)
+{
+DBGKD_ANY_WAIT_STATE_CHANGE *sc;
+SizedBuf buf;
+
+SBUF_MALLOC(buf, sizeof(DBGKD_ANY_WAIT_STATE_CHANGE));
+sc = (DBGKD_ANY_WAIT_STATE_CHANGE *) buf.data;
+kd_init_state_change(cpu, sc);
+
+stl_p(>NewState, DbgKdLoadSymbolsStateChange);
+stl_p(>u.LoadSymbols.PathNameLength, 0);
+
+return buf;
+}
+
 #endif




[Qemu-devel] [PATCH v3 22/45] windbg: implemented kd_api_read_virtual_memory and kd_api_write_virtual_memory

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 ++
 windbgstub-utils.c  |   47 +++
 windbgstub.c|8 +++
 3 files changed, 57 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 28fd53039a..827aabb6d3 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -86,6 +86,8 @@ typedef struct SizedBuf {
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
+void kd_api_read_virtual_memory(CPUState *cpu, PacketData *pd);
+void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 04a7e1cc7b..1e81c37501 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -24,6 +24,53 @@ InitedAddr *windbg_get_version(void)
 return 
 }
 
+void kd_api_read_virtual_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_MEMORY64 *mem = >m64.u.ReadMemory;
+uint32_t len;
+target_ulong addr;
+int err;
+
+len = MIN(ldl_p(>TransferCount),
+PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+addr = ldtul_p(>TargetBaseAddress);
+err = cpu_memory_rw_debug(cpu, addr, pd->extra, len, 0);
+
+if (err) {
+len = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+
+WINDBG_DEBUG("read_virtual_memory: No physical page mapped: " FMT_ADDR,
+ (target_ulong) mem->TargetBaseAddress);
+}
+
+pd->extra_size = len;
+stl_p(>ActualBytesRead, len);
+}
+
+void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_WRITE_MEMORY64 *mem = >m64.u.WriteMemory;
+uint32_t len;
+target_ulong addr;
+int err;
+
+len = MIN(ldl_p(>TransferCount), pd->extra_size);
+addr = ldtul_p(>TargetBaseAddress);
+err = cpu_memory_rw_debug(cpu, addr, pd->extra, len, 1);
+
+if (err) {
+len = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+
+WINDBG_DEBUG("read_write_memory: No physical page mapped: " FMT_ADDR,
+ (target_ulong) mem->TargetBaseAddress);
+}
+
+pd->extra_size = 0;
+stl_p(>ActualBytesWritten, len);
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index 2467d2d247..1725107722 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -140,6 +140,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 
 switch (ctx->data.m64.ApiNumber) {
 
+case DbgKdReadVirtualMemoryApi:
+kd_api_read_virtual_memory(cpu, >data);
+break;
+
+case DbgKdWriteVirtualMemoryApi:
+kd_api_write_virtual_memory(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v3 31/45] windbg: implemented windbg_set_dr

2017-11-21 Thread Mihail Abakumov
Defined useful macros for breakpoints.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 target/i386/windbgstub.c |   50 +-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index c59d1401ad..14ad195107 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -14,6 +14,21 @@
 #ifndef TARGET_X86_64
 #include "exec/windbgstub-utils.h"
 
+#define IS_LOCAL_BP_ENABLED(dr7, index) (((dr7) >> ((index) * 2)) & 1)
+
+#define IS_GLOBAL_BP_ENABLED(dr7, index) (((dr7) >> ((index) * 2)) & 2)
+
+#define IS_BP_ENABLED(dr7, index) \
+(IS_LOCAL_BP_ENABLED(dr7, index) | IS_GLOBAL_BP_ENABLED(dr7, index))
+
+#define BP_TYPE(dr7, index) \
+((int) ((dr7) >> (DR7_TYPE_SHIFT + ((index) * 4))) & 3)
+
+#define BP_LEN(dr7, index) ({\
+int _len = (((dr7) >> (DR7_LEN_SHIFT + ((index) * 4))) & 3); \
+(_len == 2) ? 8 : _len + 1;  \
+})
+
 #ifdef TARGET_X86_64
 # define OFFSET_SELF_PCR 0x18
 # define OFFSET_VERS 0x108
@@ -273,9 +288,42 @@ typedef struct _CPU_KPROCESSOR_STATE {
 CPU_KSPECIAL_REGISTERS SpecialRegisters;
 } CPU_KPROCESSOR_STATE, *PCPU_KPROCESSOR_STATE;
 
-static void windbg_set_dr(CPUState *cpu, int index, target_ulong value)
+static int windbg_hw_breakpoint_insert(CPUState *cpu, int index)
+{
+return 0;
+}
+
+static int windbg_hw_breakpoint_remove(CPUState *cpu, int index)
+{
+return 0;
+}
+
+static void windbg_set_dr7(CPUState *cpu, target_ulong new_dr7)
 {}
 
+static void windbg_set_dr(CPUState *cpu, int index, target_ulong value)
+{
+CPUArchState *env = cpu->env_ptr;
+
+switch (index) {
+case 0 ... 3:
+if (IS_BP_ENABLED(env->dr[7], index) && env->dr[index] != value) {
+windbg_hw_breakpoint_remove(cpu, index);
+env->dr[index] = value;
+windbg_hw_breakpoint_insert(cpu, index);
+} else {
+env->dr[index] = value;
+}
+return;
+case 6:
+env->dr[6] = value | DR6_FIXED_1;
+return;
+case 7:
+windbg_set_dr7(cpu, value);
+return;
+}
+}
+
 static void windbg_set_sr(CPUState *cpu, int sr, uint16_t selector)
 {
 CPUArchState *env = cpu->env_ptr;




[Qemu-devel] [PATCH v3 07/45] windbg: added chardev

2017-11-21 Thread Mihail Abakumov
Added chardev for listening to windbg. Target device is a parameter in the 
'-windbg' option.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Acked-by: Alistair Francis <alistair.fran...@xilinx.com>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   30 ++
 1 file changed, 30 insertions(+)

diff --git a/windbgstub.c b/windbgstub.c
index 0863da73fd..e30b8500e0 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -20,12 +20,26 @@
 typedef struct WindbgState {
 bool is_loaded;
 
+CharBackend chr;
+
 uint32_t ctrl_packet_id;
 uint32_t data_packet_id;
 } WindbgState;
 
 static WindbgState *windbg_state;
 
+static int windbg_chr_can_receive(void *opaque)
+{
+return PACKET_MAX_SIZE;
+}
+
+static void windbg_chr_receive(void *opaque, const uint8_t *buf, int size)
+{
+if (windbg_state->is_loaded) {
+/* T0D0: parse data */
+}
+}
+
 static void windbg_exit(void)
 {
 g_free(windbg_state);
@@ -33,15 +47,31 @@ static void windbg_exit(void)
 
 int windbg_server_start(const char *device)
 {
+Chardev *chr = NULL;
+
 if (windbg_state) {
 WINDBG_ERROR("Multiple instances of windbg are not supported.");
 exit(1);
 }
 
+if (!strstart(device, "pipe:", NULL)) {
+WINDBG_ERROR("Unsupported device. Supported only pipe.");
+exit(1);
+}
+
 windbg_state = g_new0(WindbgState, 1);
 windbg_state->ctrl_packet_id = RESET_PACKET_ID;
 windbg_state->data_packet_id = INITIAL_PACKET_ID;
 
+chr = qemu_chr_new_noreplay(WINDBG, device);
+if (!chr) {
+return -1;
+}
+
+qemu_chr_fe_init(_state->chr, chr, _abort);
+qemu_chr_fe_set_handlers(_state->chr, windbg_chr_can_receive,
+ windbg_chr_receive, NULL, NULL, NULL, NULL, true);
+
 atexit(windbg_exit);
 return 0;
 }




[Qemu-devel] [PATCH v3 16/45] windbg: generate ExceptionStateChange

2017-11-21 Thread Mihail Abakumov
Added function for generate ExceptionStateChange packet.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 ++
 target/i386/windbgstub.c|   20 +++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index b729cd604e..f35873eca0 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -86,6 +86,8 @@ typedef struct SizedBuf {
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
+SizedBuf kd_gen_exception_sc(CPUState *cpu);
+
 bool windbg_on_load(void);
 
 #endif
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index a3c433f756..f0edd94dde 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -70,7 +70,6 @@ bool windbg_on_load(void)
 return true;
 }
 
-__attribute__ ((unused)) /* unused yet */
 static void kd_init_state_change(CPUState *cpu,
  DBGKD_ANY_WAIT_STATE_CHANGE *sc)
 {
@@ -115,4 +114,23 @@ static void kd_init_state_change(CPUState *cpu,
 }
 }
 
+SizedBuf kd_gen_exception_sc(CPUState *cpu)
+{
+CPUArchState *env = cpu->env_ptr;
+DBGKD_ANY_WAIT_STATE_CHANGE *sc;
+DBGKM_EXCEPTION_RECORD64 *exc;
+SizedBuf buf;
+
+SBUF_MALLOC(buf, sizeof(DBGKD_ANY_WAIT_STATE_CHANGE) + sizeof(int));
+sc = (DBGKD_ANY_WAIT_STATE_CHANGE *) buf.data;
+exc = >u.Exception.ExceptionRecord;
+kd_init_state_change(cpu, sc);
+
+stl_p(>NewState, DbgKdExceptionStateChange);
+stl_p(>ExceptionCode, 0x8003);
+sttul_p(>ExceptionAddress, env->eip);
+
+return buf;
+}
+
 #endif




[Qemu-devel] [PATCH v3 15/45] windbg: sized data buffer

2017-11-21 Thread Mihail Abakumov
Defined useful sized data buffer. It contains pointer to data and size of this 
data. Also, defined some macros for init and free.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |   16 
 1 file changed, 16 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 6ce870beb1..b729cd604e 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -67,6 +67,22 @@ typedef struct PacketData {
 uint16_t extra_size;
 } PacketData;
 
+typedef struct SizedBuf {
+uint8_t *data;
+size_t size;
+} SizedBuf;
+
+#define SBUF_INIT(buf, mem_ptr, len) do { \
+buf.data = mem_ptr;   \
+buf.size = len;   \
+} while (false)
+#define SBUF_MALLOC(buf, size) SBUF_INIT(buf, g_malloc0(size), size)
+#define SBUF_FREE(buf) do { \
+g_free(buf.data);   \
+buf.data = NULL;\
+buf.size = 0;   \
+} while (false)
+
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 




[Qemu-devel] [PATCH v3 21/45] windbg: implemented windbg_process_manipulate_packet

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 ++
 windbgstub-utils.c  |8 
 windbgstub.c|   26 +-
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 8558bc6c8a..28fd53039a 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -86,6 +86,8 @@ typedef struct SizedBuf {
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
+void kd_api_unsupported(CPUState *cpu, PacketData *pd);
+
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
 SizedBuf kd_gen_load_symbols_sc(CPUState *cpu);
 
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 347c61553a..04a7e1cc7b 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -23,3 +23,11 @@ InitedAddr *windbg_get_version(void)
 {
 return 
 }
+
+void kd_api_unsupported(CPUState *cpu, PacketData *pd)
+{
+WINDBG_ERROR("Caught unimplemented api %s",
+ KD_API_NAME(pd->m64.ApiNumber));
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+pd->extra_size = 0;
+}
diff --git a/windbgstub.c b/windbgstub.c
index 8058972dc7..2467d2d247 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -126,7 +126,31 @@ static void windbg_vm_stop(void)
 }
 
 static void windbg_process_manipulate_packet(ParsingContext *ctx)
-{}
+{
+CPUState *cpu;
+
+ctx->data.extra_size = ctx->packet.ByteCount -
+   sizeof(DBGKD_MANIPULATE_STATE64);
+ctx->data.m64.ReturnStatus = STATUS_SUCCESS;
+
+cpu = qemu_get_cpu(ctx->data.m64.Processor);
+if (cpu == NULL) {
+cpu = qemu_get_cpu(0);
+}
+
+switch (ctx->data.m64.ApiNumber) {
+
+default:
+kd_api_unsupported(cpu, >data);
+break;
+}
+
+stl_p(>data.m64.ReturnStatus, ctx->data.m64.ReturnStatus);
+
+windbg_send_data_packet(ctx->data.buf, ctx->data.extra_size +
+sizeof(DBGKD_MANIPULATE_STATE64),
+ctx->packet.PacketType);
+}
 
 static void windbg_process_data_packet(ParsingContext *ctx)
 {




[Qemu-devel] [PATCH v3 13/45] windbg: handler of parsing context

2017-11-21 Thread Mihail Abakumov
Implemented handler of parsing context.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   36 ++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/windbgstub.c b/windbgstub.c
index 8c33e0de0a..b71449e369 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -11,6 +11,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "sysemu/sysemu.h"
 #include "chardev/char.h"
 #include "chardev/char-fe.h"
 #include "qemu/cutils.h"
@@ -97,7 +98,6 @@ static void windbg_send_data_packet(uint8_t *data, uint16_t 
byte_count,
 windbg_state->data_packet_id ^= 1;
 }
 
-__attribute__ ((unused)) /* unused yet */
 static void windbg_send_control_packet(uint16_t type)
 {
 KD_PACKET packet = {
@@ -116,9 +116,41 @@ static void windbg_send_control_packet(uint16_t type)
 windbg_state->ctrl_packet_id ^= 1;
 }
 
-static void windbg_ctx_handler(ParsingContext *ctx)
+static void windbg_process_data_packet(ParsingContext *ctx)
 {}
 
+static void windbg_process_control_packet(ParsingContext *ctx)
+{}
+
+static void windbg_ctx_handler(ParsingContext *ctx)
+{
+switch (ctx->result) {
+case RESULT_NONE:
+break;
+
+case RESULT_BREAKIN_BYTE:
+vm_stop(RUN_STATE_PAUSED);
+break;
+
+case RESULT_CONTROL_PACKET:
+windbg_process_control_packet(ctx);
+break;
+
+case RESULT_DATA_PACKET:
+windbg_process_data_packet(ctx);
+break;
+
+case RESULT_UNKNOWN_PACKET:
+case RESULT_ERROR:
+windbg_state->ctrl_packet_id = 0;
+windbg_send_control_packet(PACKET_TYPE_KD_RESEND);
+break;
+
+default:
+break;
+}
+}
+
 static void windbg_read_byte(ParsingContext *ctx, uint8_t byte)
 {
 switch (ctx->state) {




[Qemu-devel] [PATCH v3 12/45] windbg: send data and control packets

2017-11-21 Thread Mihail Abakumov
Added functions for send data and control packets to windbg.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   56 
 1 file changed, 56 insertions(+)

diff --git a/windbgstub.c b/windbgstub.c
index ace992e2cb..8c33e0de0a 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -60,6 +60,62 @@ typedef struct WindbgState {
 
 static WindbgState *windbg_state;
 
+static uint32_t compute_checksum(uint8_t *data, uint16_t len)
+{
+uint32_t checksum = 0;
+while (len) {
+--len;
+checksum += *data++;
+}
+return checksum;
+}
+
+__attribute__ ((unused)) /* unused yet */
+static void windbg_send_data_packet(uint8_t *data, uint16_t byte_count,
+uint16_t type)
+{
+uint8_t trailing_byte = PACKET_TRAILING_BYTE;
+
+KD_PACKET packet = {
+.PacketLeader = PACKET_LEADER,
+.PacketType = type,
+.ByteCount = byte_count,
+.PacketId = windbg_state->data_packet_id,
+.Checksum = compute_checksum(data, byte_count)
+};
+
+stw_p(, packet.PacketType);
+stw_p(, packet.ByteCount);
+stl_p(, packet.PacketId);
+stl_p(, packet.Checksum);
+
+qemu_chr_fe_write(_state->chr, PTR(packet), sizeof(packet));
+qemu_chr_fe_write(_state->chr, data, byte_count);
+qemu_chr_fe_write(_state->chr, _byte,
+  sizeof(trailing_byte));
+
+windbg_state->data_packet_id ^= 1;
+}
+
+__attribute__ ((unused)) /* unused yet */
+static void windbg_send_control_packet(uint16_t type)
+{
+KD_PACKET packet = {
+.PacketLeader = CONTROL_PACKET_LEADER,
+.PacketType = type,
+.ByteCount = 0,
+.PacketId = windbg_state->ctrl_packet_id,
+.Checksum = 0
+};
+
+stw_p(, packet.PacketType);
+stl_p(, packet.PacketId);
+
+qemu_chr_fe_write(_state->chr, PTR(packet), sizeof(packet));
+
+windbg_state->ctrl_packet_id ^= 1;
+}
+
 static void windbg_ctx_handler(ParsingContext *ctx)
 {}
 




[Qemu-devel] [PATCH v3 19/45] windbg: implemented windbg_process_control_packet

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   26 +-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/windbgstub.c b/windbgstub.c
index dc9eba3e3c..b2d4881ee8 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -129,7 +129,31 @@ static void windbg_process_data_packet(ParsingContext *ctx)
 {}
 
 static void windbg_process_control_packet(ParsingContext *ctx)
-{}
+{
+switch (ctx->packet.PacketType) {
+case PACKET_TYPE_KD_ACKNOWLEDGE:
+break;
+
+case PACKET_TYPE_KD_RESET:
+{
+SizedBuf buf = kd_gen_load_symbols_sc(qemu_get_cpu(0));
+
+windbg_send_data_packet(buf.data, buf.size,
+PACKET_TYPE_KD_STATE_CHANGE64);
+windbg_send_control_packet(ctx->packet.PacketType);
+windbg_state->ctrl_packet_id = INITIAL_PACKET_ID;
+SBUF_FREE(buf);
+break;
+}
+default:
+WINDBG_ERROR("Caught unsupported control packet 0x%x",
+ ctx->packet.PacketType);
+
+windbg_state->ctrl_packet_id = 0;
+windbg_send_control_packet(PACKET_TYPE_KD_RESEND);
+break;
+}
+}
 
 static void windbg_ctx_handler(ParsingContext *ctx)
 {




[Qemu-devel] [PATCH v3 06/45] windbg: added WindbgState

2017-11-21 Thread Mihail Abakumov
Added definition of the WindbgState struct and its initialization.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |   28 
 1 file changed, 28 insertions(+)

diff --git a/windbgstub.c b/windbgstub.c
index 3830446988..0863da73fd 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -10,10 +10,38 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "chardev/char.h"
+#include "chardev/char-fe.h"
+#include "qemu/cutils.h"
 #include "exec/windbgstub.h"
 #include "exec/windbgstub-utils.h"
 
+typedef struct WindbgState {
+bool is_loaded;
+
+uint32_t ctrl_packet_id;
+uint32_t data_packet_id;
+} WindbgState;
+
+static WindbgState *windbg_state;
+
+static void windbg_exit(void)
+{
+g_free(windbg_state);
+}
+
 int windbg_server_start(const char *device)
 {
+if (windbg_state) {
+WINDBG_ERROR("Multiple instances of windbg are not supported.");
+exit(1);
+}
+
+windbg_state = g_new0(WindbgState, 1);
+windbg_state->ctrl_packet_id = RESET_PACKET_ID;
+windbg_state->data_packet_id = INITIAL_PACKET_ID;
+
+atexit(windbg_exit);
 return 0;
 }




[Qemu-devel] [PATCH v3 05/45] windbg: added helper features

2017-11-21 Thread Mihail Abakumov
Added some helper features for windbgstub.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |   27 +++
 include/exec/windbgstub.h   |6 ++
 2 files changed, 33 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 2390597f1f..e9f5223e94 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -13,7 +13,34 @@
 #define WINDBGSTUB_UTILS_H
 
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "log.h"
+#include "cpu.h"
 #include "exec/windbgstub.h"
 #include "exec/windbgkd.h"
 
+#define WINDBG_DEBUG(...) do { \
+if (WINDBG_DEBUG_ON) { \
+qemu_log(WINDBG ": " __VA_ARGS__); \
+qemu_log("\n");\
+}  \
+} while (false)
+
+#define WINDBG_ERROR(...) error_report(WINDBG ": " __VA_ARGS__)
+
+#define FMT_ADDR "addr:0x" TARGET_FMT_lx
+#define FMT_ERR  "Error:%d"
+
+#define UINT8_P(ptr) ((uint8_t *) (ptr))
+#define UINT32_P(ptr) ((uint32_t *) (ptr))
+#define PTR(var) UINT8_P()
+
+#define sizeof_field(type, field) sizeof(((type *) NULL)->field)
+
+#define READ_VMEM(cpu, addr, type) ({ \
+type _t;  \
+cpu_memory_rw_debug(cpu, addr, PTR(_t), sizeof(type), 0); \
+_t;   \
+})
+
 #endif
diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
index 1a6e1cc6e5..21bc552e58 100755
--- a/include/exec/windbgstub.h
+++ b/include/exec/windbgstub.h
@@ -12,6 +12,12 @@
 #ifndef WINDBGSTUB_H
 #define WINDBGSTUB_H
 
+#define WINDBG "windbg"
+
+#ifndef WINDBG_DEBUG_ON
+#define WINDBG_DEBUG_ON false
+#endif
+
 int windbg_server_start(const char *device);
 
 #endif




[Qemu-devel] [PATCH v3 03/45] windbg: modified windbgkd.h

2017-11-21 Thread Mihail Abakumov
Added useful name arrays of some defines. Not used yet. Needs for the future.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgkd.h |   75 +++
 1 file changed, 75 insertions(+)

diff --git a/include/exec/windbgkd.h b/include/exec/windbgkd.h
index b8f98925e7..40a23f8cd0 100755
--- a/include/exec/windbgkd.h
+++ b/include/exec/windbgkd.h
@@ -870,4 +870,79 @@ typedef struct _DBGKD_TRACE_IO {
} u;
 } DBGKD_TRACE_IO, *PDBGKD_TRACE_IO;
 
+__attribute__ ((unused)) /* maybe unused */
+static const char *kd_api_names[] = {
+"DbgKdReadVirtualMemoryApi",
+"DbgKdWriteVirtualMemoryApi",
+"DbgKdGetContextApi",
+"DbgKdSetContextApi",
+"DbgKdWriteBreakPointApi",
+"DbgKdRestoreBreakPointApi",
+"DbgKdContinueApi",
+"DbgKdReadControlSpaceApi",
+"DbgKdWriteControlSpaceApi",
+"DbgKdReadIoSpaceApi",
+"DbgKdWriteIoSpaceApi",
+"DbgKdRebootApi",
+"DbgKdContinueApi2",
+"DbgKdReadPhysicalMemoryApi",
+"DbgKdWritePhysicalMemoryApi",
+"DbgKdQuerySpecialCallsApi",
+"DbgKdSetSpecialCallApi",
+"DbgKdClearSpecialCallsApi",
+"DbgKdSetInternalBreakPointApi",
+"DbgKdGetInternalBreakPointApi",
+"DbgKdReadIoSpaceExtendedApi",
+"DbgKdWriteIoSpaceExtendedApi",
+"DbgKdGetVersionApi",
+"DbgKdWriteBreakPointExApi",
+"DbgKdRestoreBreakPointExApi",
+"DbgKdCauseBugCheckApi",
+"",
+"",
+"",
+"",
+"",
+"",
+"DbgKdSwitchProcessor",
+"DbgKdPageInApi",
+"DbgKdReadMachineSpecificRegister",
+"DbgKdWriteMachineSpecificRegister",
+"OldVlm1",
+"OldVlm2",
+"DbgKdSearchMemoryApi",
+"DbgKdGetBusDataApi",
+"DbgKdSetBusDataApi",
+"DbgKdCheckLowMemoryApi",
+"DbgKdClearAllInternalBreakpointsApi",
+"DbgKdFillMemoryApi",
+"DbgKdQueryMemoryApi",
+"DbgKdSwitchPartition",
+"DbgKdUnknownApi"
+};
+
+__attribute__ ((unused)) /* maybe unused */
+static const char *kd_packet_type_names[] = {
+"PACKET_TYPE_UNUSED",
+"PACKET_TYPE_KD_STATE_CHANGE32",
+"PACKET_TYPE_KD_STATE_MANIPULATE",
+"PACKET_TYPE_KD_DEBUG_IO",
+"PACKET_TYPE_KD_ACKNOWLEDGE",
+"PACKET_TYPE_KD_RESEND",
+"PACKET_TYPE_KD_RESET",
+"PACKET_TYPE_KD_STATE_CHANGE64",
+"PACKET_TYPE_KD_POLL_BREAKIN",
+"PACKET_TYPE_KD_TRACE_IO",
+"PACKET_TYPE_KD_CONTROL_REQUEST",
+"PACKET_TYPE_KD_FILE_IO",
+"PACKET_TYPE_MAX"
+};
+
+#define KD_API_NAME(id) \
+(id >= DbgKdMinimumManipulate && id < DbgKdMaximumManipulate) ? \
+kd_api_names[id - DbgKdMinimumManipulate] : \
+kd_api_names[DbgKdMaximumManipulate - DbgKdMinimumManipulate] \
+
+#define KD_PKT_TYPE_NAME(id) kd_packet_type_names[id]
+
 #endif




[Qemu-devel] [PATCH v3 11/45] windbg: parsing data stream

2017-11-21 Thread Mihail Abakumov
Added function of parsing data stream from windbg to packet.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 windbgstub.c |  111 +-
 1 file changed, 110 insertions(+), 1 deletion(-)

diff --git a/windbgstub.c b/windbgstub.c
index 395f244d4f..ace992e2cb 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -60,6 +60,105 @@ typedef struct WindbgState {
 
 static WindbgState *windbg_state;
 
+static void windbg_ctx_handler(ParsingContext *ctx)
+{}
+
+static void windbg_read_byte(ParsingContext *ctx, uint8_t byte)
+{
+switch (ctx->state) {
+case STATE_LEADER:
+ctx->result = RESULT_NONE;
+if (byte == PACKET_LEADER_BYTE || byte == CONTROL_PACKET_LEADER_BYTE) {
+if (ctx->index > 0 && byte != PTR(ctx->packet.PacketLeader)[0]) {
+ctx->index = 0;
+}
+PTR(ctx->packet.PacketLeader)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.PacketLeader)) {
+ctx->state = STATE_PACKET_TYPE;
+ctx->index = 0;
+}
+} else if (byte == BREAKIN_PACKET_BYTE) {
+ctx->result = RESULT_BREAKIN_BYTE;
+ctx->index = 0;
+} else {
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_TYPE:
+PTR(ctx->packet.PacketType)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.PacketType)) {
+ctx->packet.PacketType = lduw_p(>packet.PacketType);
+if (ctx->packet.PacketType >= PACKET_TYPE_MAX) {
+ctx->state = STATE_LEADER;
+ctx->result = RESULT_UNKNOWN_PACKET;
+} else {
+ctx->state = STATE_PACKET_BYTE_COUNT;
+}
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_BYTE_COUNT:
+PTR(ctx->packet.ByteCount)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.ByteCount)) {
+ctx->packet.ByteCount = lduw_p(>packet.ByteCount);
+ctx->state = STATE_PACKET_ID;
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_ID:
+PTR(ctx->packet.PacketId)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.PacketId)) {
+ctx->packet.PacketId = ldl_p(>packet.PacketId);
+ctx->state = STATE_PACKET_CHECKSUM;
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_CHECKSUM:
+PTR(ctx->packet.Checksum)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.Checksum)) {
+ctx->packet.Checksum = ldl_p(>packet.Checksum);
+if (ctx->packet.PacketLeader == CONTROL_PACKET_LEADER) {
+ctx->state = STATE_LEADER;
+ctx->result = RESULT_CONTROL_PACKET;
+} else if (ctx->packet.ByteCount > PACKET_MAX_SIZE) {
+ctx->state = STATE_LEADER;
+ctx->result = RESULT_ERROR;
+} else {
+ctx->state = STATE_PACKET_DATA;
+}
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_DATA:
+ctx->data.buf[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == ctx->packet.ByteCount) {
+ctx->state = STATE_TRAILING_BYTE;
+ctx->index = 0;
+}
+break;
+
+case STATE_TRAILING_BYTE:
+if (byte == PACKET_TRAILING_BYTE) {
+ctx->result = RESULT_DATA_PACKET;
+} else {
+ctx->result = RESULT_ERROR;
+}
+ctx->state = STATE_LEADER;
+break;
+}
+}
+
 static int windbg_chr_can_receive(void *opaque)
 {
 return PACKET_MAX_SIZE;
@@ -67,8 +166,18 @@ static int windbg_chr_can_receive(void *opaque)
 
 static void windbg_chr_receive(void *opaque, const uint8_t *buf, int size)
 {
+static ParsingContext ctx = {
+.state = STATE_LEADER,
+.result = RESULT_NONE,
+.name = ""
+};
+
 if (windbg_state->is_loaded) {
-/* T0D0: parse data */
+int i;
+for (i = 0; i < size; i++) {
+windbg_read_byte(, buf[i]);
+windbg_ctx_handler();
+}
 }
 }
 




[Qemu-devel] [PATCH v3 08/45] windbg: hook to wrmsr operation

2017-11-21 Thread Mihail Abakumov
Inserted hook to wrmsr operation. Windows Kernel put address on KPCR struct to 
fs/gs (x32/x64) register. Needs catch this moment and allow windbg server 
handle packets.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgstub-utils.h |2 ++
 include/exec/windbgstub.h   |1 +
 stubs/windbgstub.c  |3 +++
 target/i386/misc_helper.c   |3 +++
 target/i386/windbgstub.c|   10 ++
 windbgstub.c|   13 +
 6 files changed, 32 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index e9f5223e94..4232aeb59d 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -43,4 +43,6 @@
 _t;   \
 })
 
+bool windbg_on_load(void);
+
 #endif
diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
index 21bc552e58..309f692383 100755
--- a/include/exec/windbgstub.h
+++ b/include/exec/windbgstub.h
@@ -18,6 +18,7 @@
 #define WINDBG_DEBUG_ON false
 #endif
 
+void windbg_try_load(void);
 int windbg_server_start(const char *device);
 
 #endif
diff --git a/stubs/windbgstub.c b/stubs/windbgstub.c
index 4951f59203..bd7e2dccd1 100755
--- a/stubs/windbgstub.c
+++ b/stubs/windbgstub.c
@@ -12,6 +12,9 @@
 #include "qemu/osdep.h"
 #include "exec/windbgstub.h"
 
+void windbg_try_load(void)
+{}
+
 int windbg_server_start(const char *device)
 {
 return 0;
diff --git a/target/i386/misc_helper.c b/target/i386/misc_helper.c
index 628f64aad5..ec1fcd2899 100644
--- a/target/i386/misc_helper.c
+++ b/target/i386/misc_helper.c
@@ -24,6 +24,7 @@
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "exec/address-spaces.h"
+#include "exec/windbgstub.h"
 
 void helper_outb(CPUX86State *env, uint32_t port, uint32_t data)
 {
@@ -385,6 +386,8 @@ void helper_wrmsr(CPUX86State *env)
 /* XXX: exception? */
 break;
 }
+
+windbg_try_load();
 }
 
 void helper_rdmsr(CPUX86State *env)
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index df89e1edd8..0938f738e6 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -10,3 +10,13 @@
  */
 
 #include "qemu/osdep.h"
+
+#ifndef TARGET_X86_64
+#include "exec/windbgstub-utils.h"
+
+bool windbg_on_load(void)
+{
+return false;
+}
+
+#endif
diff --git a/windbgstub.c b/windbgstub.c
index e30b8500e0..a2a6eb81b4 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -16,6 +16,7 @@
 #include "qemu/cutils.h"
 #include "exec/windbgstub.h"
 #include "exec/windbgstub-utils.h"
+#include "sysemu/kvm.h"
 
 typedef struct WindbgState {
 bool is_loaded;
@@ -45,6 +46,13 @@ static void windbg_exit(void)
 g_free(windbg_state);
 }
 
+void windbg_try_load(void)
+{
+if (windbg_state && !windbg_state->is_loaded) {
+windbg_state->is_loaded = windbg_on_load();
+}
+}
+
 int windbg_server_start(const char *device)
 {
 Chardev *chr = NULL;
@@ -54,6 +62,11 @@ int windbg_server_start(const char *device)
 exit(1);
 }
 
+if (kvm_enabled()) {
+WINDBG_ERROR("KVM is not supported.");
+exit(1);
+}
+
 if (!strstart(device, "pipe:", NULL)) {
 WINDBG_ERROR("Unsupported device. Supported only pipe.");
 exit(1);




[Qemu-devel] [PATCH v3 04/45] windbg: added '-windbg' option

2017-11-21 Thread Mihail Abakumov
This option starts windbg server.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Acked-by: Alistair Francis <alistair.fran...@xilinx.com>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 qemu-options.hx |8 
 vl.c|8 
 2 files changed, 16 insertions(+)

diff --git a/qemu-options.hx b/qemu-options.hx
index 9f6e2adfff..1c84eb56d9 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3544,6 +3544,14 @@ Shorthand for -gdb tcp::1234, i.e. open a gdbserver on 
TCP port 1234
 (@pxref{gdb_usage}).
 ETEXI
 
+DEF("windbg", HAS_ARG, QEMU_OPTION_windbg, \
+"-windbg wait for windbg connection\n", QEMU_ARCH_I386)
+STEXI
+@item -windbg
+@findex -windbg
+Wait for windbg connection.
+ETEXI
+
 DEF("d", HAS_ARG, QEMU_OPTION_d, \
 "-d item1,...enable logging of specified items (use '-d help' for a 
list of log items)\n",
 QEMU_ARCH_ALL)
diff --git a/vl.c b/vl.c
index 8e247cc2a2..d6378cf03f 100644
--- a/vl.c
+++ b/vl.c
@@ -80,6 +80,7 @@ int main(int argc, char **argv)
 #include "sysemu/sysemu.h"
 #include "sysemu/numa.h"
 #include "exec/gdbstub.h"
+#include "exec/windbgstub.h"
 #include "qemu/timer.h"
 #include "chardev/char.h"
 #include "qemu/bitmap.h"
@@ -2436,6 +2437,7 @@ struct device_config {
 DEV_VIRTCON,   /* -virtioconsole */
 DEV_DEBUGCON,  /* -debugcon */
 DEV_GDB,   /* -gdb, -s */
+DEV_WINDBG,/* -windbg */
 DEV_SCLP,  /* s390 sclp */
 } type;
 const char *cmdline;
@@ -3445,6 +3447,9 @@ int main(int argc, char **argv, char **envp)
 case QEMU_OPTION_gdb:
 add_device_config(DEV_GDB, optarg);
 break;
+case QEMU_OPTION_windbg:
+add_device_config(DEV_WINDBG, optarg);
+break;
 case QEMU_OPTION_L:
 if (is_help_option(optarg)) {
 list_data_dirs = true;
@@ -4586,6 +4591,9 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 }
 
+if (foreach_device_config(DEV_WINDBG, windbg_server_start) < 0) {
+exit(1);
+}
 if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
 exit(1);
 if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)




[Qemu-devel] [PATCH v3 01/45] windbg: added empty windbgstub files

2017-11-21 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 Makefile.target |7 +++
 include/exec/windbgstub-utils.h |   18 ++
 include/exec/windbgstub.h   |   17 +
 stubs/Makefile.objs |1 +
 stubs/windbgstub.c  |   18 ++
 target/i386/Makefile.objs   |2 +-
 target/i386/windbgstub.c|   12 
 windbgstub-utils.c  |   12 
 windbgstub.c|   19 +++
 9 files changed, 105 insertions(+), 1 deletion(-)
 create mode 100755 include/exec/windbgstub-utils.h
 create mode 100755 include/exec/windbgstub.h
 create mode 100755 stubs/windbgstub.c
 create mode 100755 target/i386/windbgstub.c
 create mode 100755 windbgstub-utils.c
 create mode 100755 windbgstub.c

diff --git a/Makefile.target b/Makefile.target
index 7f42c45db8..6df0836509 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -148,6 +148,13 @@ obj-y += dump.o
 obj-y += migration/ram.o
 LIBS := $(libs_softmmu) $(LIBS)
 
+# WinDbg support
+ifeq ($(TARGET_NAME), i386)
+ifneq ($(TARGET_NAME), x86_64)
+obj-y += windbgstub.o windbgstub-utils.o
+endif
+endif
+
 # Hardware support
 ifeq ($(TARGET_NAME), sparc64)
 obj-y += hw/sparc64/
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
new file mode 100755
index 00..67d190bf6c
--- /dev/null
+++ b/include/exec/windbgstub-utils.h
@@ -0,0 +1,18 @@
+/*
+ * windbgstub-utils.h
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef WINDBGSTUB_UTILS_H
+#define WINDBGSTUB_UTILS_H
+
+#include "qemu/osdep.h"
+#include "exec/windbgstub.h"
+
+#endif
diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
new file mode 100755
index 00..1a6e1cc6e5
--- /dev/null
+++ b/include/exec/windbgstub.h
@@ -0,0 +1,17 @@
+/*
+ * windbgstub.h
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef WINDBGSTUB_H
+#define WINDBGSTUB_H
+
+int windbg_server_start(const char *device);
+
+#endif
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index e69c217aff..5c25a53c15 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -12,6 +12,7 @@ stub-obj-y += dump.o
 stub-obj-y += error-printf.o
 stub-obj-y += fdset.o
 stub-obj-y += gdbstub.o
+stub-obj-y += windbgstub.o
 stub-obj-y += get-vm-name.o
 stub-obj-y += iothread.o
 stub-obj-y += iothread-lock.o
diff --git a/stubs/windbgstub.c b/stubs/windbgstub.c
new file mode 100755
index 00..4951f59203
--- /dev/null
+++ b/stubs/windbgstub.c
@@ -0,0 +1,18 @@
+/*
+ * windbgstub.c
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "exec/windbgstub.h"
+
+int windbg_server_start(const char *device)
+{
+return 0;
+}
diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs
index 6a26e9d9f0..730ee04e27 100644
--- a/target/i386/Makefile.objs
+++ b/target/i386/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += helper.o cpu.o gdbstub.o xsave_helper.o
+obj-y += helper.o cpu.o gdbstub.o windbgstub.o xsave_helper.o
 obj-$(CONFIG_TCG) += translate.o
 obj-$(CONFIG_TCG) += bpt_helper.o cc_helper.o excp_helper.o fpu_helper.o
 obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o mpx_helper.o
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
new file mode 100755
index 00..df89e1edd8
--- /dev/null
+++ b/target/i386/windbgstub.c
@@ -0,0 +1,12 @@
+/*
+ * windbgstub.c
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
new file mode 100755
index 00..dc5e505c63
--- /dev/null
+++ b/windbgstub-utils.c
@@ -0,0 +1,12 @@
+/*
+ * windbgstub-utils.c
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the

[Qemu-devel] [PATCH v3 00/45] Windbg supporting

2017-11-21 Thread Mihail Abakumov
An update of:

v1: 
https://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07092.html

We made the debugger module WinDbg (like GDB) for QEMU. This is the replacement 
of the remote stub in Windows kernel. Used for remote Windows kernel debugging 
without debugging mode.

WinDbg is a multipurpose debugger for the Microsoft Windows computer operating 
system, distributed by Microsoft. Recent versions of WinDbg have been and are 
being distributed as part of the free Debugging Tools for Windows suite.

How to start debugging QEMU using WinDbg:
  Run QEMU with next option:
-windbg pipe:
  QEMU will start and pause for waiting WinDbg connection.
  Run WinDbg with next options:
-b -k com:pipe,baud=115200,port=\\.\pipe\,resets=0
  Wait for debugger connect to kernel.

Note: You can add Symbol Search Path in WinDbg such as 
srv*c:\tmp*http://msdl.microsoft.com/download/symbols.

How it works:
The WinDbg debugger has the possibility of connecting to a remote debug service 
(Kdsrv.exe) in the Windows kernel. Therefore, it is possible to connect to the 
guest system running in the QEMU emulator. Kernel debugging is possible only 
with the enabled debugging mode, may change at the same time. Our module of 
WinDbg debugger for QEMU is an alternative of the remote debugging service in 
the kernel. Thus, the debugger connects to the debugging module, not to the 
kernel of the operating system. The module obtains all the necessary 
information answering debugger requests from the QEMU emulator. At the same 
time for debugging there is no need to enable debugging mode in the kernel. 
This leads to hidden debugging. Our module supports all features of WinDbg 
regarding remote debugging, besides interception of events and exceptions. Only 
i386 is supported now.

Changed in v3:

 - Add a support of the new api functions from the WinDbg v10.

Changed in v2:

 - Move target specific code in the 'target/' directory. (Alistair Francis)
 - Change 'kd_api_fill_memory'. Made a fill of memory by line segments. Before 
that, a full array was immediately collected and written in RAM. (Ladi Prosek)
 - Change 'kd_api_search_memory'. Made a search for memory by line segments. 
(Ladi Prosek)
 - Change ld* to st* where it needs. (Ladi Prosek)
 - Add a additional check of input arguments in 'windbg_read_context' and 
'windbg_read_ks_regs'. (Ladi Prosek)
 - Fix typos. (Ladi Prosek)
 - Add a fliping back 'windbg_state->is_loaded' after reset VM.
 - Add a check to disabled kvm. It is supported yet. (Ladi Prosek)
 - Add a check to device in windbg option. Only pipe is supporting now. 
(Alistair Francis)
 - Add a check to 'ifdef' WINDBG_DEBUG_ON before define it. (Alistair Francis)
 - Replace printf to qemu_log. (Alistair Francis)
 - Fix build on s390x host. (patchew)
 - Fix code style error. (patchew)

---

Mihail Abakumov (45):
  windbg: added empty windbgstub files
  windbg: added windbg's KD header file
  windbg: modified windbgkd.h
  windbg: added '-windbg' option
  windbg: added helper features
  windbg: added WindbgState
  windbg: added chardev
  windbg: hook to wrmsr operation
  windbg: handler of fs/gs register
  windbg: structures for parsing data stream
  windbg: parsing data stream
  windbg: send data and control packets
  windbg: handler of parsing context
  windbg: init DBGKD_ANY_WAIT_STATE_CHANGE
  windbg: sized data buffer
  windbg: generate ExceptionStateChange
  windbg: generate LoadSymbolsStateChange
  windbg: windbg_vm_stop
  windbg: implemented windbg_process_control_packet
  windbg: implemented windbg_process_data_packet
  windbg: implemented windbg_process_manipulate_packet
  windbg: implemented kd_api_read_virtual_memory and 
kd_api_write_virtual_memory
  windbg: kernel's structures
  windbg: implemented kd_api_get_context and kd_api_set_context
  windbg: implemented kd_api_read_control_space and 
kd_api_write_control_space
  windbg: implemented windbg_read_context
  windbg: implemented windbg_write_context
  windbg: implemented windbg_read_ks_regs
  windbg: implemented windbg_write_ks_regs
  windbg: implemented windbg_set_sr
  windbg: implemented windbg_set_dr
  windbg: implemented windbg_set_dr7
  windbg: implemented windbg_hw_breakpoint_insert and 
windbg_hw_breakpoint_remove
  windbg: implemented kd_api_write_breakpoint and kd_api_restore_breakpoint
  windbg: debug exception subscribing
  windbg: implemented kd_api_continue
  windbg: implemented kd_api_read_io_space and kd_api_write_io_space
  windbg: implemented kd_api_read_physical_memory and 
kd_api_write_physical_memory
  windbg: implemented kd_api_get_version
  windbg: implemented kd_api_read_msr and kd_api_write_msr
  windbg: implemented kd_api_search_memory
  windbg: implemented kd_api_fill_memory
  windbg: implemented kd_api_query_memory
  windbg: added new 

[Qemu-devel] [PATCH v3 02/45] windbg: added windbg's KD header file

2017-11-21 Thread Mihail Abakumov
Header file from windbg's source code describing the main structures.

Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
---
 include/exec/windbgkd.h |  873 +++
 include/exec/windbgstub-utils.h |1 
 2 files changed, 874 insertions(+)
 create mode 100755 include/exec/windbgkd.h

diff --git a/include/exec/windbgkd.h b/include/exec/windbgkd.h
new file mode 100755
index 00..b8f98925e7
--- /dev/null
+++ b/include/exec/windbgkd.h
@@ -0,0 +1,873 @@
+/*
+ * windbgkd.h
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef WINDBGKD_H
+#define WINDBGKD_H
+
+/*
+ * Packet Size and Control Stream Size
+ */
+#define PACKET_MAX_SIZE 4096
+#define DBGKD_MAXSTREAM 16
+
+/*
+ * Magic Packet IDs
+ */
+#define INITIAL_PACKET_ID   0x8080
+#define SYNC_PACKET_ID  0x0800
+#define RESET_PACKET_ID 0x0018359b
+
+/*
+ * Magic Packet bytes
+ */
+#define BREAKIN_PACKET  0x62626262
+#define BREAKIN_PACKET_BYTE 0x62
+#define PACKET_LEADER   0x30303030
+#define PACKET_LEADER_BYTE  0x30
+#define CONTROL_PACKET_LEADER   0x69696969
+#define CONTROL_PACKET_LEADER_BYTE  0x69
+#define PACKET_TRAILING_BYTE0xaa
+
+/*
+ * Packet Types
+ */
+#define PACKET_TYPE_UNUSED  0
+#define PACKET_TYPE_KD_STATE_CHANGE32   1
+#define PACKET_TYPE_KD_STATE_MANIPULATE 2
+#define PACKET_TYPE_KD_DEBUG_IO 3
+#define PACKET_TYPE_KD_ACKNOWLEDGE  4
+#define PACKET_TYPE_KD_RESEND   5
+#define PACKET_TYPE_KD_RESET6
+#define PACKET_TYPE_KD_STATE_CHANGE64   7
+#define PACKET_TYPE_KD_POLL_BREAKIN 8
+#define PACKET_TYPE_KD_TRACE_IO 9
+#define PACKET_TYPE_KD_CONTROL_REQUEST  10
+#define PACKET_TYPE_KD_FILE_IO  11
+#define PACKET_TYPE_MAX 12
+
+/*
+ * Wait State Change Types
+ */
+#define DbgKdMinimumStateChange 0x3030
+#define DbgKdExceptionStateChange   0x3030
+#define DbgKdLoadSymbolsStateChange 0x3031
+#define DbgKdCommandStringStateChange   0x3032
+#define DbgKdMaximumStateChange 0x3033
+
+/*
+ * This is combined with the basic state change code
+ * if the state is from an alternate source
+ */
+#define DbgKdAlternateStateChange   0x0001
+
+/*
+ * Manipulate Types
+ */
+#define DbgKdMinimumManipulate  0x3130
+#define DbgKdReadVirtualMemoryApi   0x3130
+#define DbgKdWriteVirtualMemoryApi  0x3131
+#define DbgKdGetContextApi  0x3132
+#define DbgKdSetContextApi  0x3133
+#define DbgKdWriteBreakPointApi 0x3134
+#define DbgKdRestoreBreakPointApi   0x3135
+#define DbgKdContinueApi0x3136
+#define DbgKdReadControlSpaceApi0x3137
+#define DbgKdWriteControlSpaceApi   0x3138
+#define DbgKdReadIoSpaceApi 0x3139
+#define DbgKdWriteIoSpaceApi0x313a
+#define DbgKdRebootApi  0x313b
+#define DbgKdContinueApi2   0x313c
+#define DbgKdReadPhysicalMemoryApi  0x313d
+#define DbgKdWritePhysicalMemoryApi 0x313e
+#define DbgKdQuerySpecialCallsApi   0x313f
+#define DbgKdSetSpecialCallApi  0x3140
+#define DbgKdClearSpecialCallsApi   0x3141
+#define DbgKdSetInternalBreakPointApi   0x3142
+#define DbgKdGetInternalBreakPointApi   0x3143
+#define DbgKdReadIoSpaceExtendedApi 0x3144
+#define DbgKdWriteIoSpaceExtendedApi0x3145
+#define DbgKdGetVersionApi  0x3146
+#define DbgKdWriteBreakPointExApi   0x3147
+#define DbgKdRestoreBreakPointExApi 0x3148
+#define DbgKdCauseBugCheckApi   0x3149
+#define DbgKdSwitchProcessor0x3150
+#define DbgKdPageInApi  0x3151
+#define DbgKdReadMachineSpecificRegister0x3152
+#define DbgKdWriteMachineSpecificRegister   0x3153
+#define OldVlm1 0x3154
+#define OldVlm2 0x3155
+#define DbgKdSearchMemoryApi0x3156
+#define DbgKdGetBusDataApi  0x3157
+#define DbgKdSetBusDataApi  0x3158
+#define DbgKdCheckLowMemoryApi  0x3159
+#define DbgKdClearAllInternalBreakpointsApi 0

Re: [Qemu-devel] [PATCH v2 00/43] Windbg supporting

2017-11-14 Thread Mihail Abakumov

Ladi Prosek писал 2017-11-13 15:23:

On Wed, Nov 8, 2017 at 3:28 PM, Mihail Abakumov
<mikhail.abaku...@ispras.ru> wrote:

Ladi Prosek писал 2017-11-08 16:43:


On Wed, Nov 8, 2017 at 12:54 PM, Mihail Abakumov
<mikhail.abaku...@ispras.ru> wrote:


Ladi Prosek писал 2017-11-06 18:15:

In your case windbg does not send packets, more specifically, does 
not
continue to do it. What is your version of windbg. Also, windbg stub 
has

been supported only for windbg x64, yet.



Ah, so that's a pretty important piece of information and not very
intuitive given the "Only i386 is supported now." sentence in the
cover email.

Microsoft (R) Windows Debugger Version 10.0.15063.468 X86
Microsoft (R) Windows Debugger Version 10.0.15063.468 AMD64
Microsoft (R) Windows Debugger Version 10.0.16299.15 X86
Microsoft (R) Windows Debugger Version 10.0.16299.15 AMD64

are the versions I have tried. I don't see any difference between x86
and amd64, all versions never connect and crash after the second
break.

What guest OS are you running? Can you maybe zip up your QEMU 
binaries

and share them with me?

Thanks,
Ladi



Oh, it looks like a problem in the versions. I use the Windbg from 
Windows

7.
Windbg version: 6.12.0002.633 AMD64. I will try to test with your 
version.


Looks like it's the -b switch making the difference here. It was
removed in later versions of windbg.


Windbg docs (older):

-b
(Kernel mode only) This option has two effects:
1. The debugger will break into the target computer immediately upon 
connection.


2. After a reboot, the debugger will break into the target computer
once the kernel is initialized. See Crashing and Rebooting the Target
Computer for details and for other methods of changing this status.


Windbg docs (newer):

-b
This option is no longer supported.


-b makes windbg send a break-in right after connecting. Apparently
there is a short time window when the break-in will work. I can
actually successfully connect with a Win10 windbg (so without -b) if I
hit Ctrl+Break shortly after the initial handshake. This also explains
why I was able to connect once during my initial testing. I was just
lucky and hit Ctrl+Break soon enough after connecting.

By initial handshake I mean this sequence (I have added a simple
logging, should be clear what it means):

Received control PACKET_TYPE_KD_RESET
Sending data 7
Sending control 6

Newer debuggers without -b will stop here. Older debuggers with -b
will continue with:

Received RESULT_BREAKIN_BYTE
Sending data 7
Received RESULT_BREAKIN_BYTE
Sending data 7
Received data PACKET_TYPE_KD_STATE_MANIPULATE (12614)
Sending control 4
Sending data 2
Received data PACKET_TYPE_KD_STATE_MANIPULATE (12592)
Sending control 4
Sending data 2
Received data PACKET_TYPE_KD_STATE_MANIPULATE (12592)
Sending control 4
Sending data 2
...


Next step, when I have time, is to find the differences between
sending the break-in early and sending it later. Also interesting
would be recording the exchange between windbg and the target when
doing regular remote kernel debugging. I would still expect to see the
"Connected to Windows 7 7601 x86 compatible target ..." output always,
even when not breaking in immediately. The handshake is likely still
missing something.

Thanks,
Ladi


I tested the new windbg. And as it turned out, three new api appeared in 
it.
Naturally, it falls due to the fact that they are not realized. I will 
try

to implement these api.

--
Thanks,
Mihail



Re: [Qemu-devel] [PATCH v2 00/43] Windbg supporting

2017-11-08 Thread Mihail Abakumov

Ladi Prosek писал 2017-11-08 16:43:

On Wed, Nov 8, 2017 at 12:54 PM, Mihail Abakumov
<mikhail.abaku...@ispras.ru> wrote:

Ladi Prosek писал 2017-11-06 18:15:

On Mon, Oct 23, 2017 at 10:31 AM, Ladi Prosek <lpro...@redhat.com> 
wrote:


On Tue, Oct 17, 2017 at 3:08 PM, Mihail Abakumov
<mikhail.abaku...@ispras.ru> wrote:


An update of:

v1:
https://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07092.html

We made the debugger module WinDbg (like GDB) for QEMU. This is the
replacement of the remote stub in Windows kernel. Used for remote 
Windows

kernel debugging without debugging mode.

WinDbg is a multipurpose debugger for the Microsoft Windows 
computer
operating system, distributed by Microsoft. Recent versions of 
WinDbg have
been and are being distributed as part of the free Debugging Tools 
for

Windows suite.

How to start debugging QEMU using WinDbg:
  Run QEMU with next option:
-windbg pipe:
  QEMU will start and pause for waiting WinDbg connection.
  Run WinDbg with next options:
-b -k com:pipe,baud=115200,port=\\.\pipe\,resets=0
  Wait for debugger connect to kernel.

Note: You can add Symbol Search Path in WinDbg such as
srv*c:\tmp*http://msdl.microsoft.com/download/symbols.

How it works:
The WinDbg debugger has the possibility of connecting to a remote 
debug
service (Kdsrv.exe) in the Windows kernel. Therefore, it is 
possible to
connect to the guest system running in the QEMU emulator. Kernel 
debugging
is possible only with the enabled debugging mode, may change at the 
same
time. Our module of WinDbg debugger for QEMU is an alternative of 
the remote

debugging service in the kernel. Thus, the debugger connects to the
debugging module, not to the kernel of the operating system. The 
module
obtains all the necessary information answering debugger requests 
from the
QEMU emulator. At the same time for debugging there is no need to 
enable
debugging mode in the kernel. This leads to hidden debugging. Our 
module

supports all features of WinDbg regarding remote debugging, besides
interception of events and exceptions. Only i386 is supported now.

Changed in v2:

 - Move target specific code in the 'target/' directory. (Alistair
Francis)
 - Change 'kd_api_fill_memory'. Made a fill of memory by line 
segments.
Before that, a full array was immediately collected and written in 
RAM.

(Ladi Prosek)
 - Change 'kd_api_search_memory'. Made a search for memory by line
segments. (Ladi Prosek)
 - Change ld* to st* where it needs. (Ladi Prosek)
 - Add a additional check of input arguments in 
'windbg_read_context'

and 'windbg_read_ks_regs'. (Ladi Prosek)
 - Fix typos. (Ladi Prosek)
 - Add a fliping back 'windbg_state->is_loaded' after reset VM.
 - Add a check to disabled kvm. It is supported yet. (Ladi Prosek)
 - Add a check to device in windbg option. Only pipe is supporting 
now.

(Alistair Francis)
 - Add a check to 'ifdef' WINDBG_DEBUG_ON before define it. 
(Alistair

Francis)
 - Replace printf to qemu_log. (Alistair Francis)
 - Fix build on s390x host. (patchew)
 - Fix code style error. (patchew)



Thank you, I am planning to take a closer look and test the changes 
in

a week or two.

Still wondering if it is limited to Windows hosts or if it can be 
used

on Linux as well, preferably with KVM.



I haven't been able to make this work.

I've built a 32-bit QEMU for Windows with these patches and used the
command line parameters given above:

  qemu-system-i386.exe run with -windbg pipe:win7_dbg
  windbg -b -k com:pipe,baud=115200,port=\\.\pipe\win7_dbg,resets=0

The guest is a fresh install of Win7 32-bit.

FS base passes all the checks in windbg_on_load() as the guest kernel
loads and it returns true. QEMU then sends some data over the pipe.
Windbg doesn't print anything, it's still showing:

  Opened \\.\pipe\win7_dbg
  Waiting to reconnect...

Is this expected? In regular remote kernel debugging, windbg produces
a bunch of output about the target state when it attaches.

The only thing I can reasonably do at this point is Ctrl+Break. This
results in some data exchange between QEMU and windbg but nothing
really changes -- windbg still says "Waiting to reconnect...". 
Hitting

Ctrl+Break for the second time kills windbg. I tried running windbg
under windbg and was able to capture this output:

  Debug target initialization failed, 0x8000

Once I managed to make windbg actually attach (i.e. it generated the
target state output) but the QEMU process died shortly after that. I
don't know why because I haven't been able to reproduce it.

So, what am I doing wrong? Can you post your detailed steps please?

I'm pasting a dump of the pipe traffic as captured with IO Ninja. "<"
is windbg to QEMU, ">" is QEMU to windbg. QEMU initialized the stub 
at

14:57:48, the first Ctrl+Break was issued at 15:00:32 and the second
one at 15:01:10.



This is very strange.
After reading the desired addresses (windbg_on_load()), th

  1   2   3   >