* [Qemu-devel] [PATCH 2 00/39] Windbg supporting
@ 2018-12-05 12:52 Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 01/39] windbg: add empty windbgstub files Mikhail Abakumov
` (41 more replies)
0 siblings, 42 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:52 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
An update of:
v1: https://lists.gnu.org/archive/html/qemu-devel/2018-11/msg06222.html
We made the debugger module WinDbg (like GDB) for QEMU. This is the replacement
of the remote server 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:<name>
QEMU will start and pause for waiting WinDbg connection.
Run WinDbg with next options:
-b -k com:pipe,baud=115200,port=\\.\pipe\<name>,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 server
(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.
Supports i386 and x86_64 architectures.
Changed in v2:
- Fix errors in crash report. (Changbin Du)
Tested-by: Ladi Prosek <lprosek@redhat.com>
---
Mikhail Abakumov (39):
windbg: add empty windbgstub files
windbg: add windbg's KD header file
windbg: add -windbg option
windbg: add helper features
windbg: add WindbgState
windbg: add chardev
windbg: hook to wrmsr operation
windbg: implement windbg_on_load
windbg: implement find_KPCR
windbg: implement find_kdVersion
windbg: add windbg_search_vmaddr
windbg: implement find_kdDebuggerDataBlock
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 and LoadSymbolsStateChange
windbg: implement windbg_process_control_packet
windbg: implement windbg_process_data_packet
windbg: implement windbg_process_manipulate_packet
windbg: implement kd_api_read_virtual_memory and kd_api_write_virtual_memory
windbg: some kernel structures
windbg: add helper functions
windbg: [de]serialization cpu context
windbg: [de]serialization cpu spec registers
windbg: implement kd_api_get_context and kd_api_set_context
windbg: implement kd_api_get_context_ex and kd_api_set_context_ex
windbg: implement kd_api_read_control_space and kd_api_write_control_space
windbg: implement kd_api_write_breakpoint and kd_api_restore_breakpoint
windbg: debug exception subscribing
windbg: implement kd_api_continue
windbg: implement kd_api_read_io_space and kd_api_write_io_space
windbg: implement kd_api_read_physical_memory and kd_api_write_physical_memory
windbg: implement kd_api_get_version
windbg: implement kd_api_read_msr and kd_api_write_msr
windbg: implement kd_api_search_memory
windbg: implement kd_api_fill_memory
windbg: implement kd_api_query_memory
windbg: maintainers
MAINTAINERS | 12
Makefile.target | 3
cpus.c | 19 +
default-configs/i386-softmmu.mak | 1
gdbstub.c | 4
include/exec/windbgkd.h | 928 ++++++++++++++++++++++++++
include/exec/windbgstub-utils.h | 104 +++
include/exec/windbgstub.h | 25 +
include/sysemu/sysemu.h | 2
qemu-options.hx | 8
stubs/Makefile.objs | 1
stubs/windbgstub.c | 22 +
target/i386/Makefile.objs | 1
target/i386/cpu.h | 5
target/i386/misc_helper.c | 38 +
target/i386/windbgstub.c | 1368 ++++++++++++++++++++++++++++++++++++++
vl.c | 8
windbgstub-utils.c | 511 ++++++++++++++
windbgstub.c | 545 +++++++++++++++
19 files changed, 3595 insertions(+), 10 deletions(-)
create mode 100644 include/exec/windbgkd.h
create mode 100644 include/exec/windbgstub-utils.h
create mode 100644 include/exec/windbgstub.h
create mode 100644 stubs/windbgstub.c
create mode 100644 target/i386/windbgstub.c
create mode 100644 windbgstub-utils.c
create mode 100644 windbgstub.c
--
Mikhail Abakumov
^ permalink raw reply [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 01/39] windbg: add empty windbgstub files
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
@ 2018-12-05 12:52 ` Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 02/39] windbg: add windbg's KD header file Mikhail Abakumov
` (40 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:52 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
Makefile.target | 3 +++
default-configs/i386-softmmu.mak | 1 +
include/exec/windbgstub-utils.h | 18 ++++++++++++++++++
include/exec/windbgstub.h | 17 +++++++++++++++++
stubs/Makefile.objs | 1 +
stubs/windbgstub.c | 18 ++++++++++++++++++
target/i386/Makefile.objs | 1 +
target/i386/windbgstub.c | 13 +++++++++++++
windbgstub-utils.c | 12 ++++++++++++
windbgstub.c | 19 +++++++++++++++++++
10 files changed, 103 insertions(+)
create mode 100644 include/exec/windbgstub-utils.h
create mode 100644 include/exec/windbgstub.h
create mode 100644 stubs/windbgstub.c
create mode 100644 target/i386/windbgstub.c
create mode 100644 windbgstub-utils.c
create mode 100644 windbgstub.c
diff --git a/Makefile.target b/Makefile.target
index 4d56298bbf..3bf11d3366 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -147,6 +147,9 @@ obj-$(TARGET_X86_64) += win_dump.o
obj-y += migration/ram.o
LIBS := $(libs_softmmu) $(LIBS)
+# WinDbg support
+obj-$(CONFIG_WINDBGSTUB) += windbgstub.o windbgstub-utils.o
+
# Hardware support
ifeq ($(TARGET_NAME), sparc64)
obj-y += hw/sparc64/
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 64c998c4c8..5cb41a53ab 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -67,3 +67,4 @@ CONFIG_I2C=y
CONFIG_SEV=$(CONFIG_KVM)
CONFIG_VTD=y
CONFIG_AMD_IOMMU=y
+CONFIG_WINDBGSTUB=y
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
new file mode 100644
index 0000000000..11487be465
--- /dev/null
+++ b/include/exec/windbgstub-utils.h
@@ -0,0 +1,18 @@
+/*
+ * windbgstub-utils.h
+ *
+ * Copyright (c) 2010-2018 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 /* WINDBGSTUB_UTILS_H */
diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
new file mode 100644
index 0000000000..9656c152ef
--- /dev/null
+++ b/include/exec/windbgstub.h
@@ -0,0 +1,17 @@
+/*
+ * windbgstub.h
+ *
+ * Copyright (c) 2010-2018 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 /* WINDBGSTUB_H */
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 5dd0aeeec6..2158e99516 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -33,6 +33,7 @@ stub-obj-y += trace-control.o
stub-obj-y += uuid.o
stub-obj-y += vm-stop.o
stub-obj-y += vmstate.o
+stub-obj-y += windbgstub.o
stub-obj-$(CONFIG_WIN32) += fd-register.o
stub-obj-y += qmp_memory_device.o
stub-obj-y += target-monitor-defs.o
diff --git a/stubs/windbgstub.c b/stubs/windbgstub.c
new file mode 100644
index 0000000000..36ad918dad
--- /dev/null
+++ b/stubs/windbgstub.c
@@ -0,0 +1,18 @@
+/*
+ * windbgstub.c
+ *
+ * Copyright (c) 2010-2018 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 32bf966300..249b878036 100644
--- a/target/i386/Makefile.objs
+++ b/target/i386/Makefile.objs
@@ -20,3 +20,4 @@ obj-$(CONFIG_WHPX) += whpx-all.o
endif
obj-$(CONFIG_SEV) += sev.o
obj-$(call lnot,$(CONFIG_SEV)) += sev-stub.o
+obj-$(CONFIG_WINDBGSTUB) += windbgstub.o
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
new file mode 100644
index 0000000000..8caaa7cd38
--- /dev/null
+++ b/target/i386/windbgstub.c
@@ -0,0 +1,13 @@
+/*
+ * windbgstub.c
+ *
+ * Copyright (c) 2010-2018 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-utils.h"
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
new file mode 100644
index 0000000000..7f603b7f3f
--- /dev/null
+++ b/windbgstub-utils.c
@@ -0,0 +1,12 @@
+/*
+ * windbgstub-utils.c
+ *
+ * Copyright (c) 2010-2018 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 "exec/windbgstub-utils.h"
diff --git a/windbgstub.c b/windbgstub.c
new file mode 100644
index 0000000000..4673703b66
--- /dev/null
+++ b/windbgstub.c
@@ -0,0 +1,19 @@
+/*
+ * windbgstub.c
+ *
+ * Copyright (c) 2010-2018 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"
+#include "exec/windbgstub-utils.h"
+
+int windbg_server_start(const char *device)
+{
+ return 0;
+}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 02/39] windbg: add windbg's KD header file
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 01/39] windbg: add empty windbgstub files Mikhail Abakumov
@ 2018-12-05 12:52 ` Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 03/39] windbg: add -windbg option Mikhail Abakumov
` (39 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:52 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Header file from windbg's source code describing the main structures.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgkd.h | 928 +++++++++++++++++++++++++++++++++++++++
include/exec/windbgstub-utils.h | 1
2 files changed, 929 insertions(+)
create mode 100644 include/exec/windbgkd.h
diff --git a/include/exec/windbgkd.h b/include/exec/windbgkd.h
new file mode 100644
index 0000000000..63ebc4c50f
--- /dev/null
+++ b/include/exec/windbgkd.h
@@ -0,0 +1,928 @@
+/*
+ * windbgkd.h
+ *
+ * Copyright (c) 2010-2018 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 0x80800000
+#define SYNC_PACKET_ID 0x00000800
+#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_BYTE 0xaa
+
+/*
+ * 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_RESET 6
+#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 0x00003030
+#define DbgKdExceptionStateChange 0x00003030
+#define DbgKdLoadSymbolsStateChange 0x00003031
+#define DbgKdCommandStringStateChange 0x00003032
+#define DbgKdMaximumStateChange 0x00003033
+
+/*
+ * This is combined with the basic state change code
+ * if the state is from an alternate source
+ */
+#define DbgKdAlternateStateChange 0x00010000
+
+/*
+ * Manipulate Types
+ */
+#define DbgKdMinimumManipulate 0x00003130
+#define DbgKdReadVirtualMemoryApi 0x00003130
+#define DbgKdWriteVirtualMemoryApi 0x00003131
+#define DbgKdGetContextApi 0x00003132
+#define DbgKdSetContextApi 0x00003133
+#define DbgKdWriteBreakPointApi 0x00003134
+#define DbgKdRestoreBreakPointApi 0x00003135
+#define DbgKdContinueApi 0x00003136
+#define DbgKdReadControlSpaceApi 0x00003137
+#define DbgKdWriteControlSpaceApi 0x00003138
+#define DbgKdReadIoSpaceApi 0x00003139
+#define DbgKdWriteIoSpaceApi 0x0000313a
+#define DbgKdRebootApi 0x0000313b
+#define DbgKdContinueApi2 0x0000313c
+#define DbgKdReadPhysicalMemoryApi 0x0000313d
+#define DbgKdWritePhysicalMemoryApi 0x0000313e
+#define DbgKdQuerySpecialCallsApi 0x0000313f
+#define DbgKdSetSpecialCallApi 0x00003140
+#define DbgKdClearSpecialCallsApi 0x00003141
+#define DbgKdSetInternalBreakPointApi 0x00003142
+#define DbgKdGetInternalBreakPointApi 0x00003143
+#define DbgKdReadIoSpaceExtendedApi 0x00003144
+#define DbgKdWriteIoSpaceExtendedApi 0x00003145
+#define DbgKdGetVersionApi 0x00003146
+#define DbgKdWriteBreakPointExApi 0x00003147
+#define DbgKdRestoreBreakPointExApi 0x00003148
+#define DbgKdCauseBugCheckApi 0x00003149
+#define DbgKdSwitchProcessor 0x00003150
+#define DbgKdPageInApi 0x00003151
+#define DbgKdReadMachineSpecificRegister 0x00003152
+#define DbgKdWriteMachineSpecificRegister 0x00003153
+#define OldVlm1 0x00003154
+#define OldVlm2 0x00003155
+#define DbgKdSearchMemoryApi 0x00003156
+#define DbgKdGetBusDataApi 0x00003157
+#define DbgKdSetBusDataApi 0x00003158
+#define DbgKdCheckLowMemoryApi 0x00003159
+#define DbgKdClearAllInternalBreakpointsApi 0x0000315a
+#define DbgKdFillMemoryApi 0x0000315b
+#define DbgKdQueryMemoryApi 0x0000315c
+#define DbgKdSwitchPartition 0x0000315d
+#define DbgKdWriteCustomBreakpointApi 0x0000315e
+#define DbgKdGetContextExApi 0x0000315f
+#define DbgKdSetContextExApi 0x00003160
+#define DbgKdMaximumManipulate 0x00003161
+
+/*
+ * Debug I/O Types
+ */
+#define DbgKdPrintStringApi 0x00003230
+#define DbgKdGetStringApi 0x00003231
+
+/*
+ * Trace I/O Types
+ */
+#define DbgKdPrintTraceApi 0x00003330
+
+/*
+ * Control Request Types
+ */
+#define DbgKdRequestHardwareBp 0x00004300
+#define DbgKdReleaseHardwareBp 0x00004301
+
+/*
+ * File I/O Types
+ */
+#define DbgKdCreateFileApi 0x00003430
+#define DbgKdReadFileApi 0x00003431
+#define DbgKdWriteFileApi 0x00003432
+#define DbgKdCloseFileApi 0x00003433
+
+/*
+ * Control Report Flags
+ */
+#define REPORT_INCLUDES_SEGS 0x0001
+#define REPORT_STANDARD_CS 0x0002
+
+/*
+ * Protocol Versions
+ */
+#define DBGKD_64BIT_PROTOCOL_VERSION1 5
+#define DBGKD_64BIT_PROTOCOL_VERSION2 6
+
+/*
+ * Query Memory Address Spaces
+ */
+#define DBGKD_QUERY_MEMORY_VIRTUAL 0
+#define DBGKD_QUERY_MEMORY_PROCESS 0
+#define DBGKD_QUERY_MEMORY_SESSION 1
+#define DBGKD_QUERY_MEMORY_KERNEL 2
+
+/*
+ * Query Memory Flags
+ */
+#define DBGKD_QUERY_MEMORY_READ 0x01
+#define DBGKD_QUERY_MEMORY_WRITE 0x02
+#define DBGKD_QUERY_MEMORY_EXECUTE 0x04
+#define DBGKD_QUERY_MEMORY_FIXED 0x08
+
+/*
+ * Internal Breakpoint Flags
+ */
+#define DBGKD_INTERNAL_BP_FLAG_COUNTONLY 0x01
+#define DBGKD_INTERNAL_BP_FLAG_INVALID 0x02
+#define DBGKD_INTERNAL_BP_FLAG_SUSPENDED 0x04
+#define DBGKD_INTERNAL_BP_FLAG_DYING 0x08
+
+/*
+ * Fill Memory Flags
+ */
+#define DBGKD_FILL_MEMORY_VIRTUAL 0x01
+#define DBGKD_FILL_MEMORY_PHYSICAL 0x02
+
+/*
+ * Physical Memory Caching Flags
+ */
+#define DBGKD_CACHING_DEFAULT 0
+#define DBGKD_CACHING_CACHED 1
+#define DBGKD_CACHING_UNCACHED 2
+#define DBGKD_CACHING_WRITE_COMBINED 3
+
+/*
+ * Partition Switch Flags
+ */
+#define DBGKD_PARTITION_DEFAULT 0x00
+#define DBGKD_PARTITION_ALTERNATE 0x01
+
+/*
+ * AMD64 Control Space types
+ */
+#define AMD64_DEBUG_CONTROL_SPACE_KPCR 0
+#define AMD64_DEBUG_CONTROL_SPACE_KPRCB 1
+#define AMD64_DEBUG_CONTROL_SPACE_KSPECIAL 2
+#define AMD64_DEBUG_CONTROL_SPACE_KTHREAD 3
+
+/*
+ * Version flags
+ */
+#define DBGKD_VERS_FLAG_MP 0x0001
+#define DBGKD_VERS_FLAG_DATA 0x0002
+#define DBGKD_VERS_FLAG_PTR64 0x0004
+#define DBGKD_VERS_FLAG_NOMM 0x0008
+#define DBGKD_VERS_FLAG_HSS 0x0010
+#define DBGKD_VERS_FLAG_PARTITIONS 0x0020
+
+/*
+ * Image architectures
+ */
+#ifndef IMAGE_FILE_MACHINE_AMD64
+#define IMAGE_FILE_MACHINE_AMD64 0x8664
+#endif
+#ifndef IMAGE_FILE_MACHINE_ARM
+#define IMAGE_FILE_MACHINE_ARM 0x1c0
+#endif
+#ifndef IMAGE_FILE_MACHINE_EBC
+#define IMAGE_FILE_MACHINE_EBC 0xebc
+#endif
+#ifndef IMAGE_FILE_MACHINE_I386
+#define IMAGE_FILE_MACHINE_I386 0x14c
+#endif
+#ifndef IMAGE_FILE_MACHINE_IA64
+#define IMAGE_FILE_MACHINE_IA64 0x200
+#endif
+
+/*
+ * DBGKD_GET_VERSION64.Simulation
+ */
+enum {
+ DBGKD_SIMULATION_NONE,
+ DBGKD_SIMULATION_EXDI
+};
+
+/*
+ * Maximum supported number of breakpoints
+ */
+#define KD_BREAKPOINT_MAX 32
+
+typedef uint8_t boolean_t;
+typedef int32_t ntstatus_t;
+
+/*
+ * NTSTATUS
+ */
+#define NT_SUCCESS(status) ((ntstatus_t) (status) >= 0)
+#ifndef STATUS_SUCCESS
+#define STATUS_SUCCESS ((ntstatus_t) 0x00000000)
+#endif
+#ifndef DBG_CONTINUE
+#define DBG_CONTINUE ((ntstatus_t) 0x00010002)
+#endif
+#ifndef STATUS_NO_MORE_ENTRIES
+#define STATUS_NO_MORE_ENTRIES ((ntstatus_t) 0x8000001A)
+#endif
+#ifndef STATUS_UNSUCCESSFUL
+#define STATUS_UNSUCCESSFUL ((ntstatus_t) 0xC0000001)
+#endif
+#ifndef STATUS_INVALID_PARAMETER
+#define STATUS_INVALID_PARAMETER ((ntstatus_t) 0xC000000D)
+#endif
+
+/*
+ * KD Packet Structure
+ */
+typedef struct _KD_PACKET {
+ uint32_t PacketLeader;
+ uint16_t PacketType;
+ uint16_t ByteCount;
+ uint32_t PacketId;
+ uint32_t Checksum;
+} QEMU_PACKED KD_PACKET, *PKD_PACKET;
+
+/*
+ * KD Context
+ */
+typedef struct _KD_CONTEXT {
+ uint32_t KdpDefaultRetries;
+ boolean_t KdpControlCPending;
+} KD_CONTEXT, *PKD_CONTEXT;
+
+/*
+ * Control Sets for Supported Architectures
+ */
+typedef struct _X86_DBGKD_CONTROL_SET {
+ uint32_t TraceFlag;
+ uint32_t Dr7;
+ uint32_t CurrentSymbolStart;
+ uint32_t CurrentSymbolEnd;
+} X86_DBGKD_CONTROL_SET, *PX86_DBGKD_CONTROL_SET;
+
+typedef struct _ALPHA_DBGKD_CONTROL_SET {
+ uint32_t __padding;
+} ALPHA_DBGKD_CONTROL_SET, *PALPHA_DBGKD_CONTROL_SET;
+
+typedef struct _IA64_DBGKD_CONTROL_SET {
+ uint32_t Continue;
+ uint64_t CurrentSymbolStart;
+ uint64_t CurrentSymbolEnd;
+} IA64_DBGKD_CONTROL_SET, *PIA64_DBGKD_CONTROL_SET;
+
+typedef struct _AMD64_DBGKD_CONTROL_SET {
+ uint32_t TraceFlag;
+ uint64_t Dr7;
+ uint64_t CurrentSymbolStart;
+ uint64_t CurrentSymbolEnd;
+} AMD64_DBGKD_CONTROL_SET, *PAMD64_DBGKD_CONTROL_SET;
+
+typedef struct _ARM_DBGKD_CONTROL_SET {
+ uint32_t Continue;
+ uint32_t CurrentSymbolStart;
+ uint32_t CurrentSymbolEnd;
+} ARM_DBGKD_CONTROL_SET, *PARM_DBGKD_CONTROL_SET;
+
+typedef struct _DBGKD_ANY_CONTROL_SET {
+ union {
+ X86_DBGKD_CONTROL_SET X86ControlSet;
+ ALPHA_DBGKD_CONTROL_SET AlphaControlSet;
+ IA64_DBGKD_CONTROL_SET IA64ControlSet;
+ AMD64_DBGKD_CONTROL_SET Amd64ControlSet;
+ ARM_DBGKD_CONTROL_SET ARMControlSet;
+ };
+} DBGKD_ANY_CONTROL_SET, *PDBGKD_ANY_CONTROL_SET;
+
+#if defined(TARGET_I386)
+typedef X86_DBGKD_CONTROL_SET DBGKD_CONTROL_SET, *PDBGKD_CONTROL_SET;
+#elif defined(TARGET_X86_64)
+typedef AMD64_DBGKD_CONTROL_SET DBGKD_CONTROL_SET, *PDBGKD_CONTROL_SET;
+#elif defined(TARGET_ARM)
+typedef ARM_DBGKD_CONTROL_SET DBGKD_CONTROL_SET, *PDBGKD_CONTROL_SET;
+#else
+#error Unsupported Architecture
+#endif
+
+/*
+ * EXCEPTION_RECORD Structures
+ */
+typedef struct _DBGKM_EXCEPTION_RECORD32 {
+ int32_t ExceptionCode;
+ uint32_t ExceptionFlags;
+ uint32_t ExceptionRecord;
+ uint32_t ExceptionAddress;
+ uint32_t NumberParameters;
+ uint32_t ExceptionInformation[15];
+} DBGKM_EXCEPTION_RECORD32, *PDBGKM_EXCEPTION_RECORD32;
+
+typedef struct _DBGKM_EXCEPTION_RECORD64 {
+ int32_t ExceptionCode;
+ uint32_t ExceptionFlags;
+ uint64_t ExceptionRecord;
+ uint64_t ExceptionAddress;
+ uint32_t NumberParameters;
+ uint32_t __unusedAligment;
+ uint64_t ExceptionInformation[15];
+} DBGKM_EXCEPTION_RECORD64, *PDBGKM_EXCEPTION_RECORD64;
+
+/*
+ * DBGKM Structure for Exceptions
+ */
+typedef struct _DBGKM_EXCEPTION32 {
+ DBGKM_EXCEPTION_RECORD32 ExceptionRecord;
+ uint32_t FirstChance;
+} DBGKM_EXCEPTION32, *PDBGKM_EXCEPTION32;
+
+typedef struct _DBGKM_EXCEPTION64 {
+ DBGKM_EXCEPTION_RECORD64 ExceptionRecord;
+ uint32_t FirstChance;
+} DBGKM_EXCEPTION64, *PDBGKM_EXCEPTION64;
+
+/*
+ * DBGKD Structure for State Change
+ */
+typedef struct _X86_DBGKD_CONTROL_REPORT {
+ uint32_t Dr6;
+ uint32_t Dr7;
+ uint16_t InstructionCount;
+ uint16_t ReportFlags;
+ uint8_t InstructionStream[DBGKD_MAXSTREAM];
+ uint16_t SegCs;
+ uint16_t SegDs;
+ uint16_t SegEs;
+ uint16_t SegFs;
+ uint32_t EFlags;
+} X86_DBGKD_CONTROL_REPORT, *PX86_DBGKD_CONTROL_REPORT;
+
+typedef struct _ALPHA_DBGKD_CONTROL_REPORT {
+ uint32_t InstructionCount;
+ uint8_t InstructionStream[DBGKD_MAXSTREAM];
+} ALPHA_DBGKD_CONTROL_REPORT, *PALPHA_DBGKD_CONTROL_REPORT;
+
+typedef struct _IA64_DBGKD_CONTROL_REPORT {
+ uint32_t InstructionCount;
+ uint8_t InstructionStream[DBGKD_MAXSTREAM];
+} IA64_DBGKD_CONTROL_REPORT, *PIA64_DBGKD_CONTROL_REPORT;
+
+typedef struct _AMD64_DBGKD_CONTROL_REPORT {
+ uint64_t Dr6;
+ uint64_t Dr7;
+ uint32_t EFlags;
+ uint16_t InstructionCount;
+ uint16_t ReportFlags;
+ uint8_t InstructionStream[DBGKD_MAXSTREAM];
+ uint16_t SegCs;
+ uint16_t SegDs;
+ uint16_t SegEs;
+ uint16_t SegFs;
+} AMD64_DBGKD_CONTROL_REPORT, *PAMD64_DBGKD_CONTROL_REPORT;
+
+typedef struct _ARM_DBGKD_CONTROL_REPORT {
+ uint32_t Cpsr;
+ uint32_t InstructionCount;
+ uint8_t InstructionStream[DBGKD_MAXSTREAM];
+} ARM_DBGKD_CONTROL_REPORT, *PARM_DBGKD_CONTROL_REPORT;
+
+typedef struct _DBGKD_ANY_CONTROL_REPORT {
+ union {
+ X86_DBGKD_CONTROL_REPORT X86ControlReport;
+ ALPHA_DBGKD_CONTROL_REPORT AlphaControlReport;
+ IA64_DBGKD_CONTROL_REPORT IA64ControlReport;
+ AMD64_DBGKD_CONTROL_REPORT Amd64ControlReport;
+ ARM_DBGKD_CONTROL_REPORT ARMControlReport;
+ };
+} DBGKD_ANY_CONTROL_REPORT, *PDBGKD_ANY_CONTROL_REPORT;
+
+#if defined(TARGET_I386)
+typedef X86_DBGKD_CONTROL_REPORT DBGKD_CONTROL_REPORT, *PDBGKD_CONTROL_REPORT;
+#elif defined(TARGET_X86_64)
+typedef AMD64_DBGKD_CONTROL_REPORT DBGKD_CONTROL_REPORT, *PDBGKD_CONTROL_REPORT;
+#elif defined(TARGET_ARM)
+typedef ARM_DBGKD_CONTROL_REPORT DBGKD_CONTROL_REPORT, *PDBGKD_CONTROL_REPORT;
+#else
+#error Unsupported Architecture
+#endif
+
+/*
+ * DBGKD Structure for Debug I/O Type Print String
+ */
+typedef struct _DBGKD_PRINT_STRING {
+ uint32_t LengthOfString;
+} DBGKD_PRINT_STRING, *PDBGKD_PRINT_STRING;
+
+/*
+ * DBGKD Structure for Debug I/O Type Get String
+ */
+typedef struct _DBGKD_GET_STRING {
+ uint32_t LengthOfPromptString;
+ uint32_t LengthOfStringRead;
+} DBGKD_GET_STRING, *PDBGKD_GET_STRING;
+
+/*
+ * DBGKD Structure for Debug I/O
+ */
+typedef struct _DBGKD_DEBUG_IO {
+ uint32_t ApiNumber;
+ uint16_t ProcessorLevel;
+ uint16_t Processor;
+ union {
+ DBGKD_PRINT_STRING PrintString;
+ DBGKD_GET_STRING GetString;
+ } u;
+} DBGKD_DEBUG_IO, *PDBGKD_DEBUG_IO;
+
+/*
+ * DBGkD Structure for Command String
+ */
+typedef struct _DBGKD_COMMAND_STRING {
+ uint32_t Flags;
+ uint32_t Reserved1;
+ uint64_t Reserved2[7];
+} DBGKD_COMMAND_STRING, *PDBGKD_COMMAND_STRING;
+
+/*
+ * DBGKD Structure for Load Symbols
+ */
+typedef struct _DBGKD_LOAD_SYMBOLS32 {
+ uint32_t PathNameLength;
+ uint32_t BaseOfDll;
+ uint32_t ProcessId;
+ uint32_t CheckSum;
+ uint32_t SizeOfImage;
+ boolean_t UnloadSymbols;
+} DBGKD_LOAD_SYMBOLS32, *PDBGKD_LOAD_SYMBOLS32;
+
+typedef struct _DBGKD_LOAD_SYMBOLS64 {
+ uint32_t PathNameLength;
+ uint64_t BaseOfDll;
+ uint64_t ProcessId;
+ uint32_t CheckSum;
+ uint32_t SizeOfImage;
+ boolean_t UnloadSymbols;
+} DBGKD_LOAD_SYMBOLS64, *PDBGKD_LOAD_SYMBOLS64;
+
+/*
+ * DBGKD Structure for Wait State Change
+ */
+typedef struct _DBGKD_WAIT_STATE_CHANGE32 {
+ uint32_t NewState;
+ uint16_t ProcessorLevel;
+ uint16_t Processor;
+ uint32_t NumberProcessors;
+ uint32_t Thread;
+ uint32_t ProgramCounter;
+ union {
+ DBGKM_EXCEPTION32 Exception;
+ DBGKD_LOAD_SYMBOLS32 LoadSymbols;
+ } u;
+} DBGKD_WAIT_STATE_CHANGE32, *PDBGKD_WAIT_STATE_CHANGE32;
+
+typedef struct _DBGKD_WAIT_STATE_CHANGE64 {
+ uint32_t NewState;
+ uint16_t ProcessorLevel;
+ uint16_t Processor;
+ uint32_t NumberProcessors;
+ uint64_t Thread;
+ uint64_t ProgramCounter;
+ union {
+ DBGKM_EXCEPTION64 Exception;
+ DBGKD_LOAD_SYMBOLS64 LoadSymbols;
+ } u;
+} DBGKD_WAIT_STATE_CHANGE64, *PDBGKD_WAIT_STATE_CHANGE64;
+
+typedef struct _DBGKD_ANY_WAIT_STATE_CHANGE {
+ uint32_t NewState;
+ uint16_t ProcessorLevel;
+ uint16_t Processor;
+ uint32_t NumberProcessors;
+ uint64_t Thread;
+ uint64_t ProgramCounter;
+ union {
+ DBGKM_EXCEPTION64 Exception;
+ DBGKD_LOAD_SYMBOLS64 LoadSymbols;
+ DBGKD_COMMAND_STRING CommandString;
+ } u;
+ union {
+ DBGKD_CONTROL_REPORT ControlReport;
+ DBGKD_ANY_CONTROL_REPORT AnyControlReport;
+ };
+} DBGKD_ANY_WAIT_STATE_CHANGE, *PDBGKD_ANY_WAIT_STATE_CHANGE;
+
+/*
+ * DBGKD Manipulate Structures
+ */
+typedef struct _DBGKD_READ_MEMORY32 {
+ uint32_t TargetBaseAddress;
+ uint32_t TransferCount;
+ uint32_t ActualBytesRead;
+} DBGKD_READ_MEMORY32, *PDBGKD_READ_MEMORY32;
+
+typedef struct _DBGKD_READ_MEMORY64 {
+ uint64_t TargetBaseAddress;
+ uint32_t TransferCount;
+ uint32_t ActualBytesRead;
+} DBGKD_READ_MEMORY64, *PDBGKD_READ_MEMORY64;
+
+typedef struct _DBGKD_WRITE_MEMORY32 {
+ uint32_t TargetBaseAddress;
+ uint32_t TransferCount;
+ uint32_t ActualBytesWritten;
+} DBGKD_WRITE_MEMORY32, *PDBGKD_WRITE_MEMORY32;
+
+typedef struct _DBGKD_WRITE_MEMORY64 {
+ uint64_t TargetBaseAddress;
+ uint32_t TransferCount;
+ uint32_t ActualBytesWritten;
+} DBGKD_WRITE_MEMORY64, *PDBGKD_WRITE_MEMORY64;
+
+typedef struct _DBGKD_GET_CONTEXT {
+ uint32_t Unused;
+} DBGKD_GET_CONTEXT, *PDBGKD_GET_CONTEXT;
+
+typedef struct _DBGKD_SET_CONTEXT {
+ uint32_t ContextFlags;
+} DBGKD_SET_CONTEXT, *PDBGKD_SET_CONTEXT;
+
+typedef struct _DBGKD_WRITE_BREAKPOINT32 {
+ uint32_t BreakPointAddress;
+ uint32_t BreakPointHandle;
+} DBGKD_WRITE_BREAKPOINT32, *PDBGKD_WRITE_BREAKPOINT32;
+
+typedef struct _DBGKD_WRITE_BREAKPOINT64 {
+ uint64_t BreakPointAddress;
+ uint32_t BreakPointHandle;
+} DBGKD_WRITE_BREAKPOINT64, *PDBGKD_WRITE_BREAKPOINT64;
+
+typedef struct _DBGKD_RESTORE_BREAKPOINT {
+ uint32_t BreakPointHandle;
+} DBGKD_RESTORE_BREAKPOINT, *PDBGKD_RESTORE_BREAKPOINT;
+
+typedef struct _DBGKD_CONTINUE {
+ ntstatus_t ContinueStatus;
+} DBGKD_CONTINUE, *PDBGKD_CONTINUE;
+
+#pragma pack(push, 4)
+typedef struct _DBGKD_CONTINUE2 {
+ ntstatus_t ContinueStatus;
+ union {
+ DBGKD_CONTROL_SET ControlSet;
+ DBGKD_ANY_CONTROL_SET AnyControlSet;
+ };
+} DBGKD_CONTINUE2, *PDBGKD_CONTINUE2;
+#pragma pack(pop)
+
+typedef struct _DBGKD_READ_WRITE_IO32 {
+ uint32_t IoAddress;
+ uint32_t DataSize;
+ uint32_t DataValue;
+} DBGKD_READ_WRITE_IO32, *PDBGKD_READ_WRITE_IO32;
+
+typedef struct _DBGKD_READ_WRITE_IO64 {
+ uint64_t IoAddress;
+ uint32_t DataSize;
+ uint32_t DataValue;
+} DBGKD_READ_WRITE_IO64, *PDBGKD_READ_WRITE_IO64;
+
+typedef struct _DBGKD_READ_WRITE_IO_EXTENDED32 {
+ uint32_t DataSize;
+ uint32_t InterfaceType;
+ uint32_t BusNumber;
+ uint32_t AddressSpace;
+ uint32_t IoAddress;
+ uint32_t DataValue;
+} DBGKD_READ_WRITE_IO_EXTENDED32, *PDBGKD_READ_WRITE_IO_EXTENDED32;
+
+typedef struct _DBGKD_READ_WRITE_IO_EXTENDED64 {
+ uint32_t DataSize;
+ uint32_t InterfaceType;
+ uint32_t BusNumber;
+ uint32_t AddressSpace;
+ uint64_t IoAddress;
+ uint32_t DataValue;
+} DBGKD_READ_WRITE_IO_EXTENDED64, *PDBGKD_READ_WRITE_IO_EXTENDED64;
+
+typedef struct _DBGKD_READ_WRITE_MSR {
+ uint32_t Msr;
+ uint32_t DataValueLow;
+ uint32_t DataValueHigh;
+} DBGKD_READ_WRITE_MSR, *PDBGKD_READ_WRITE_MSR;
+
+typedef struct _DBGKD_QUERY_SPECIAL_CALLS {
+ uint32_t NumberOfSpecialCalls;
+} DBGKD_QUERY_SPECIAL_CALLS, *PDBGKD_QUERY_SPECIAL_CALLS;
+
+typedef struct _DBGKD_SET_SPECIAL_CALL32 {
+ uint32_t SpecialCall;
+} DBGKD_SET_SPECIAL_CALL32, *PDBGKD_SET_SPECIAL_CALL32;
+
+typedef struct _DBGKD_SET_SPECIAL_CALL64 {
+ uint64_t SpecialCall;
+} DBGKD_SET_SPECIAL_CALL64, *PDBGKD_SET_SPECIAL_CALL64;
+
+typedef struct _DBGKD_SET_INTERNAL_BREAKPOINT32 {
+ uint32_t BreakpointAddress;
+ uint32_t Flags;
+} DBGKD_SET_INTERNAL_BREAKPOINT32, *PDBGKD_SET_INTERNAL_BREAKPOINT32;
+
+typedef struct _DBGKD_SET_INTERNAL_BREAKPOINT64 {
+ uint64_t BreakpointAddress;
+ uint32_t Flags;
+} DBGKD_SET_INTERNAL_BREAKPOINT64, *PDBGKD_SET_INTERNAL_BREAKPOINT64;
+
+typedef struct _DBGKD_GET_INTERNAL_BREAKPOINT32 {
+ uint32_t BreakpointAddress;
+ uint32_t Flags;
+ uint32_t Calls;
+ uint32_t MaxCallsPerPeriod;
+ uint32_t MinInstructions;
+ uint32_t MaxInstructions;
+ uint32_t TotalInstructions;
+} DBGKD_GET_INTERNAL_BREAKPOINT32, *PDBGKD_GET_INTERNAL_BREAKPOINT32;
+
+typedef struct _DBGKD_GET_INTERNAL_BREAKPOINT64 {
+ uint64_t BreakpointAddress;
+ uint32_t Flags;
+ uint32_t Calls;
+ uint32_t MaxCallsPerPeriod;
+ uint32_t MinInstructions;
+ uint32_t MaxInstructions;
+ uint32_t TotalInstructions;
+} DBGKD_GET_INTERNAL_BREAKPOINT64, *PDBGKD_GET_INTERNAL_BREAKPOINT64;
+
+typedef struct _DBGKD_GET_VERSION32 {
+ uint16_t MajorVersion;
+ uint16_t MinorVersion;
+ uint16_t ProtocolVersion;
+ uint16_t Flags;
+ uint32_t KernBase;
+ uint32_t PsLoadedModuleList;
+ uint16_t MachineType;
+ uint16_t ThCallbackStack;
+ uint16_t NextCallback;
+ uint16_t FramePointer;
+ uint32_t KiCallUserMode;
+ uint32_t KeUserCallbackDispatcher;
+ uint32_t BreakpointWithStatus;
+ uint32_t DebuggerDataList;
+} DBGKD_GET_VERSION32, *PDBGKD_GET_VERSION32;
+
+typedef struct _DBGKD_GET_VERSION64 {
+ uint16_t MajorVersion;
+ uint16_t MinorVersion;
+ uint8_t ProtocolVersion;
+ uint8_t KdSecondaryVersion;
+ uint16_t Flags;
+ uint16_t MachineType;
+ uint8_t MaxPacketType;
+ uint8_t MaxStateChange;
+ uint8_t MaxManipulate;
+ uint8_t Simulation;
+ uint16_t Unused[1];
+ uint64_t KernBase;
+ uint64_t PsLoadedModuleList;
+ uint64_t DebuggerDataList;
+} DBGKD_GET_VERSION64, *PDBGKD_GET_VERSION64;
+
+typedef struct _DBGKD_BREAKPOINTEX {
+ uint32_t BreakPointCount;
+ ntstatus_t ContinueStatus;
+} DBGKD_BREAKPOINTEX, *PDBGKD_BREAKPOINTEX;
+
+typedef struct _DBGKD_SEARCH_MEMORY {
+ union {
+ uint64_t SearchAddress;
+ uint64_t FoundAddress;
+ };
+ uint64_t SearchLength;
+ uint32_t PatternLength;
+} DBGKD_SEARCH_MEMORY, *PDBGKD_SEARCH_MEMORY;
+
+typedef struct _DBGKD_GET_SET_BUS_DATA {
+ uint32_t BusDataType;
+ uint32_t BusNumber;
+ uint32_t SlotNumber;
+ uint32_t Offset;
+ uint32_t Length;
+} DBGKD_GET_SET_BUS_DATA, *PDBGKD_GET_SET_BUS_DATA;
+
+typedef struct _DBGKD_FILL_MEMORY {
+ uint64_t Address;
+ uint32_t Length;
+ uint16_t Flags;
+ uint16_t PatternLength;
+} DBGKD_FILL_MEMORY, *PDBGKD_FILL_MEMORY;
+
+typedef struct _DBGKD_QUERY_MEMORY {
+ uint64_t Address;
+ uint64_t Reserved;
+ uint32_t AddressSpace;
+ uint32_t Flags;
+} DBGKD_QUERY_MEMORY, *PDBGKD_QUERY_MEMORY;
+
+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
+ */
+typedef struct _DBGKD_MANIPULATE_STATE32 {
+ uint32_t ApiNumber;
+ uint16_t ProcessorLevel;
+ uint16_t Processor;
+ ntstatus_t ReturnStatus;
+ union {
+ DBGKD_READ_MEMORY32 ReadMemory;
+ DBGKD_WRITE_MEMORY32 WriteMemory;
+ DBGKD_READ_MEMORY64 ReadMemory64;
+ DBGKD_WRITE_MEMORY64 WriteMemory64;
+ DBGKD_GET_CONTEXT GetContext;
+ DBGKD_SET_CONTEXT SetContext;
+ DBGKD_WRITE_BREAKPOINT32 WriteBreakPoint;
+ DBGKD_RESTORE_BREAKPOINT RestoreBreakPoint;
+ DBGKD_CONTINUE Continue;
+ DBGKD_CONTINUE2 Continue2;
+ DBGKD_READ_WRITE_IO32 ReadWriteIo;
+ DBGKD_READ_WRITE_IO_EXTENDED32 ReadWriteIoExtended;
+ DBGKD_QUERY_SPECIAL_CALLS QuerySpecialCalls;
+ DBGKD_SET_SPECIAL_CALL32 SetSpecialCall;
+ DBGKD_SET_INTERNAL_BREAKPOINT32 SetInternalBreakpoint;
+ DBGKD_GET_INTERNAL_BREAKPOINT32 GetInternalBreakpoint;
+ DBGKD_GET_VERSION32 GetVersion32;
+ DBGKD_BREAKPOINTEX BreakPointEx;
+ DBGKD_READ_WRITE_MSR ReadWriteMsr;
+ DBGKD_SEARCH_MEMORY SearchMemory;
+ DBGKD_GET_SET_BUS_DATA GetSetBusData;
+ DBGKD_FILL_MEMORY FillMemory;
+ DBGKD_QUERY_MEMORY QueryMemory;
+ DBGKD_SWITCH_PARTITION SwitchPartition;
+ } u;
+} DBGKD_MANIPULATE_STATE32, *PDBGKD_MANIPULATE_STATE32;
+
+typedef struct _DBGKD_MANIPULATE_STATE64 {
+ uint32_t ApiNumber;
+ uint16_t ProcessorLevel;
+ uint16_t Processor;
+ ntstatus_t ReturnStatus;
+ union {
+ DBGKD_READ_MEMORY64 ReadMemory;
+ DBGKD_WRITE_MEMORY64 WriteMemory;
+ DBGKD_GET_CONTEXT GetContext;
+ DBGKD_SET_CONTEXT SetContext;
+ DBGKD_WRITE_BREAKPOINT64 WriteBreakPoint;
+ DBGKD_RESTORE_BREAKPOINT RestoreBreakPoint;
+ DBGKD_CONTINUE Continue;
+ DBGKD_CONTINUE2 Continue2;
+ DBGKD_READ_WRITE_IO64 ReadWriteIo;
+ DBGKD_READ_WRITE_IO_EXTENDED64 ReadWriteIoExtended;
+ DBGKD_QUERY_SPECIAL_CALLS QuerySpecialCalls;
+ DBGKD_SET_SPECIAL_CALL64 SetSpecialCall;
+ DBGKD_SET_INTERNAL_BREAKPOINT64 SetInternalBreakpoint;
+ DBGKD_GET_INTERNAL_BREAKPOINT64 GetInternalBreakpoint;
+ DBGKD_GET_VERSION64 GetVersion64;
+ DBGKD_BREAKPOINTEX BreakPointEx;
+ DBGKD_READ_WRITE_MSR ReadWriteMsr;
+ DBGKD_SEARCH_MEMORY SearchMemory;
+ DBGKD_GET_SET_BUS_DATA GetSetBusData;
+ 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;
+
+/*
+ * File I/O Structure
+ */
+typedef struct _DBGKD_CREATE_FILE {
+ uint32_t DesiredAccess;
+ uint32_t FileAttributes;
+ uint32_t ShareAccess;
+ uint32_t CreateDisposition;
+ uint32_t CreateOptions;
+ uint64_t Handle;
+ uint64_t Length;
+} DBGKD_CREATE_FILE, *PDBGKD_CREATE_FILE;
+
+typedef struct _DBGKD_READ_FILE {
+ uint64_t Handle;
+ uint64_t Offset;
+ uint32_t Length;
+} DBGKD_READ_FILE, *PDBGKD_READ_FILE;
+
+typedef struct _DBGKD_WRITE_FILE {
+ uint64_t Handle;
+ uint64_t Offset;
+ uint32_t Length;
+} DBGKD_WRITE_FILE, *PDBGKD_WRITE_FILE;
+
+typedef struct _DBGKD_CLOSE_FILE {
+ uint64_t Handle;
+} DBGKD_CLOSE_FILE, *PDBGKD_CLOSE_FILE;
+
+typedef struct _DBGKD_FILE_IO {
+ uint32_t ApiNumber;
+ uint32_t Status;
+ union {
+ uint64_t ReserveSpace[7];
+ DBGKD_CREATE_FILE CreateFile;
+ DBGKD_READ_FILE ReadFile;
+ DBGKD_WRITE_FILE WriteFile;
+ DBGKD_CLOSE_FILE CloseFile;
+ } u;
+} DBGKD_FILE_IO, *PDBGKD_FILE_IO;
+
+/*
+ * Control Request Structure
+ */
+typedef struct _DBGKD_REQUEST_BREAKPOINT {
+ uint32_t HardwareBreakPointNumber;
+ uint32_t Available;
+} DBGKD_REQUEST_BREAKPOINT, *PDBGKD_REQUEST_BREAKPOINT;
+
+typedef struct _DBGKD_RELEASE_BREAKPOINT {
+ uint32_t HardwareBreakPointNumber;
+ uint32_t Released;
+} DBGKD_RELEASE_BREAKPOINT, *PDBGKD_RELEASE_BREAKPOINT;
+
+typedef struct _DBGKD_CONTROL_REQUEST {
+ uint32_t ApiNumber;
+ union {
+ DBGKD_REQUEST_BREAKPOINT RequestBreakpoint;
+ DBGKD_RELEASE_BREAKPOINT ReleaseBreakpoint;
+ } u;
+} DBGKD_CONTROL_REQUEST, *PDBGKD_CONTROL_REQUEST;
+
+/*
+ * Trace I/O Structure
+ */
+typedef struct _DBGKD_PRINT_TRACE {
+ uint32_t LengthOfData;
+} DBGKD_PRINT_TRACE, *PDBGKD_PRINT_TRACE;
+
+typedef struct _DBGKD_TRACE_IO {
+ uint32_t ApiNumber;
+ uint16_t ProcessorLevel;
+ uint16_t Processor;
+ union {
+ uint64_t ReserveSpace[7];
+ DBGKD_PRINT_TRACE PrintTrace;
+ } u;
+} DBGKD_TRACE_IO, *PDBGKD_TRACE_IO;
+
+#endif /* WINDBGKD_H */
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 11487be465..e80b9cba8f 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -14,5 +14,6 @@
#include "qemu/osdep.h"
#include "exec/windbgstub.h"
+#include "exec/windbgkd.h"
#endif /* WINDBGSTUB_UTILS_H */
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 03/39] windbg: add -windbg option
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 01/39] windbg: add empty windbgstub files Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 02/39] windbg: add windbg's KD header file Mikhail Abakumov
@ 2018-12-05 12:52 ` Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 04/39] windbg: add helper features Mikhail Abakumov
` (38 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:52 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
This option starts windbg server.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@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 f7df472f43..13b1157114 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3317,6 +3317,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 fa25d1ae2d..bfcecf9a5c 100644
--- a/vl.c
+++ b/vl.c
@@ -76,6 +76,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"
@@ -2372,6 +2373,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;
@@ -3324,6 +3326,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;
@@ -4464,6 +4469,9 @@ int main(int argc, char **argv, char **envp)
qemu_opts_foreach(qemu_find_opts("mon"),
mon_init_func, NULL, &error_fatal);
+ 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)
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 04/39] windbg: add helper features
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (2 preceding siblings ...)
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 03/39] windbg: add -windbg option Mikhail Abakumov
@ 2018-12-05 12:52 ` Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 05/39] windbg: add WindbgState Mikhail Abakumov
` (37 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:52 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Add some helper features for windbgstub.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 40 +++++++++++++++++++
include/exec/windbgstub.h | 6 +++
windbgstub-utils.c | 83 +++++++++++++++++++++++++++++++++++++++
3 files changed, 129 insertions(+)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index e80b9cba8f..e7db062289 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -13,7 +13,47 @@
#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 DPRINTF(fmt, ...) \
+ do { \
+ if (WINDBG_DPRINT) { \
+ qemu_log("windbg: " fmt, ##__VA_ARGS__); \
+ } \
+ } while (0)
+
+#define WINDBG_ERROR(...) error_report("windbg: " __VA_ARGS__)
+
+#define FMT_ADDR "addr:0x" TARGET_FMT_lx
+#define FMT_ERR "Error:%d"
+
+#define PTR(var) ((uint8_t *) (&var))
+
+#define VMEM_ADDR(cpu, addr) \
+ ({ \
+ target_ulong _addr; \
+ cpu_memory_rw_debug(cpu, addr, PTR(_addr), sizeof(target_ulong), 0); \
+ ldtul_p(&_addr); \
+ })
+
+#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;
+} InitedAddr;
+
+const char *kd_api_name(int id);
+const char *kd_pkt_type_name(int id);
+
#endif /* WINDBGSTUB_UTILS_H */
diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
index 9656c152ef..576acb1ee8 100644
--- a/include/exec/windbgstub.h
+++ b/include/exec/windbgstub.h
@@ -12,6 +12,12 @@
#ifndef WINDBGSTUB_H
#define WINDBGSTUB_H
+#ifdef DEBUG_WINDBG
+#define WINDBG_DPRINT true
+#else
+#define WINDBG_DPRINT false
+#endif
+
int windbg_server_start(const char *device);
#endif /* WINDBGSTUB_H */
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 7f603b7f3f..968e5cb2dd 100644
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -10,3 +10,86 @@
*/
#include "exec/windbgstub-utils.h"
+
+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",
+ "DbgKdWriteCustomBreakpointApi",
+ "DbgKdGetContextExApi",
+ "DbgKdSetContextExApi",
+ "DbgKdUnknownApi",
+};
+
+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",
+};
+
+const char *kd_api_name(int id)
+{
+ return (id >= DbgKdMinimumManipulate && id < DbgKdMaximumManipulate)
+ ? kd_api_names[id - DbgKdMinimumManipulate]
+ : kd_api_names[DbgKdMaximumManipulate - DbgKdMinimumManipulate];
+}
+
+const char *kd_pkt_type_name(int id)
+{
+ return (id >= 0 && id < PACKET_TYPE_MAX)
+ ? kd_packet_type_names[id]
+ : kd_packet_type_names[PACKET_TYPE_MAX - 1];
+}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 05/39] windbg: add WindbgState
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (3 preceding siblings ...)
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 04/39] windbg: add helper features Mikhail Abakumov
@ 2018-12-05 12:52 ` Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 06/39] windbg: add chardev Mikhail Abakumov
` (36 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:52 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Add definition of the WindbgState struct and its initialization.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
windbgstub.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/windbgstub.c b/windbgstub.c
index 4673703b66..b073cc6a3f 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -13,7 +13,38 @@
#include "exec/windbgstub.h"
#include "exec/windbgstub-utils.h"
+typedef struct WindbgState {
+ bool is_loaded;
+ bool catched_breakin_byte;
+ uint32_t wait_packet_type;
+ uint32_t curr_packet_id;
+} WindbgState;
+
+static WindbgState *windbg_state;
+
+static void windbg_state_clean(WindbgState *state)
+{
+ state->is_loaded = false;
+ state->catched_breakin_byte = false;
+ state->wait_packet_type = 0;
+ state->curr_packet_id = INITIAL_PACKET_ID | SYNC_PACKET_ID;
+}
+
+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_clean(windbg_state);
+
+ atexit(windbg_exit);
return 0;
}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 06/39] windbg: add chardev
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (4 preceding siblings ...)
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 05/39] windbg: add WindbgState Mikhail Abakumov
@ 2018-12-05 12:52 ` Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 07/39] windbg: hook to wrmsr operation Mikhail Abakumov
` (35 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:52 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Add chardev for listening to windbg client. Target device is a parameter
in the '-windbg' option.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
windbgstub.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/windbgstub.c b/windbgstub.c
index b073cc6a3f..85e2215f73 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -10,6 +10,10 @@
*/
#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"
@@ -18,6 +22,8 @@ typedef struct WindbgState {
bool catched_breakin_byte;
uint32_t wait_packet_type;
uint32_t curr_packet_id;
+
+ CharBackend chr;
} WindbgState;
static WindbgState *windbg_state;
@@ -30,6 +36,15 @@ static void windbg_state_clean(WindbgState *state)
state->curr_packet_id = INITIAL_PACKET_ID | SYNC_PACKET_ID;
}
+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)
+{
+}
+
static void windbg_exit(void)
{
g_free(windbg_state);
@@ -37,14 +52,30 @@ 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_clean(windbg_state);
+ chr = qemu_chr_new_noreplay("windbg", device, true);
+ if (!chr) {
+ return -1;
+ }
+
+ qemu_chr_fe_init(&windbg_state->chr, chr, &error_abort);
+ qemu_chr_fe_set_handlers(&windbg_state->chr, windbg_chr_can_receive,
+ windbg_chr_receive, NULL, NULL, NULL, NULL, true);
+
atexit(windbg_exit);
return 0;
}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 07/39] windbg: hook to wrmsr operation
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (5 preceding siblings ...)
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 06/39] windbg: add chardev Mikhail Abakumov
@ 2018-12-05 12:52 ` Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 08/39] windbg: implement windbg_on_load Mikhail Abakumov
` (34 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:52 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Insert hook to wrmsr operation. Windows kernel put address on KPCR struct
to fs/gs (x32/x64) register. Needs catch this moment and allow windbgstub
handle packets from client.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 3 +++
include/exec/windbgstub.h | 2 ++
stubs/windbgstub.c | 4 ++++
target/i386/misc_helper.c | 3 +++
target/i386/windbgstub.c | 9 +++++++++
windbgstub.c | 24 ++++++++++++++++++++++++
6 files changed, 45 insertions(+)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index e7db062289..e076227b39 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -56,4 +56,7 @@ typedef struct InitedAddr {
const char *kd_api_name(int id);
const char *kd_pkt_type_name(int id);
+bool windbg_on_load(void);
+void windbg_on_reset(void);
+
#endif /* WINDBGSTUB_UTILS_H */
diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
index 576acb1ee8..daa413da41 100644
--- a/include/exec/windbgstub.h
+++ b/include/exec/windbgstub.h
@@ -18,6 +18,8 @@
#define WINDBG_DPRINT false
#endif
+void windbg_try_load(void);
+
int windbg_server_start(const char *device);
#endif /* WINDBGSTUB_H */
diff --git a/stubs/windbgstub.c b/stubs/windbgstub.c
index 36ad918dad..67205ae1f7 100644
--- a/stubs/windbgstub.c
+++ b/stubs/windbgstub.c
@@ -12,6 +12,10 @@
#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 78f2020ef2..6ae67cf885 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 8caaa7cd38..e55054c63d 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -11,3 +11,12 @@
#include "qemu/osdep.h"
#include "exec/windbgstub-utils.h"
+
+bool windbg_on_load(void)
+{
+ return false;
+}
+
+void windbg_on_reset(void)
+{
+}
diff --git a/windbgstub.c b/windbgstub.c
index 85e2215f73..d7fadda096 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -14,6 +14,8 @@
#include "chardev/char.h"
#include "chardev/char-fe.h"
#include "qemu/cutils.h"
+#include "sysemu/reset.h"
+#include "sysemu/kvm.h"
#include "exec/windbgstub.h"
#include "exec/windbgstub-utils.h"
@@ -50,6 +52,21 @@ static void windbg_exit(void)
g_free(windbg_state);
}
+static void windbg_handle_reset(void *opaque)
+{
+ windbg_state_clean(windbg_state);
+ windbg_on_reset();
+}
+
+void windbg_try_load(void)
+{
+ if (windbg_state && !windbg_state->is_loaded) {
+ if (windbg_on_load()) {
+ windbg_state->is_loaded = true;
+ }
+ }
+}
+
int windbg_server_start(const char *device)
{
Chardev *chr = NULL;
@@ -59,6 +76,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);
@@ -76,6 +98,8 @@ int windbg_server_start(const char *device)
qemu_chr_fe_set_handlers(&windbg_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;
}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 08/39] windbg: implement windbg_on_load
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (6 preceding siblings ...)
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 07/39] windbg: hook to wrmsr operation Mikhail Abakumov
@ 2018-12-05 12:52 ` Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 09/39] windbg: implement find_KPCR Mikhail Abakumov
` (33 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:52 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Define addresses that must be found on loading stage.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
target/i386/windbgstub.c | 48 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 47 insertions(+), 1 deletion(-)
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index e55054c63d..1c1631d7c1 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -12,11 +12,57 @@
#include "qemu/osdep.h"
#include "exec/windbgstub-utils.h"
+static InitedAddr KPCR;
+#ifdef TARGET_X86_64
+static InitedAddr kdDebuggerDataBlock;
+#else /* TARGET_I386 */
+static InitedAddr kdVersion;
+#endif /* TARGET_I386 */
+
+static bool find_KPCR(CPUState *cs)
+{
+ return KPCR.is_init;
+}
+
+#ifdef TARGET_X86_64
+static bool find_kdDebuggerDataBlock(CPUState *cs)
+{
+ return kdDebuggerDataBlock.is_init;
+}
+#else /* TARGET_I386 */
+static bool find_kdVersion(CPUState *cs)
+{
+ return kdVersion.is_init;
+}
+#endif /* TARGET_I386 */
+
bool windbg_on_load(void)
{
- return false;
+ CPUState *cs = qemu_get_cpu(0);
+
+ if (!find_KPCR(cs)) {
+ return false;
+ }
+
+#ifdef TARGET_X86_64
+ if (!find_kdDebuggerDataBlock(cs)) {
+ return false;
+ }
+#else
+ if (!find_kdVersion(cs)) {
+ return false;
+ }
+#endif
+
+ return true;
}
void windbg_on_reset(void)
{
+ KPCR.is_init = false;
+#ifdef TARGET_X86_64
+ kdDebuggerDataBlock.is_init = false;
+#else
+ kdVersion.is_init = false;
+#endif
}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 09/39] windbg: implement find_KPCR
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (7 preceding siblings ...)
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 08/39] windbg: implement windbg_on_load Mikhail Abakumov
@ 2018-12-05 12:52 ` Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 10/39] windbg: implement find_kdVersion Mikhail Abakumov
` (32 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:52 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
target/i386/windbgstub.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 1c1631d7c1..15a90e521c 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -12,6 +12,18 @@
#include "qemu/osdep.h"
#include "exec/windbgstub-utils.h"
+#ifdef TARGET_X86_64
+#define OFFSET_KPCR_SELF 0x18
+#else /* TARGET_I386 */
+#define OFFSET_KPCR_SELF 0x1C
+#endif /* TARGET_I386 */
+
+#ifdef TARGET_X86_64
+#define TARGET_SAFE(i386_obj, x86_64_obj) x86_64_obj
+#else /* TARGET_I386 */
+#define TARGET_SAFE(i386_obj, x86_64_obj) i386_obj
+#endif /* TARGET_I386 */
+
static InitedAddr KPCR;
#ifdef TARGET_X86_64
static InitedAddr kdDebuggerDataBlock;
@@ -21,6 +33,26 @@ static InitedAddr kdVersion;
static bool find_KPCR(CPUState *cs)
{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ if (!KPCR.is_init) {
+ KPCR.addr = env->segs[TARGET_SAFE(R_FS, R_GS)].base;
+
+ static target_ulong prev_KPCR;
+ if (!KPCR.addr || prev_KPCR == KPCR.addr) {
+ return false;
+ }
+ prev_KPCR = KPCR.addr;
+
+ if (KPCR.addr != VMEM_ADDR(cs, KPCR.addr + OFFSET_KPCR_SELF)) {
+ return false;
+ }
+ KPCR.is_init = true;
+
+ DPRINTF("find KPCR " FMT_ADDR "\n", KPCR.addr);
+ }
+
return KPCR.is_init;
}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 10/39] windbg: implement find_kdVersion
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (8 preceding siblings ...)
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 09/39] windbg: implement find_KPCR Mikhail Abakumov
@ 2018-12-05 12:52 ` Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 11/39] windbg: add windbg_search_vmaddr Mikhail Abakumov
` (31 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:52 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
target/i386/windbgstub.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 15a90e521c..dc58f5a8cc 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -16,6 +16,7 @@
#define OFFSET_KPCR_SELF 0x18
#else /* TARGET_I386 */
#define OFFSET_KPCR_SELF 0x1C
+#define OFFSET_KPCR_VERSION 0x34
#endif /* TARGET_I386 */
#ifdef TARGET_X86_64
@@ -64,6 +65,16 @@ static bool find_kdDebuggerDataBlock(CPUState *cs)
#else /* TARGET_I386 */
static bool find_kdVersion(CPUState *cs)
{
+ if (!kdVersion.is_init && KPCR.is_init) {
+ kdVersion.addr = VMEM_ADDR(cs, KPCR.addr + OFFSET_KPCR_VERSION);
+ if (!kdVersion.addr) {
+ return false;
+ }
+ kdVersion.is_init = true;
+
+ DPRINTF("find kdVersion " FMT_ADDR, kdVersion.addr);
+ }
+
return kdVersion.is_init;
}
#endif /* TARGET_I386 */
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 11/39] windbg: add windbg_search_vmaddr
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (9 preceding siblings ...)
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 10/39] windbg: implement find_kdVersion Mikhail Abakumov
@ 2018-12-05 12:53 ` Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 12/39] windbg: implement find_kdDebuggerDataBlock Mikhail Abakumov
` (30 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:53 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Add function to search in virtual memory.
Implemented Boyer-Moore search algorithm.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 4 +
windbgstub-utils.c | 120 +++++++++++++++++++++++++++++++++++++++
2 files changed, 124 insertions(+)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index e076227b39..2760684cfb 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -59,4 +59,8 @@ const char *kd_pkt_type_name(int id);
bool windbg_on_load(void);
void windbg_on_reset(void);
+InitedAddr windbg_search_vmaddr(CPUState *cs, target_ulong start,
+ target_ulong finish, const uint8_t *pattern,
+ int pLen);
+
#endif /* WINDBGSTUB_UTILS_H */
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 968e5cb2dd..6d2bb33307 100644
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -80,6 +80,126 @@ static const char *kd_packet_type_names[] = {
"PACKET_TYPE_MAX",
};
+static void prep_bmbc(const uint8_t *pattern, int pLen, int bmBc[])
+{
+ int i;
+
+ for (i = 0; i < 256; ++i) {
+ bmBc[i] = pLen;
+ }
+ for (i = 0; i < pLen - 1; ++i) {
+ bmBc[pattern[i]] = pLen - i - 1;
+ }
+}
+
+static void prep_suffixes(const uint8_t *pattern, int pLen, int *suff)
+{
+ int f, g, i;
+
+ suff[pLen - 1] = pLen;
+ f = 0;
+ g = pLen - 1;
+ for (i = pLen - 2; i >= 0; --i) {
+ if (i > g && suff[i + pLen - 1 - f] < i - g) {
+ suff[i] = suff[i + pLen - 1 - f];
+ } else {
+ if (i < g) {
+ g = i;
+ }
+ f = i;
+ while (g >= 0 && pattern[g] == pattern[g + pLen - 1 - f]) {
+ --g;
+ }
+ suff[i] = f - g;
+ }
+ }
+}
+
+static void prep_bmgs(const uint8_t *pattern, int pLen, int bmGs[])
+{
+ int i, j, suff[pLen];
+
+ prep_suffixes(pattern, pLen, suff);
+
+ for (i = 0; i < pLen; ++i) {
+ bmGs[i] = pLen;
+ }
+
+ j = 0;
+ for (i = pLen - 1; i >= 0; --i) {
+ if (suff[i] == i + 1) {
+ for (; j < pLen - 1 - i; ++j) {
+ if (bmGs[j] == pLen) {
+ bmGs[j] = pLen - 1 - i;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i <= pLen - 2; ++i) {
+ bmGs[pLen - 1 - suff[i]] = pLen - 1 - i;
+ }
+}
+
+static int search_boyermoore(const uint8_t *data, int dLen,
+ const uint8_t *pattern, int pLen, int bmGs[],
+ int bmBc[])
+{
+ int i;
+ int j = 0;
+ while (j <= dLen - pLen) {
+ i = pLen - 1;
+ while (i >= 0 && pattern[i] == data[i + j]) {
+ --i;
+ }
+ if (i < 0) {
+ return j;
+ } else {
+ j += MAX(bmGs[i], bmBc[data[i + j]] - pLen + 1 + i);
+ }
+ }
+ return -1;
+}
+
+InitedAddr windbg_search_vmaddr(CPUState *cs, target_ulong start,
+ target_ulong finish, const uint8_t *pattern,
+ int pLen)
+{
+ InitedAddr ret = {
+ addr = 0;
+ is_init = false;
+ };
+ int bmGs[pLen], bmBc[256];
+ int find;
+ target_ulong offset = start;
+ target_ulong step = MIN(MAX(finish - start, 0x10000), pLen * 2);
+
+ if (finish <= start || pLen > finish - start) {
+ return ret;
+ }
+
+ uint8_t *buf = g_new(uint8_t, step);
+
+ prep_bmgs(pattern, pLen, bmGs);
+ prep_bmbc(pattern, pLen, bmBc);
+
+ while (offset < finish) {
+ step = MIN(step, finish - offset);
+ if (cpu_memory_rw_debug(cs, offset, buf, step, 0) == 0) {
+ find = search_boyermoore(buf, step, pattern, pLen, bmGs, bmBc);
+ if (find >= 0) {
+ ret.addr = offset + find;
+ ret.is_init = true;
+ break;
+ }
+ }
+ offset += step - pLen;
+ }
+
+ g_free(buf);
+ return ret;
+}
+
const char *kd_api_name(int id)
{
return (id >= DbgKdMinimumManipulate && id < DbgKdMaximumManipulate)
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 12/39] windbg: implement find_kdDebuggerDataBlock
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (10 preceding siblings ...)
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 11/39] windbg: add windbg_search_vmaddr Mikhail Abakumov
@ 2018-12-05 12:53 ` Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 13/39] windbg: parsing data stream Mikhail Abakumov
` (29 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:53 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
It is necessary to find address on the structure kdDebuggerDataBlock,
which is located somewhere at kernel .data section.
We can find it in structure defined in kernel:
typedef struct _DBGKD_DEBUG_DATA_HEADER
{
LIST_ENTRY64 List;
ULONG OwnerTag;
ULONG Size;
} DBGKD_DEBUG_DATA_HEADER, *PDBGKD_DEBUG_DATA_HEEADER;
where OwnerTag == 'KDBG',
then List == kdDebuggerDataBlock.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
target/i386/windbgstub.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index dc58f5a8cc..f1bab10b10 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -14,6 +14,7 @@
#ifdef TARGET_X86_64
#define OFFSET_KPCR_SELF 0x18
+#define OFFSET_KPCR_LOCK_ARRAY 0x28
#else /* TARGET_I386 */
#define OFFSET_KPCR_SELF 0x1C
#define OFFSET_KPCR_VERSION 0x34
@@ -60,6 +61,52 @@ static bool find_KPCR(CPUState *cs)
#ifdef TARGET_X86_64
static bool find_kdDebuggerDataBlock(CPUState *cs)
{
+ target_ulong lockArray;
+ target_ulong dDataList;
+ const uint8_t tag[] = { 'K', 'D', 'B', 'G' };
+ target_ulong start = 0xfffff80000000000LL;
+ target_ulong finish = 0xfffff81000000000LL;
+ InitedAddr find;
+
+ /* kdDebuggerDataBlock is located in
+ - range of [0xfffff80000000000 ... 0xfffff81000000000]
+ - at offset of ('KDBG') - 0x10 */
+
+ if (!kdDebuggerDataBlock.is_init && KPCR.is_init) {
+ /* At first, find lockArray. If it is NULL,
+ then kdDebuggerDataBlock is also NULL (empirically). */
+ lockArray = VMEM_ADDR(cs, KPCR.addr + OFFSET_KPCR_LOCK_ARRAY);
+ if (!lockArray) {
+ return false;
+ }
+ DPRINTF("find LockArray " FMT_ADDR "\n", lockArray);
+
+ while (true) {
+ find = windbg_search_vmaddr(cs, start, finish, tag,
+ ARRAY_SIZE(tag));
+ if (!find.is_init) {
+ return false;
+ }
+
+ /* Valid address to 'KDBG ' is always aligned */
+ if (!(find.addr & 0xf)) {
+ dDataList = VMEM_ADDR(cs, find.addr - 0x10);
+
+ /* Valid address to 'dDataList ' is always
+ in range [0xfffff80000000000 ... 0xfffff8ffffffffff] */
+ if ((dDataList >> 40) == 0xfffff8) {
+ kdDebuggerDataBlock.addr = find.addr - 0x10;
+ kdDebuggerDataBlock.is_init = true;
+ DPRINTF("find kdDebuggerDataBlock " FMT_ADDR "\n",
+ kdDebuggerDataBlock.addr);
+ break;
+ }
+ }
+
+ start = find.addr + 0x8; /* next addr */
+ }
+ }
+
return kdDebuggerDataBlock.is_init;
}
#else /* TARGET_I386 */
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 13/39] windbg: parsing data stream
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (11 preceding siblings ...)
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 12/39] windbg: implement find_kdDebuggerDataBlock Mikhail Abakumov
@ 2018-12-05 12:53 ` Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 14/39] windbg: send data and control packets Mikhail Abakumov
` (28 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:53 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Add parsing data stream to packets from windbg client.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 11 +++
windbgstub.c | 139 +++++++++++++++++++++++++++++++++++++++
2 files changed, 150 insertions(+)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 2760684cfb..a28068eecd 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -53,6 +53,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;
+
const char *kd_api_name(int id);
const char *kd_pkt_type_name(int id);
diff --git a/windbgstub.c b/windbgstub.c
index d7fadda096..2869d94389 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -19,12 +19,43 @@
#include "exec/windbgstub.h"
#include "exec/windbgstub-utils.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;
bool catched_breakin_byte;
uint32_t wait_packet_type;
uint32_t curr_packet_id;
+ ParsingContext ctx;
CharBackend chr;
} WindbgState;
@@ -36,6 +67,108 @@ static void windbg_state_clean(WindbgState *state)
state->catched_breakin_byte = false;
state->wait_packet_type = 0;
state->curr_packet_id = INITIAL_PACKET_ID | SYNC_PACKET_ID;
+ state->ctx.state = STATE_LEADER;
+ state->ctx.result = RESULT_NONE;
+}
+
+static void windbg_ctx_handler(WindbgState *state)
+{
+}
+
+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(&ctx->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(&ctx->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(&ctx->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(&ctx->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)
@@ -45,6 +178,11 @@ static int windbg_chr_can_receive(void *opaque)
static void windbg_chr_receive(void *opaque, const uint8_t *buf, int size)
{
+ int i;
+ for (i = 0; i < size; i++) {
+ windbg_read_byte(&windbg_state->ctx, buf[i]);
+ windbg_ctx_handler(windbg_state);
+ }
}
static void windbg_exit(void)
@@ -87,6 +225,7 @@ int windbg_server_start(const char *device)
}
windbg_state = g_new0(WindbgState, 1);
+ windbg_state->ctx.name = "Windbg";
windbg_state_clean(windbg_state);
chr = qemu_chr_new_noreplay("windbg", device, true);
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 14/39] windbg: send data and control packets
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (12 preceding siblings ...)
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 13/39] windbg: parsing data stream Mikhail Abakumov
@ 2018-12-05 12:53 ` Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 15/39] windbg: handler of parsing context Mikhail Abakumov
` (27 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:53 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
windbgstub.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/windbgstub.c b/windbgstub.c
index 2869d94389..c45faec43f 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -71,6 +71,65 @@ static void windbg_state_clean(WindbgState *state)
state->ctx.result = RESULT_NONE;
}
+static uint32_t compute_checksum(uint8_t *data, uint16_t len)
+{
+ uint32_t checksum = 0;
+ while (len) {
+ --len;
+ checksum += *data++;
+ }
+ return checksum;
+}
+
+static void windbg_store_packet(KD_PACKET *packet)
+{
+ stw_p(&packet->PacketLeader, packet->PacketLeader);
+ stw_p(&packet->PacketType, packet->PacketType);
+ stw_p(&packet->ByteCount, packet->ByteCount);
+ stl_p(&packet->PacketId, packet->PacketId);
+ stl_p(&packet->Checksum, packet->Checksum);
+}
+
+__attribute__ ((unused)) /* unused yet */
+static void windbg_send_data_packet(WindbgState *state, uint8_t *data,
+ uint16_t byte_count, uint16_t type)
+{
+ const uint8_t trailing_byte = PACKET_TRAILING_BYTE;
+
+ KD_PACKET packet = {
+ .PacketLeader = PACKET_LEADER,
+ .PacketType = type,
+ .ByteCount = byte_count,
+ .PacketId = state->curr_packet_id,
+ .Checksum = compute_checksum(data, byte_count),
+ };
+
+ windbg_store_packet(&packet);
+
+ 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, &trailing_byte, sizeof(trailing_byte));
+
+ state->wait_packet_type = PACKET_TYPE_KD_ACKNOWLEDGE;
+}
+
+__attribute__ ((unused)) /* unused yet */
+static void windbg_send_control_packet(WindbgState *state, uint16_t type,
+ uint32_t id)
+{
+ KD_PACKET packet = {
+ .PacketLeader = CONTROL_PACKET_LEADER,
+ .PacketType = type,
+ .ByteCount = 0,
+ .PacketId = id,
+ .Checksum = 0,
+ };
+
+ windbg_store_packet(&packet);
+
+ qemu_chr_fe_write(&state->chr, PTR(packet), sizeof(packet));
+}
+
static void windbg_ctx_handler(WindbgState *state)
{
}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 15/39] windbg: handler of parsing context
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (13 preceding siblings ...)
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 14/39] windbg: send data and control packets Mikhail Abakumov
@ 2018-12-05 12:53 ` Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 16/39] windbg: init DBGKD_ANY_WAIT_STATE_CHANGE Mikhail Abakumov
` (26 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:53 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
windbgstub.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/windbgstub.c b/windbgstub.c
index c45faec43f..fe0b007a06 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -15,6 +15,7 @@
#include "chardev/char-fe.h"
#include "qemu/cutils.h"
#include "sysemu/reset.h"
+#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "exec/windbgstub.h"
#include "exec/windbgstub-utils.h"
@@ -113,7 +114,6 @@ static void windbg_send_data_packet(WindbgState *state, uint8_t *data,
state->wait_packet_type = PACKET_TYPE_KD_ACKNOWLEDGE;
}
-__attribute__ ((unused)) /* unused yet */
static void windbg_send_control_packet(WindbgState *state, uint16_t type,
uint32_t id)
{
@@ -130,8 +130,52 @@ static void windbg_send_control_packet(WindbgState *state, uint16_t type,
qemu_chr_fe_write(&state->chr, PTR(packet), sizeof(packet));
}
+static void windbg_vm_stop(void)
+{
+ vm_stop(RUN_STATE_PAUSED);
+}
+
+static void windbg_process_data_packet(WindbgState *state)
+{
+}
+
+static void windbg_process_control_packet(WindbgState *state)
+{
+}
+
static void windbg_ctx_handler(WindbgState *state)
{
+ if (!state->is_loaded) {
+ if (state->ctx.result == RESULT_BREAKIN_BYTE) {
+ state->catched_breakin_byte = true;
+ }
+ return;
+ }
+
+ switch (state->ctx.result) {
+ case RESULT_NONE:
+ break;
+
+ case RESULT_BREAKIN_BYTE:
+ windbg_vm_stop();
+ break;
+
+ case RESULT_CONTROL_PACKET:
+ windbg_process_control_packet(state);
+ break;
+
+ case RESULT_DATA_PACKET:
+ windbg_process_data_packet(state);
+ break;
+
+ case RESULT_UNKNOWN_PACKET:
+ case RESULT_ERROR:
+ windbg_send_control_packet(state, PACKET_TYPE_KD_RESEND, 0);
+ break;
+
+ default:
+ break;
+ }
}
static void windbg_read_byte(ParsingContext *ctx, uint8_t byte)
@@ -260,6 +304,14 @@ void windbg_try_load(void)
if (windbg_state && !windbg_state->is_loaded) {
if (windbg_on_load()) {
windbg_state->is_loaded = true;
+
+ /* Handle last packet. Or we can require resend last packet. */
+ windbg_ctx_handler(windbg_state);
+
+ if (windbg_state->catched_breakin_byte == true) {
+ windbg_vm_stop();
+ windbg_state->catched_breakin_byte = false;
+ }
}
}
}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 16/39] windbg: init DBGKD_ANY_WAIT_STATE_CHANGE
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (14 preceding siblings ...)
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 15/39] windbg: handler of parsing context Mikhail Abakumov
@ 2018-12-05 12:53 ` Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 17/39] windbg: generate ExceptionStateChange and LoadSymbolsStateChange Mikhail Abakumov
` (25 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:53 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Add function for init DBGKD_ANY_WAIT_STATE_CHANGE. It is a header of
'state change' packets.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
target/i386/windbgstub.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index f1bab10b10..b2ac7a6d5f 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -15,9 +15,13 @@
#ifdef TARGET_X86_64
#define OFFSET_KPCR_SELF 0x18
#define OFFSET_KPCR_LOCK_ARRAY 0x28
+#define OFFSET_KPRCB 0x20
+#define OFFSET_KPRCB_CURRTHREAD 0x8
#else /* TARGET_I386 */
#define OFFSET_KPCR_SELF 0x1C
#define OFFSET_KPCR_VERSION 0x34
+#define OFFSET_KPRCB 0x20
+#define OFFSET_KPRCB_CURRTHREAD 0x4
#endif /* TARGET_I386 */
#ifdef TARGET_X86_64
@@ -156,3 +160,44 @@ void windbg_on_reset(void)
kdVersion.is_init = false;
#endif
}
+
+__attribute__ ((unused)) /* unused yet */
+static void kd_init_state_change(CPUState *cs, DBGKD_ANY_WAIT_STATE_CHANGE *sc)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+ DBGKD_CONTROL_REPORT *cr = &sc->ControlReport;
+ target_ulong KPRCB = VMEM_ADDR(cs, KPCR.addr + OFFSET_KPRCB);
+ target_ulong thread = VMEM_ADDR(cs, KPRCB + OFFSET_KPRCB_CURRTHREAD);
+ int number_processors = 0;
+
+ CPUState *cpu_tmp;
+ CPU_FOREACH(cpu_tmp) {
+ ++number_processors;
+ }
+
+ /* HEADER */
+
+ /* TODO: Fix this hardcoded value. */
+ stw_p(&sc->ProcessorLevel, 0);
+ /* TODO: Fix this hardcoded value. */
+ stw_p(&sc->Processor, 0);
+ stl_p(&sc->NumberProcessors, number_processors);
+ sttul_p(&sc->Thread, thread);
+ sttul_p(&sc->ProgramCounter, env->eip);
+
+ /* CONTROL REPORT */
+
+ sttul_p(&cr->Dr6, env->dr[6]);
+ sttul_p(&cr->Dr7, env->dr[7]);
+ stw_p(&cr->ReportFlags, REPORT_INCLUDES_SEGS | REPORT_STANDARD_CS);
+ stw_p(&cr->SegCs, env->segs[R_CS].selector);
+ stw_p(&cr->SegDs, env->segs[R_DS].selector);
+ stw_p(&cr->SegEs, env->segs[R_ES].selector);
+ stw_p(&cr->SegFs, env->segs[R_FS].selector);
+ stl_p(&cr->EFlags, env->eflags);
+
+ /* This is a feature */
+ memset(cr->InstructionStream, 0, DBGKD_MAXSTREAM);
+ stw_p(&cr->InstructionCount, 0);
+}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 17/39] windbg: generate ExceptionStateChange and LoadSymbolsStateChange
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (15 preceding siblings ...)
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 16/39] windbg: init DBGKD_ANY_WAIT_STATE_CHANGE Mikhail Abakumov
@ 2018-12-05 12:53 ` Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 18/39] windbg: implement windbg_process_control_packet Mikhail Abakumov
` (24 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:53 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 3 +++
target/i386/windbgstub.c | 33 ++++++++++++++++++++++++++++++++-
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index a28068eecd..794cb387b0 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -67,6 +67,9 @@ typedef struct PacketData {
const char *kd_api_name(int id);
const char *kd_pkt_type_name(int id);
+DBGKD_ANY_WAIT_STATE_CHANGE *kd_state_change_exc(CPUState *cs);
+DBGKD_ANY_WAIT_STATE_CHANGE *kd_state_change_ls(CPUState *cs);
+
bool windbg_on_load(void);
void windbg_on_reset(void);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index b2ac7a6d5f..37c5805818 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -161,7 +161,6 @@ void windbg_on_reset(void)
#endif
}
-__attribute__ ((unused)) /* unused yet */
static void kd_init_state_change(CPUState *cs, DBGKD_ANY_WAIT_STATE_CHANGE *sc)
{
X86CPU *cpu = X86_CPU(cs);
@@ -201,3 +200,35 @@ static void kd_init_state_change(CPUState *cs, DBGKD_ANY_WAIT_STATE_CHANGE *sc)
memset(cr->InstructionStream, 0, DBGKD_MAXSTREAM);
stw_p(&cr->InstructionCount, 0);
}
+
+DBGKD_ANY_WAIT_STATE_CHANGE *kd_state_change_exc(CPUState *cs)
+{
+ DBGKD_ANY_WAIT_STATE_CHANGE *sc = g_new0(DBGKD_ANY_WAIT_STATE_CHANGE, 1);
+ DBGKM_EXCEPTION_RECORD64 *exc = &sc->u.Exception.ExceptionRecord;
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ kd_init_state_change(cs, sc);
+
+ stl_p(&sc->NewState, DbgKdExceptionStateChange);
+ sttul_p(&exc->ExceptionAddress, env->eip);
+
+ /* TODO: Fix this hardcoded value. */
+ stl_p(&exc->ExceptionCode, 0x80000003);
+
+ return sc;
+}
+
+DBGKD_ANY_WAIT_STATE_CHANGE *kd_state_change_ls(CPUState *cs)
+{
+ DBGKD_ANY_WAIT_STATE_CHANGE *sc = g_new0(DBGKD_ANY_WAIT_STATE_CHANGE, 1);
+
+ kd_init_state_change(cs, sc);
+
+ stl_p(&sc->NewState, DbgKdLoadSymbolsStateChange);
+
+ /* TODO: Path to load symbold (with extra array). */
+ stl_p(&sc->u.LoadSymbols.PathNameLength, 0);
+
+ return sc;
+}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 18/39] windbg: implement windbg_process_control_packet
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (16 preceding siblings ...)
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 17/39] windbg: generate ExceptionStateChange and LoadSymbolsStateChange Mikhail Abakumov
@ 2018-12-05 12:53 ` Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 19/39] windbg: implement windbg_process_data_packet Mikhail Abakumov
` (23 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:53 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
windbgstub.c | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/windbgstub.c b/windbgstub.c
index fe0b007a06..f13c9a6c1e 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -91,7 +91,6 @@ static void windbg_store_packet(KD_PACKET *packet)
stl_p(&packet->Checksum, packet->Checksum);
}
-__attribute__ ((unused)) /* unused yet */
static void windbg_send_data_packet(WindbgState *state, uint8_t *data,
uint16_t byte_count, uint16_t type)
{
@@ -141,6 +140,40 @@ static void windbg_process_data_packet(WindbgState *state)
static void windbg_process_control_packet(WindbgState *state)
{
+ ParsingContext *ctx = &state->ctx;
+
+ switch (ctx->packet.PacketType) {
+ case PACKET_TYPE_KD_ACKNOWLEDGE:
+ if (state->wait_packet_type == PACKET_TYPE_KD_ACKNOWLEDGE &&
+ (ctx->packet.PacketId == (state->curr_packet_id &
+ ~SYNC_PACKET_ID))) {
+ state->curr_packet_id ^= 1;
+ state->wait_packet_type = 0;
+ }
+ break;
+
+ case PACKET_TYPE_KD_RESET: {
+ state->curr_packet_id = INITIAL_PACKET_ID;
+ windbg_send_control_packet(state, PACKET_TYPE_KD_RESET, 0);
+
+ DBGKD_ANY_WAIT_STATE_CHANGE *sc = kd_state_change_ls(qemu_get_cpu(0));
+ windbg_send_data_packet(state, (uint8_t *) sc,
+ sizeof(DBGKD_ANY_WAIT_STATE_CHANGE),
+ PACKET_TYPE_KD_STATE_CHANGE64);
+ g_free(sc);
+ break;
+ }
+
+ case PACKET_TYPE_KD_RESEND:
+ break;
+
+ default:
+ WINDBG_ERROR("Caught unsupported control packet 0x%x",
+ ctx->packet.PacketType);
+
+ windbg_send_control_packet(state, PACKET_TYPE_KD_RESEND, 0);
+ break;
+ }
}
static void windbg_ctx_handler(WindbgState *state)
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 19/39] windbg: implement windbg_process_data_packet
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (17 preceding siblings ...)
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 18/39] windbg: implement windbg_process_control_packet Mikhail Abakumov
@ 2018-12-05 12:53 ` Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 20/39] windbg: implement windbg_process_manipulate_packet Mikhail Abakumov
` (22 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:53 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
windbgstub.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/windbgstub.c b/windbgstub.c
index f13c9a6c1e..8cbece40da 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -134,8 +134,35 @@ static void windbg_vm_stop(void)
vm_stop(RUN_STATE_PAUSED);
}
+static void windbg_process_manipulate_packet(WindbgState *state)
+{
+}
+
static void windbg_process_data_packet(WindbgState *state)
{
+ ParsingContext *ctx = &state->ctx;
+
+ if (state->wait_packet_type == PACKET_TYPE_KD_ACKNOWLEDGE) {
+ /* We received something different */
+ windbg_send_control_packet(state, PACKET_TYPE_KD_RESEND, 0);
+ return;
+ }
+
+ switch (ctx->packet.PacketType) {
+ case PACKET_TYPE_KD_STATE_MANIPULATE:
+ windbg_send_control_packet(state, PACKET_TYPE_KD_ACKNOWLEDGE,
+ ctx->packet.PacketId);
+ windbg_process_manipulate_packet(state);
+ state->curr_packet_id &= ~SYNC_PACKET_ID;
+ break;
+
+ default:
+ WINDBG_ERROR("Caught unsupported data packet 0x%x",
+ ctx->packet.PacketType);
+
+ windbg_send_control_packet(state, PACKET_TYPE_KD_RESEND, 0);
+ break;
+ }
}
static void windbg_process_control_packet(WindbgState *state)
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 20/39] windbg: implement windbg_process_manipulate_packet
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (18 preceding siblings ...)
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 19/39] windbg: implement windbg_process_data_packet Mikhail Abakumov
@ 2018-12-05 12:53 ` Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 21/39] windbg: implement kd_api_read_virtual_memory and kd_api_write_virtual_memory Mikhail Abakumov
` (21 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:53 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 2 ++
windbgstub-utils.c | 7 +++++++
windbgstub.c | 27 +++++++++++++++++++++++++++
3 files changed, 36 insertions(+)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 794cb387b0..1c577ddd49 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -67,6 +67,8 @@ typedef struct PacketData {
const char *kd_api_name(int id);
const char *kd_pkt_type_name(int id);
+void kd_api_unsupported(CPUState *cs, PacketData *pd);
+
DBGKD_ANY_WAIT_STATE_CHANGE *kd_state_change_exc(CPUState *cs);
DBGKD_ANY_WAIT_STATE_CHANGE *kd_state_change_ls(CPUState *cs);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 6d2bb33307..6da6eea08f 100644
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -200,6 +200,13 @@ InitedAddr windbg_search_vmaddr(CPUState *cs, target_ulong start,
return ret;
}
+void kd_api_unsupported(CPUState *cs, PacketData *pd)
+{
+ WINDBG_ERROR("Caught unimplemented api %s", kd_api_name(pd->m64.ApiNumber));
+ pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+ pd->extra_size = 0;
+}
+
const char *kd_api_name(int id)
{
return (id >= DbgKdMinimumManipulate && id < DbgKdMaximumManipulate)
diff --git a/windbgstub.c b/windbgstub.c
index 8cbece40da..6ed93b8ce9 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -136,6 +136,33 @@ static void windbg_vm_stop(void)
static void windbg_process_manipulate_packet(WindbgState *state)
{
+ CPUState *cs;
+ ParsingContext *ctx = &state->ctx;
+ PacketData *data = &ctx->data;
+
+ data->extra_size = ctx->packet.ByteCount - sizeof(DBGKD_MANIPULATE_STATE64);
+ data->m64.ReturnStatus = STATUS_SUCCESS;
+
+ cs = qemu_get_cpu(data->m64.Processor);
+ if (cs == NULL) {
+ cs = qemu_get_cpu(0);
+ }
+
+ switch (data->m64.ApiNumber) {
+ default:
+ kd_api_unsupported(cs, data);
+ break;
+ }
+
+ if (data->m64.ReturnStatus == STATUS_UNSUCCESSFUL) {
+ WINDBG_ERROR("Caught error at %s", kd_api_name(data->m64.ApiNumber));
+ }
+
+ stl_p(&data->m64.ReturnStatus, data->m64.ReturnStatus);
+
+ windbg_send_data_packet(state, data->buf,
+ data->extra_size + sizeof(DBGKD_MANIPULATE_STATE64),
+ ctx->packet.PacketType);
}
static void windbg_process_data_packet(WindbgState *state)
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 21/39] windbg: implement kd_api_read_virtual_memory and kd_api_write_virtual_memory
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (19 preceding siblings ...)
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 20/39] windbg: implement windbg_process_manipulate_packet Mikhail Abakumov
@ 2018-12-05 12:54 ` Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 22/39] windbg: some kernel structures Mikhail Abakumov
` (20 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@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 1c577ddd49..638b2b9a6f 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -67,6 +67,8 @@ typedef struct PacketData {
const char *kd_api_name(int id);
const char *kd_pkt_type_name(int id);
+void kd_api_read_virtual_memory(CPUState *cs, PacketData *pd);
+void kd_api_write_virtual_memory(CPUState *cs, PacketData *pd);
void kd_api_unsupported(CPUState *cs, PacketData *pd);
DBGKD_ANY_WAIT_STATE_CHANGE *kd_state_change_exc(CPUState *cs);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 6da6eea08f..61f74dd22e 100644
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -200,6 +200,53 @@ InitedAddr windbg_search_vmaddr(CPUState *cs, target_ulong start,
return ret;
}
+void kd_api_read_virtual_memory(CPUState *cs, PacketData *pd)
+{
+ DBGKD_READ_MEMORY64 *mem = &pd->m64.u.ReadMemory;
+ uint32_t len;
+ target_ulong addr;
+ int err;
+
+ len = MIN(ldl_p(&mem->TransferCount),
+ PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+ addr = ldtul_p(&mem->TargetBaseAddress);
+ err = cpu_memory_rw_debug(cs, addr, pd->extra, len, 0);
+
+ if (err) {
+ len = 0;
+ pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+
+ DPRINTF("read_virtual_memory: No physical page mapped: " FMT_ADDR "\n",
+ addr);
+ }
+
+ pd->extra_size = len;
+ stl_p(&mem->ActualBytesRead, len);
+}
+
+void kd_api_write_virtual_memory(CPUState *cs, PacketData *pd)
+{
+ DBGKD_WRITE_MEMORY64 *mem = &pd->m64.u.WriteMemory;
+ uint32_t len;
+ target_ulong addr;
+ int err;
+
+ len = MIN(ldl_p(&mem->TransferCount), pd->extra_size);
+ addr = ldtul_p(&mem->TargetBaseAddress);
+ err = cpu_memory_rw_debug(cs, addr, pd->extra, len, 1);
+
+ if (err) {
+ len = 0;
+ pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+
+ DPRINTF("read_write_memory: No physical page mapped: " FMT_ADDR "\n",
+ addr);
+ }
+
+ pd->extra_size = 0;
+ stl_p(&mem->ActualBytesWritten, len);
+}
+
void kd_api_unsupported(CPUState *cs, PacketData *pd)
{
WINDBG_ERROR("Caught unimplemented api %s", kd_api_name(pd->m64.ApiNumber));
diff --git a/windbgstub.c b/windbgstub.c
index 6ed93b8ce9..46400d9bad 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -149,6 +149,14 @@ static void windbg_process_manipulate_packet(WindbgState *state)
}
switch (data->m64.ApiNumber) {
+ case DbgKdReadVirtualMemoryApi:
+ kd_api_read_virtual_memory(cs, data);
+ break;
+
+ case DbgKdWriteVirtualMemoryApi:
+ kd_api_write_virtual_memory(cs, data);
+ break;
+
default:
kd_api_unsupported(cs, data);
break;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 22/39] windbg: some kernel structures
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (20 preceding siblings ...)
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 21/39] windbg: implement kd_api_read_virtual_memory and kd_api_write_virtual_memory Mikhail Abakumov
@ 2018-12-05 12:54 ` Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 23/39] windbg: add helper functions Mikhail Abakumov
` (19 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
target/i386/windbgstub.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 243 insertions(+)
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 37c5805818..5d47d5c9e9 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -30,6 +30,249 @@
#define TARGET_SAFE(i386_obj, x86_64_obj) i386_obj
#endif /* TARGET_I386 */
+/*
+ * Next code copied from winnt.h
+ */
+#ifdef TARGET_X86_64
+
+#define CPU_CONTEXT_AMD64 0x100000
+
+#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;
+
+typedef struct _CPU_M128A {
+ uint64_t Low;
+ int64_t High;
+} QEMU_ALIGNED(16) CPU_M128A, *PCPU_M128A;
+
+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;
+
+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;
+} QEMU_ALIGNED(16) CPU_CONTEXT, *PCPU_CONTEXT;
+
+#else /* TARGET_I386 */
+
+#define SIZE_OF_X86_REG 80
+#define MAX_SUP_EXT 512
+
+#define CPU_CONTEXT_i386 0x10000
+
+#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_i386 | 0x8)
+#define CPU_CONTEXT_DEBUG_REGISTERS (CPU_CONTEXT_i386 | 0x10)
+#define CPU_CONTEXT_EXTENDED_REGISTERS (CPU_CONTEXT_i386 | 0x20)
+
+#define CPU_CONTEXT_FULL \
+ (CPU_CONTEXT_CONTROL | CPU_CONTEXT_INTEGER | CPU_CONTEXT_SEGMENTS)
+#define CPU_CONTEXT_ALL \
+ (CPU_CONTEXT_FULL | CPU_CONTEXT_FLOATING_POINT \
+ | CPU_CONTEXT_DEBUG_REGISTERS | CPU_CONTEXT_EXTENDED_REGISTERS)
+
+typedef struct _CPU_DESCRIPTOR {
+ uint16_t Pad;
+ uint16_t Limit;
+ uint32_t Base;
+} CPU_DESCRIPTOR, *PCPU_DESCRIPTOR;
+
+typedef struct _CPU_KSPECIAL_REGISTERS {
+ uint32_t Cr0;
+ uint32_t Cr2;
+ uint32_t Cr3;
+ uint32_t Cr4;
+ uint32_t KernelDr0;
+ uint32_t KernelDr1;
+ uint32_t KernelDr2;
+ uint32_t KernelDr3;
+ uint32_t KernelDr6;
+ uint32_t KernelDr7;
+ CPU_DESCRIPTOR Gdtr;
+ CPU_DESCRIPTOR Idtr;
+ uint16_t Tr;
+ uint16_t Ldtr;
+ uint32_t Reserved[6];
+} CPU_KSPECIAL_REGISTERS, *PCPU_KSPECIAL_REGISTERS;
+
+typedef struct _CPU_FLOATING_SAVE_AREA {
+ uint32_t ControlWord;
+ uint32_t StatusWord;
+ uint32_t TagWord;
+ uint32_t ErrorOffset;
+ uint32_t ErrorSelector;
+ uint32_t DataOffset;
+ uint32_t DataSelector;
+ uint8_t RegisterArea[SIZE_OF_X86_REG];
+ uint32_t Cr0NpxState;
+} CPU_FLOATING_SAVE_AREA, *PCPU_FLOATING_SAVE_AREA;
+
+typedef struct _CPU_CONTEXT { /* sizeof = 716 */
+ uint32_t ContextFlags;
+ uint32_t Dr0;
+ uint32_t Dr1;
+ uint32_t Dr2;
+ uint32_t Dr3;
+ uint32_t Dr6;
+ uint32_t Dr7;
+ CPU_FLOATING_SAVE_AREA FloatSave;
+ uint32_t SegGs;
+ uint32_t SegFs;
+ uint32_t SegEs;
+ uint32_t SegDs;
+
+ uint32_t Edi;
+ uint32_t Esi;
+ uint32_t Ebx;
+ uint32_t Edx;
+ uint32_t Ecx;
+ uint32_t Eax;
+ uint32_t Ebp;
+ uint32_t Eip;
+ uint32_t SegCs;
+ uint32_t EFlags;
+ uint32_t Esp;
+ uint32_t SegSs;
+ uint8_t ExtendedRegisters[MAX_SUP_EXT];
+} CPU_CONTEXT, *PCPU_CONTEXT;
+
+#endif /* TARGET_I386 */
+
+typedef struct _CPU_KPROCESSOR_STATE {
+ CPU_CONTEXT ContextFrame;
+ CPU_KSPECIAL_REGISTERS SpecialRegisters;
+} CPU_KPROCESSOR_STATE, *PCPU_KPROCESSOR_STATE;
+
static InitedAddr KPCR;
#ifdef TARGET_X86_64
static InitedAddr kdDebuggerDataBlock;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 23/39] windbg: add helper functions
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (21 preceding siblings ...)
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 22/39] windbg: some kernel structures Mikhail Abakumov
@ 2018-12-05 12:54 ` Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 24/39] windbg: [de]serialization cpu context Mikhail Abakumov
` (18 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Add helper functions for serialization and deserialization kernel structures to
byte buffer.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
target/i386/windbgstub.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 123 insertions(+)
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 5d47d5c9e9..e2ed2b3105 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -280,6 +280,129 @@ static InitedAddr kdDebuggerDataBlock;
static InitedAddr kdVersion;
#endif /* TARGET_I386 */
+__attribute__ ((unused)) /* unused yet */
+static void windbg_set_dr(CPUState *cs, int index, target_ulong value)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ switch (index) {
+ case 0 ... 3:
+ env->dr[index] = value;
+ return;
+ case 6:
+ env->dr[6] = value | DR6_FIXED_1;
+ return;
+ case 7:
+ cpu_x86_update_dr7(env, value);
+ return;
+ }
+}
+
+/* copy from gdbstub.c */
+__attribute__ ((unused)) /* unused yet */
+static void windbg_set_sr(CPUState *cs, int sreg, uint16_t selector)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ if (selector != env->segs[sreg].selector) {
+#if defined(CONFIG_USER_ONLY)
+ cpu_x86_load_seg(env, sreg, selector);
+#else
+ unsigned int limit, flags;
+ target_ulong base;
+
+ if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
+ int dpl = (env->eflags & VM_MASK) ? 3 : 0;
+ base = selector << 4;
+ limit = 0xffff;
+ flags = DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+ DESC_A_MASK | (dpl << DESC_DPL_SHIFT);
+ } else {
+ if (!cpu_x86_get_descr_debug(env, selector, &base, &limit,
+ &flags)) {
+ return;
+ }
+ }
+ cpu_x86_load_seg_cache(env, sreg, selector, base, limit, flags);
+#endif
+ }
+}
+
+#define rwuw_p(ptr, var, is_read) \
+ do { \
+ if (is_read) { \
+ var = lduw_p(ptr); \
+ } else { \
+ stw_p(ptr, var); \
+ } \
+ } while (0)
+
+#define rwl_p(ptr, var, is_read) \
+ do { \
+ if (is_read) { \
+ var = ldl_p(ptr); \
+ } else { \
+ stl_p(ptr, var); \
+ } \
+ } while (0)
+
+#define rwtul_p(ptr, var, is_read) \
+ do { \
+ if (is_read) { \
+ var = ldtul_p(ptr); \
+ } else { \
+ sttul_p(ptr, var); \
+ } \
+ } while (0)
+
+#define RW_DR(ptr, cs, dr_index, is_read) \
+ do { \
+ if (is_read) { \
+ windbg_set_dr(cs, dr_index, ldtul_p(ptr)); \
+ } else { \
+ sttul_p(ptr, X86_CPU(cs)->env.dr[dr_index]); \
+ } \
+ } while (0)
+
+#define RW_SR(ptr, cs, sr_index, is_read) \
+ do { \
+ if (is_read) { \
+ windbg_set_sr(cs, sr_index, lduw_p(ptr)); \
+ } else { \
+ stw_p(ptr, X86_CPU(cs)->env.segs[R_CS].selector); \
+ } \
+ } while (0)
+
+#define RW_CR(ptr, cs, cr_index, is_read) \
+ do { \
+ if (is_read) { \
+ cpu_x86_update_cr##cr_index(env, (int32_t) ldtul_p(ptr)); \
+ } else { \
+ sttul_p(ptr, (target_ulong) X86_CPU(cs)->env.cr[cr_index]); \
+ } \
+ } while (0)
+
+#define CASE_FIELD(stct, field, field_size, block) \
+ case offsetof(stct, field): \
+ field_size = sizeof_field(stct, field); \
+ block; \
+ break;
+
+#define CASE_FIELD_X32_64(stct, field_x32, field_x64, field_size, block) \
+ CASE_FIELD(stct, TARGET_SAFE(field_x32, field_x64), field_size, block)
+
+#ifdef TARGET_X86_64
+#define CASE_FIELD_X32(stct, field, field_size, block)
+#define CASE_FIELD_X64(stct, field, field_size, block) \
+ CASE_FIELD(stct, field, field_size, block)
+#else /* TARGET_I386 */
+#define CASE_FIELD_X64(stct, field, field_size, block)
+#define CASE_FIELD_X32(stct, field, field_size, block) \
+ CASE_FIELD(stct, field, field_size, block)
+#endif /* TARGET_I386 */
+
static bool find_KPCR(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 24/39] windbg: [de]serialization cpu context
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (22 preceding siblings ...)
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 23/39] windbg: add helper functions Mikhail Abakumov
@ 2018-12-05 12:54 ` Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 25/39] windbg: [de]serialization cpu spec registers Mikhail Abakumov
` (17 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
target/i386/windbgstub.c | 374 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 372 insertions(+), 2 deletions(-)
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index e2ed2b3105..7a091e1dee 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -280,7 +280,6 @@ static InitedAddr kdDebuggerDataBlock;
static InitedAddr kdVersion;
#endif /* TARGET_I386 */
-__attribute__ ((unused)) /* unused yet */
static void windbg_set_dr(CPUState *cs, int index, target_ulong value)
{
X86CPU *cpu = X86_CPU(cs);
@@ -300,7 +299,6 @@ static void windbg_set_dr(CPUState *cs, int index, target_ulong value)
}
/* copy from gdbstub.c */
-__attribute__ ((unused)) /* unused yet */
static void windbg_set_sr(CPUState *cs, int sreg, uint16_t selector)
{
X86CPU *cpu = X86_CPU(cs);
@@ -403,6 +401,378 @@ static void windbg_set_sr(CPUState *cs, int sreg, uint16_t selector)
CASE_FIELD(stct, field, field_size, block)
#endif /* TARGET_I386 */
+#define GEN_WINDBG_CONTEXT_RW(fun_name, is_read) \
+static int fun_name(CPUState *cs, uint8_t *buf, int buf_size, \
+ int offset, int len) \
+{ \
+ X86CPU *cpu = X86_CPU(cs); \
+ CPUX86State *env = &cpu->env; \
+ uint32_t ctx_flags = CPU_CONTEXT_ALL; \
+ uint32_t tmp32, i; \
+ uint32_t f_size = 0; \
+ \
+ if (len < 0 || len > buf_size) { \
+ WINDBG_ERROR("" #fun_name ": incorrect length %d", len); \
+ return 1; \
+ } \
+ \
+ if (offset < 0 || offset + len > sizeof(CPU_CONTEXT)) { \
+ WINDBG_ERROR("" #fun_name ": incorrect offset %d", offset); \
+ return 2; \
+ } \
+ \
+ len = MIN(len, sizeof(CPU_CONTEXT) - offset); \
+ \
+ while (offset < len) { \
+ switch (offset) { \
+ CASE_FIELD(CPU_CONTEXT, ContextFlags, f_size, { \
+ rwl_p(buf, ctx_flags, is_read); \
+ }); \
+ /* DEBUG REGISTERS */ \
+ CASE_FIELD(CPU_CONTEXT, Dr0, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_DEBUG_REGISTERS) { \
+ RW_DR(buf, cs, 0, is_read); \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, Dr1, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_DEBUG_REGISTERS) { \
+ RW_DR(buf, cs, 1, is_read); \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, Dr2, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_DEBUG_REGISTERS) { \
+ RW_DR(buf, cs, 2, is_read); \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, Dr3, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_DEBUG_REGISTERS) { \
+ RW_DR(buf, cs, 3, is_read); \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, Dr6, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_DEBUG_REGISTERS) { \
+ RW_DR(buf, cs, 6, is_read); \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, Dr7, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_DEBUG_REGISTERS) { \
+ RW_DR(buf, cs, 7, is_read); \
+ } \
+ }); \
+ /* SEGMENT REGISTERS */ \
+ CASE_FIELD(CPU_CONTEXT, SegCs, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_SEGMENTS) { \
+ RW_SR(buf, cs, R_CS, is_read); \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, SegDs, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_SEGMENTS) { \
+ RW_SR(buf, cs, R_DS, is_read); \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, SegEs, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_SEGMENTS) { \
+ RW_SR(buf, cs, R_ES, is_read); \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, SegFs, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_SEGMENTS) { \
+ RW_SR(buf, cs, R_FS, is_read); \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, SegGs, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_SEGMENTS) { \
+ RW_SR(buf, cs, R_GS, is_read); \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, SegSs, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_SEGMENTS) { \
+ RW_SR(buf, cs, R_SS, is_read); \
+ } \
+ }); \
+ /* INTEGER REGISTERS */ \
+ CASE_FIELD_X32_64(CPU_CONTEXT, Eax, Rax, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[R_EAX], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X32_64(CPU_CONTEXT, Ecx, Rcx, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[R_ECX], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X32_64(CPU_CONTEXT, Edx, Rdx, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[R_EDX], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X32_64(CPU_CONTEXT, Ebx, Rbx, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[R_EBX], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X32_64(CPU_CONTEXT, Esi, Rsi, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[R_ESI], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X32_64(CPU_CONTEXT, Edi, Rdi, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[R_EDI], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, R8, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[8], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, R9, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[9], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, R10, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[10], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, R11, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[11], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, R12, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[12], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, R13, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[13], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, R14, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[14], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, R15, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_INTEGER) { \
+ rwtul_p(buf, env->regs[15], is_read); \
+ } \
+ }); \
+ /* CONTROL REGISTERS */ \
+ CASE_FIELD_X32_64(CPU_CONTEXT, Esp, Rsp, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_CONTROL) { \
+ rwtul_p(buf, env->regs[R_ESP], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X32_64(CPU_CONTEXT, Ebp, Rbp, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_CONTROL) { \
+ rwtul_p(buf, env->regs[R_EBP], is_read); \
+ } \
+ }); \
+ CASE_FIELD_X32_64(CPU_CONTEXT, Eip, Rip, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_CONTROL) { \
+ rwtul_p(buf, env->eip, is_read); \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, EFlags, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_CONTROL) { \
+ rwl_p(buf, env->eflags, is_read); \
+ } \
+ }); \
+ /* FLOAT REGISTERS */ \
+ CASE_FIELD(CPU_CONTEXT, FloatSave.ControlWord, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ if (is_read) { \
+ cpu_set_fpuc(env, TARGET_SAFE(ldl_p, lduw_p)(buf)); \
+ } else { \
+ TARGET_SAFE(stl_p, stw_p)(buf, env->fpuc); \
+ } \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, FloatSave.StatusWord, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ if (is_read) { \
+ tmp32 = TARGET_SAFE(ldl_p, lduw_p)(buf); \
+ env->fpstt = (tmp32 >> 11) & 7; \
+ env->fpus = tmp32 & ~0x3800; \
+ } else { \
+ tmp32 = env->fpus & ~(7 << 11); \
+ tmp32 |= (env->fpstt & 7) << 11; \
+ TARGET_SAFE(stl_p, stw_p)(buf, tmp32); \
+ } \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, FloatSave.TagWord, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ if (is_read) { \
+ tmp32 = TARGET_SAFE(ldl_p(buf), buf[0]); \
+ for (i = 0; i < 8; ++i) { \
+ env->fptags[i] = !((tmp32 >> i) & 1); \
+ } \
+ } else { \
+ tmp32 = 0; \
+ for (i = 0; i < 8; ++i) { \
+ tmp32 |= (!env->fptags[i]) << i; \
+ } \
+ TARGET_SAFE(stl_p, stb_p)(buf, tmp32); \
+ } \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, FloatSave.Reserved1, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, FloatSave.ErrorOpcode, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ rwuw_p(buf, env->fpop, is_read); \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, FloatSave.ErrorOffset, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ if (is_read) { \
+ env->fpip &= ~0xffffffffL; \
+ env->fpip |= ldl_p(buf); \
+ } else { \
+ stl_p(buf, env->fpip & 0xffffffff); \
+ } \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, FloatSave.ErrorSelector, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ if (is_read) { \
+ env->fpip &= 0xffffffffL; \
+ env->fpip |= ((uint64_t) ldl_p(buf)) << 32; \
+ } else { \
+ stl_p(buf, (env->fpip >> 32) & 0xffffffff); \
+ } \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, FloatSave.Reserved2, f_size, {}); \
+ CASE_FIELD(CPU_CONTEXT, FloatSave.DataOffset, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ if (is_read) { \
+ env->fpdp &= ~0xffffffffL; \
+ env->fpdp |= ldl_p(buf); \
+ } else { \
+ stl_p(buf, env->fpdp & 0xffffffff); \
+ } \
+ } \
+ }); \
+ CASE_FIELD(CPU_CONTEXT, FloatSave.DataSelector, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ if (is_read) { \
+ env->fpdp &= 0xffffffffL; \
+ env->fpdp |= ((uint64_t) ldl_p(buf)) << 32; \
+ } else { \
+ stl_p(buf, (env->fpdp >> 32) & 0xffffffff); \
+ } \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, FloatSave.Reserved3, f_size, {}); \
+ CASE_FIELD_X32(CPU_CONTEXT, FloatSave.Cr0NpxState, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ rwl_p(buf, env->xcr0, is_read); \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, FloatSave.MxCsr, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ rwl_p(buf, env->mxcsr, is_read); \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, FloatSave.MxCsr_Mask, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ /* FIXME: this is unimplemented in qemu? */ \
+ /* rwl_p(buf, env->mxcsr_mask, is_read); */ \
+ } \
+ }); \
+ CASE_FIELD_X32_64(CPU_CONTEXT, FloatSave.RegisterArea, \
+ FloatSave.FloatRegisters, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ uint8_t *mem = buf; \
+ for (i = 0; i < 8; ++i, mem += TARGET_SAFE(10, 16)) { \
+ floatx80 fl = env->fpregs[i].d; \
+ if (is_read) { \
+ fl.low = ldq_p(mem); \
+ fl.high = TARGET_SAFE(lduw_p, ldq_p)(mem + 8); \
+ } else { \
+ stq_p(mem, fl.low); \
+ TARGET_SAFE(stw_p, stq_p)(mem + 8, fl.high); \
+ } \
+ } \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, FloatSave.XmmRegisters, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_FLOATING_POINT) { \
+ uint8_t *mem = buf; \
+ if (is_read) { \
+ for (i = 0; i < CPU_NB_REGS; ++i, mem += 16) { \
+ env->xmm_regs[i].ZMM_Q(0) = ldl_p(mem); \
+ env->xmm_regs[i].ZMM_Q(1) = ldl_p(mem + 8); \
+ } \
+ } else { \
+ for (i = 0; i < CPU_NB_REGS; ++i, mem += 16) { \
+ stq_p(mem, env->xmm_regs[i].ZMM_Q(0)); \
+ stq_p(mem + 8, env->xmm_regs[i].ZMM_Q(1)); \
+ } \
+ } \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, FloatSave.Reserved4, f_size, {}); \
+ /* EXTENDED REGISTERS I386 */ \
+ CASE_FIELD_X32(CPU_CONTEXT, ExtendedRegisters, f_size, { \
+ if (ctx_flags & CPU_CONTEXT_EXTENDED_REGISTERS) { \
+ uint8_t *mem = buf + 160; \
+ if (is_read) { \
+ for (i = 0; i < CPU_NB_REGS; ++i, mem += 16) { \
+ env->xmm_regs[i].ZMM_Q(0) = ldl_p(mem); \
+ env->xmm_regs[i].ZMM_Q(1) = ldl_p(mem + 8); \
+ } \
+ cpu_set_mxcsr(env, ldl_p(mem + 24)); \
+ } else { \
+ for (i = 0; i < CPU_NB_REGS; ++i, mem += 16) { \
+ stq_p(mem, env->xmm_regs[i].ZMM_Q(0)); \
+ stq_p(mem + 8, env->xmm_regs[i].ZMM_Q(1)); \
+ } \
+ stl_p(mem + 24, env->mxcsr); \
+ } \
+ } \
+ }); \
+ /* UNKNOWN REGISTERS */ \
+ CASE_FIELD_X64(CPU_CONTEXT, P1Home, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, P2Home, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, P3Home, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, P4Home, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, P5Home, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, P6Home, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, MxCsr, f_size, { \
+ if (is_read) { \
+ cpu_set_mxcsr(env, ldl_p(buf)); \
+ } else { \
+ stl_p(buf, env->mxcsr); \
+ } \
+ }); \
+ CASE_FIELD_X64(CPU_CONTEXT, VectorRegister, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, VectorControl, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, DebugControl, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, LastBranchToRip, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, LastBranchFromRip, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, LastExceptionToRip, f_size, {}); \
+ CASE_FIELD_X64(CPU_CONTEXT, LastExceptionFromRip, f_size, {}); \
+ default: \
+ f_size = 1; \
+ } \
+ offset += f_size; \
+ buf += f_size; \
+ } \
+ return 0; \
+}
+
+__attribute__ ((unused)) /* unused yet */
+GEN_WINDBG_CONTEXT_RW(windbg_read_context, false)
+
+__attribute__ ((unused)) /* unused yet */
+GEN_WINDBG_CONTEXT_RW(windbg_write_context, true)
+
static bool find_KPCR(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 25/39] windbg: [de]serialization cpu spec registers
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (23 preceding siblings ...)
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 24/39] windbg: [de]serialization cpu context Mikhail Abakumov
@ 2018-12-05 12:54 ` Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 26/39] windbg: implement kd_api_get_context and kd_api_set_context Mikhail Abakumov
` (16 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
target/i386/windbgstub.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 123 insertions(+)
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 7a091e1dee..a1d27b8aca 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -767,12 +767,135 @@ static int fun_name(CPUState *cs, uint8_t *buf, int buf_size, \
return 0; \
}
+#define GEN_WINDBG_KSPEC_REGS_RW(fun_name, is_read) \
+static int fun_name(CPUState *cs, uint8_t *buf, int buf_size, \
+ int offset, int len) \
+{ \
+ X86CPU *cpu = X86_CPU(cs); \
+ CPUX86State *env = &cpu->env; \
+ uint32_t f_size = 0; \
+ \
+ if (len < 0 || len > buf_size) { \
+ WINDBG_ERROR("" #fun_name ": incorrect length %d", len); \
+ return 1; \
+ } \
+ \
+ if (offset < 0 || offset + len > sizeof(CPU_KSPECIAL_REGISTERS)) { \
+ WINDBG_ERROR("" #fun_name ": incorrect offset %d", f_size); \
+ return 2; \
+ } \
+ \
+ len = MIN(len, sizeof(CPU_KSPECIAL_REGISTERS) - offset); \
+ \
+ while (offset < len) { \
+ switch (offset) { \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, Cr0, f_size, { \
+ RW_CR(buf, cs, 0, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, Cr2, f_size, { \
+ if (is_read) { \
+ env->cr[2] = (int32_t) ldtul_p(buf); \
+ } else { \
+ sttul_p(buf, (target_ulong) env->cr[2]); \
+ } \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, Cr3, f_size, { \
+ RW_CR(buf, cs, 3, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, Cr4, f_size, { \
+ RW_CR(buf, cs, 4, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, KernelDr0, f_size, { \
+ RW_DR(buf, cs, 0, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, KernelDr1, f_size, { \
+ RW_DR(buf, cs, 1, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, KernelDr2, f_size, { \
+ RW_DR(buf, cs, 2, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, KernelDr3, f_size, { \
+ RW_DR(buf, cs, 3, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, KernelDr6, f_size, { \
+ RW_DR(buf, cs, 6, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, KernelDr7, f_size, { \
+ RW_DR(buf, cs, 7, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, Gdtr.Pad, f_size, {}); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, Gdtr.Limit, f_size, { \
+ rwuw_p(buf, env->gdt.limit, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, Gdtr.Base, f_size, { \
+ rwtul_p(buf, env->gdt.base, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, Idtr.Pad, f_size, {}); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, Idtr.Limit, f_size, { \
+ rwuw_p(buf, env->idt.limit, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, Idtr.Base, f_size, { \
+ rwtul_p(buf, env->idt.base, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, Tr, f_size, { \
+ rwuw_p(buf, env->tr.selector, is_read); \
+ }); \
+ CASE_FIELD(CPU_KSPECIAL_REGISTERS, Ldtr, f_size, { \
+ rwuw_p(buf, env->tr.selector, is_read); \
+ }); \
+ CASE_FIELD_X32(CPU_KSPECIAL_REGISTERS, Reserved, f_size, {}); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, MxCsr, f_size, { \
+ rwl_p(buf, env->mxcsr, is_read); \
+ }); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, DebugControl, f_size, {}); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, LastBranchToRip, f_size, {}); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, LastBranchFromRip, f_size, {}); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, LastExceptionToRip, f_size, {});\
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, LastExceptionFromRip, f_size, { \
+ }); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, Cr8, f_size, {}); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, MsrGsBase, f_size, { \
+ rwtul_p(buf, env->segs[R_GS].base, is_read); \
+ }); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, MsrGsSwap, f_size, { \
+ rwtul_p(buf, env->kernelgsbase, is_read); \
+ }); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, MsrStar, f_size, { \
+ rwtul_p(buf, env->star, is_read); \
+ }); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, MsrLStar, f_size, { \
+ rwtul_p(buf, env->lstar, is_read); \
+ }); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, MsrCStar, f_size, { \
+ rwtul_p(buf, env->cstar, is_read); \
+ }); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, MsrSyscallMask, f_size, { \
+ /* NOTE: Unimplemented in qemu: msr MSR_SFMASK */ \
+ }); \
+ CASE_FIELD_X64(CPU_KSPECIAL_REGISTERS, Xcr0, f_size, { \
+ rwtul_p(buf, env->xcr0, is_read); \
+ }); \
+ default: \
+ f_size = 1; \
+ } \
+ offset += f_size; \
+ buf += f_size; \
+ } \
+ return 0; \
+}
+
__attribute__ ((unused)) /* unused yet */
GEN_WINDBG_CONTEXT_RW(windbg_read_context, false)
__attribute__ ((unused)) /* unused yet */
GEN_WINDBG_CONTEXT_RW(windbg_write_context, true)
+__attribute__ ((unused)) /* unused yet */
+GEN_WINDBG_KSPEC_REGS_RW(windbg_read_ks_regs, false)
+
+__attribute__ ((unused)) /* unused yet */
+GEN_WINDBG_KSPEC_REGS_RW(windbg_write_ks_regs, true)
+
static bool find_KPCR(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 26/39] windbg: implement kd_api_get_context and kd_api_set_context
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (24 preceding siblings ...)
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 25/39] windbg: [de]serialization cpu spec registers Mikhail Abakumov
@ 2018-12-05 12:54 ` Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 27/39] windbg: implement kd_api_get_context_ex and kd_api_set_context_ex Mikhail Abakumov
` (15 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 2 ++
target/i386/windbgstub.c | 27 +++++++++++++++++++++++++++
windbgstub.c | 8 ++++++++
3 files changed, 37 insertions(+)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 638b2b9a6f..a88e013de9 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -69,6 +69,8 @@ const char *kd_pkt_type_name(int id);
void kd_api_read_virtual_memory(CPUState *cs, PacketData *pd);
void kd_api_write_virtual_memory(CPUState *cs, PacketData *pd);
+void kd_api_get_context(CPUState *cs, PacketData *pd);
+void kd_api_set_context(CPUState *cs, PacketData *pd);
void kd_api_unsupported(CPUState *cs, PacketData *pd);
DBGKD_ANY_WAIT_STATE_CHANGE *kd_state_change_exc(CPUState *cs);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index a1d27b8aca..900950495f 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -896,6 +896,33 @@ GEN_WINDBG_KSPEC_REGS_RW(windbg_read_ks_regs, false)
__attribute__ ((unused)) /* unused yet */
GEN_WINDBG_KSPEC_REGS_RW(windbg_write_ks_regs, true)
+void kd_api_get_context(CPUState *cs, PacketData *pd)
+{
+ int err;
+
+ pd->extra_size = sizeof(CPU_CONTEXT);
+ err = windbg_read_context(cs, pd->extra, pd->extra_size,
+ 0, sizeof(CPU_CONTEXT));
+
+ if (err) {
+ pd->extra_size = 0;
+ pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+ }
+}
+
+void kd_api_set_context(CPUState *cs, PacketData *pd)
+{
+ int err;
+
+ err = windbg_write_context(cs, pd->extra, pd->extra_size,
+ 0, sizeof(CPU_CONTEXT));
+ pd->extra_size = 0;
+
+ if (err) {
+ pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+ }
+}
+
static bool find_KPCR(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
diff --git a/windbgstub.c b/windbgstub.c
index 46400d9bad..70ebf3c0ad 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -157,6 +157,14 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_write_virtual_memory(cs, data);
break;
+ case DbgKdGetContextApi:
+ kd_api_get_context(cs, data);
+ break;
+
+ case DbgKdSetContextApi:
+ kd_api_set_context(cs, data);
+ break;
+
default:
kd_api_unsupported(cs, data);
break;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 27/39] windbg: implement kd_api_get_context_ex and kd_api_set_context_ex
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (25 preceding siblings ...)
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 26/39] windbg: implement kd_api_get_context and kd_api_set_context Mikhail Abakumov
@ 2018-12-05 12:54 ` Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 28/39] windbg: implement kd_api_read_control_space and kd_api_write_control_space Mikhail Abakumov
` (14 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 2 +
target/i386/windbgstub.c | 90 ++++++++++++++++++++++++++++++++++++---
windbgstub.c | 8 +++
3 files changed, 93 insertions(+), 7 deletions(-)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index a88e013de9..6936fd0ffb 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -71,6 +71,8 @@ void kd_api_read_virtual_memory(CPUState *cs, PacketData *pd);
void kd_api_write_virtual_memory(CPUState *cs, PacketData *pd);
void kd_api_get_context(CPUState *cs, PacketData *pd);
void kd_api_set_context(CPUState *cs, PacketData *pd);
+void kd_api_get_context_ex(CPUState *cs, PacketData *pd);
+void kd_api_set_context_ex(CPUState *cs, PacketData *pd);
void kd_api_unsupported(CPUState *cs, PacketData *pd);
DBGKD_ANY_WAIT_STATE_CHANGE *kd_state_change_exc(CPUState *cs);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 900950495f..76cdc1d9a7 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -884,18 +884,57 @@ static int fun_name(CPUState *cs, uint8_t *buf, int buf_size, \
return 0; \
}
-__attribute__ ((unused)) /* unused yet */
GEN_WINDBG_CONTEXT_RW(windbg_read_context, false)
-
-__attribute__ ((unused)) /* unused yet */
GEN_WINDBG_CONTEXT_RW(windbg_write_context, true)
-
-__attribute__ ((unused)) /* unused yet */
GEN_WINDBG_KSPEC_REGS_RW(windbg_read_ks_regs, false)
-
-__attribute__ ((unused)) /* unused yet */
GEN_WINDBG_KSPEC_REGS_RW(windbg_write_ks_regs, true)
+static int windbg_rw_context_ex(CPUState *cs, uint8_t *buf, int buf_size,
+ int offset, int len, bool is_read)
+{
+ int context_len;
+ int 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(cs, buf, context_len, offset,
+ context_len);
+ } else {
+ err = windbg_write_context(cs, 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(cs, buf + context_len, ks_regs_len,
+ offset, ks_regs_len);
+ } else {
+ err = windbg_write_ks_regs(cs, buf + context_len, ks_regs_len,
+ offset, ks_regs_len);
+ }
+
+ if (err) {
+ return err;
+ }
+ }
+ }
+
+ return err;
+}
+
void kd_api_get_context(CPUState *cs, PacketData *pd)
{
int err;
@@ -923,6 +962,43 @@ void kd_api_set_context(CPUState *cs, PacketData *pd)
}
}
+void kd_api_get_context_ex(CPUState *cs, PacketData *pd)
+{
+ DBGKD_CONTEXT_EX *ctx = &pd->m64.u.ContextEx;
+ uint32_t offset = ldl_p(&ctx->Offset);
+ uint32_t len = MIN(ldl_p(&ctx->ByteCount),
+ PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+ int err;
+
+ err = windbg_rw_context_ex(cs, pd->extra, len, offset, len, true);
+
+ if (err) {
+ len = 0;
+ pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+ }
+
+ pd->extra_size = len;
+ stl_p(&ctx->BytesCopied, len);
+}
+
+void kd_api_set_context_ex(CPUState *cs, PacketData *pd)
+{
+ DBGKD_CONTEXT_EX *ctx = &pd->m64.u.ContextEx;
+ uint32_t offset = ldl_p(&ctx->Offset);
+ uint32_t len = MIN(ldl_p(&ctx->ByteCount), pd->extra_size);
+ int err;
+
+ err = windbg_rw_context_ex(cs, pd->extra, len, offset, len, false);
+
+ if (err) {
+ len = 0;
+ pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+ }
+
+ pd->extra_size = 0;
+ stl_p(&ctx->BytesCopied, len);
+}
+
static bool find_KPCR(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
diff --git a/windbgstub.c b/windbgstub.c
index 70ebf3c0ad..e9d759cddf 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -165,6 +165,14 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_set_context(cs, data);
break;
+ case DbgKdGetContextExApi:
+ kd_api_get_context_ex(cs, data);
+ break;
+
+ case DbgKdSetContextExApi:
+ kd_api_set_context_ex(cs, data);
+ break;
+
default:
kd_api_unsupported(cs, data);
break;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 28/39] windbg: implement kd_api_read_control_space and kd_api_write_control_space
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (26 preceding siblings ...)
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 27/39] windbg: implement kd_api_get_context_ex and kd_api_set_context_ex Mikhail Abakumov
@ 2018-12-05 12:54 ` Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 29/39] windbg: implement kd_api_write_breakpoint and kd_api_restore_breakpoint Mikhail Abakumov
` (13 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 2 +
target/i386/windbgstub.c | 81 +++++++++++++++++++++++++++++++++++++++
windbgstub.c | 8 ++++
3 files changed, 91 insertions(+)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 6936fd0ffb..2781a54044 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -71,6 +71,8 @@ void kd_api_read_virtual_memory(CPUState *cs, PacketData *pd);
void kd_api_write_virtual_memory(CPUState *cs, PacketData *pd);
void kd_api_get_context(CPUState *cs, PacketData *pd);
void kd_api_set_context(CPUState *cs, PacketData *pd);
+void kd_api_read_control_space(CPUState *cs, PacketData *pd);
+void kd_api_write_control_space(CPUState *cs, PacketData *pd);
void kd_api_get_context_ex(CPUState *cs, PacketData *pd);
void kd_api_set_context_ex(CPUState *cs, PacketData *pd);
void kd_api_unsupported(CPUState *cs, PacketData *pd);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 76cdc1d9a7..6d2e7de746 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -962,6 +962,87 @@ void kd_api_set_context(CPUState *cs, PacketData *pd)
}
}
+void kd_api_read_control_space(CPUState *cs, PacketData *pd)
+{
+ DBGKD_READ_MEMORY64 *mem = &pd->m64.u.ReadMemory;
+ target_ulong addr = ldtul_p(&mem->TargetBaseAddress);
+ uint32_t len = MIN(ldl_p(&mem->TransferCount),
+ PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+ int err = 0;
+
+#ifdef TARGET_X86_64
+
+ switch (addr) {
+ case AMD64_DEBUG_CONTROL_SPACE_KPCR:
+ addr = KPCR.addr;
+ len = sizeof(target_ulong);
+ err = cpu_memory_rw_debug(cs, addr, pd->extra, len, 0);
+ break;
+
+ case AMD64_DEBUG_CONTROL_SPACE_KPRCB:
+ addr = VMEM_ADDR(cs, KPCR.addr + OFFSET_KPRCB);
+ len = sizeof(target_ulong);
+ err = cpu_memory_rw_debug(cs, addr, pd->extra, len, 0);
+ break;
+
+ case AMD64_DEBUG_CONTROL_SPACE_KSPECIAL:
+ len = MIN(len, sizeof(CPU_KSPECIAL_REGISTERS));
+ err = windbg_read_ks_regs(cs, pd->extra, len, 0, len);
+ break;
+
+ case AMD64_DEBUG_CONTROL_SPACE_KTHREAD:
+ addr = VMEM_ADDR(cs, addr + OFFSET_KPRCB_CURRTHREAD);
+ len = sizeof(target_ulong);
+ err = cpu_memory_rw_debug(cs, addr, pd->extra, len, 0);
+ break;
+ }
+
+#else /* TARGET_I386 */
+
+ err = windbg_rw_context_ex(cs, pd->extra, len, addr, len, true);
+
+#endif /* TARGET_I386 */
+
+ if (err) {
+ len = 0;
+ pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+ }
+
+ pd->extra_size = len;
+ stl_p(&mem->ActualBytesRead, len);
+}
+
+void kd_api_write_control_space(CPUState *cs, PacketData *pd)
+{
+ DBGKD_WRITE_MEMORY64 *mem = &pd->m64.u.WriteMemory;
+ target_ulong addr = ldtul_p(&mem->TargetBaseAddress);
+ uint32_t len = MIN(ldl_p(&mem->TransferCount), pd->extra_size);
+ int err = 0;
+
+#ifdef TARGET_X86_64
+
+ if (addr == AMD64_DEBUG_CONTROL_SPACE_KSPECIAL) {
+ len = MIN(len, sizeof(CPU_KSPECIAL_REGISTERS));
+ err = windbg_write_ks_regs(cs, pd->extra, len, 0, len);
+ } else {
+ err = 1;
+ }
+
+#else /* TARGET_I386 */
+
+ err = windbg_rw_context_ex(cs, pd->extra, len, addr, len, false);
+
+#endif /* TARGET_I386 */
+
+ if (err) {
+ len = 0;
+ pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+ }
+
+ pd->extra_size = 0;
+ stl_p(&mem->ActualBytesWritten, len);
+}
+
void kd_api_get_context_ex(CPUState *cs, PacketData *pd)
{
DBGKD_CONTEXT_EX *ctx = &pd->m64.u.ContextEx;
diff --git a/windbgstub.c b/windbgstub.c
index e9d759cddf..328a04735f 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -165,6 +165,14 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_set_context(cs, data);
break;
+ case DbgKdReadControlSpaceApi:
+ kd_api_read_control_space(cs, data);
+ break;
+
+ case DbgKdWriteControlSpaceApi:
+ kd_api_write_control_space(cs, data);
+ break;
+
case DbgKdGetContextExApi:
kd_api_get_context_ex(cs, data);
break;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 29/39] windbg: implement kd_api_write_breakpoint and kd_api_restore_breakpoint
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (27 preceding siblings ...)
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 28/39] windbg: implement kd_api_read_control_space and kd_api_write_control_space Mikhail Abakumov
@ 2018-12-05 12:54 ` Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 30/39] windbg: debug exception subscribing Mikhail Abakumov
` (12 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 3 ++
windbgstub-utils.c | 68 +++++++++++++++++++++++++++++++++++++++
windbgstub.c | 12 +++++++
3 files changed, 83 insertions(+)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 2781a54044..85b7322b82 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -71,8 +71,11 @@ void kd_api_read_virtual_memory(CPUState *cs, PacketData *pd);
void kd_api_write_virtual_memory(CPUState *cs, PacketData *pd);
void kd_api_get_context(CPUState *cs, PacketData *pd);
void kd_api_set_context(CPUState *cs, PacketData *pd);
+void kd_api_write_breakpoint(CPUState *cs, PacketData *pd);
+void kd_api_restore_breakpoint(CPUState *cs, PacketData *pd);
void kd_api_read_control_space(CPUState *cs, PacketData *pd);
void kd_api_write_control_space(CPUState *cs, PacketData *pd);
+void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd);
void kd_api_get_context_ex(CPUState *cs, PacketData *pd);
void kd_api_set_context_ex(CPUState *cs, PacketData *pd);
void kd_api_unsupported(CPUState *cs, PacketData *pd);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 61f74dd22e..ea96c0598c 100644
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -80,6 +80,8 @@ static const char *kd_packet_type_names[] = {
"PACKET_TYPE_MAX",
};
+static InitedAddr bps[KD_BREAKPOINT_MAX];
+
static void prep_bmbc(const uint8_t *pattern, int pLen, int bmBc[])
{
int i;
@@ -247,6 +249,72 @@ void kd_api_write_virtual_memory(CPUState *cs, PacketData *pd)
stl_p(&mem->ActualBytesWritten, len);
}
+void kd_api_write_breakpoint(CPUState *cs, PacketData *pd)
+{
+ DBGKD_WRITE_BREAKPOINT64 *m64c = &pd->m64.u.WriteBreakPoint;
+ target_ulong addr;
+ int i, err = 0;
+
+ addr = ldtul_p(&m64c->BreakPointAddress);
+
+ for (i = 0; i < KD_BREAKPOINT_MAX; ++i) {
+ if (!bps[i].is_init) {
+ err = cpu_breakpoint_insert(cs, addr, BP_GDB, NULL);
+ if (!err) {
+ bps[i].addr = addr;
+ bps[i].is_init = true;
+ DPRINTF("write_breakpoint: " FMT_ADDR ", index(%d)\n",
+ addr, i);
+ 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(&m64c->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 *cs, PacketData *pd)
+{
+ DBGKD_RESTORE_BREAKPOINT *m64c = &pd->m64.u.RestoreBreakPoint;
+ uint8_t index;
+ int err = -1;
+
+ index = ldtul_p(&m64c->BreakPointHandle) - 1;
+
+ if (bps[index].is_init) {
+ err = cpu_breakpoint_remove(cs, bps[index].addr, BP_GDB);
+ if (!err) {
+ DPRINTF("restore_breakpoint: " FMT_ADDR ", index(%d)\n",
+ 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_SUCCESS;
+ }
+}
+
+void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd)
+{
+}
+
void kd_api_unsupported(CPUState *cs, PacketData *pd)
{
WINDBG_ERROR("Caught unimplemented api %s", kd_api_name(pd->m64.ApiNumber));
diff --git a/windbgstub.c b/windbgstub.c
index 328a04735f..a1c013cd8c 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -165,6 +165,14 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_set_context(cs, data);
break;
+ case DbgKdWriteBreakPointApi:
+ kd_api_write_breakpoint(cs, data);
+ break;
+
+ case DbgKdRestoreBreakPointApi:
+ kd_api_restore_breakpoint(cs, data);
+ break;
+
case DbgKdReadControlSpaceApi:
kd_api_read_control_space(cs, data);
break;
@@ -173,6 +181,10 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_write_control_space(cs, data);
break;
+ case DbgKdClearAllInternalBreakpointsApi:
+ kd_api_clear_all_internal_breakpoints(cs, data);
+ return;
+
case DbgKdGetContextExApi:
kd_api_get_context_ex(cs, data);
break;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 30/39] windbg: debug exception subscribing
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (28 preceding siblings ...)
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 29/39] windbg: implement kd_api_write_breakpoint and kd_api_restore_breakpoint Mikhail Abakumov
@ 2018-12-05 12:54 ` Mikhail Abakumov
2018-12-05 14:36 ` Alex Bennée
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 31/39] windbg: implement kd_api_continue Mikhail Abakumov
` (11 subsequent siblings)
41 siblings, 1 reply; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Add handler registration of gdb debug exception. Its exception also can be used
for windbg.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
cpus.c | 19 ++++++++++++++++++-
gdbstub.c | 4 ++++
include/sysemu/sysemu.h | 2 ++
windbgstub.c | 14 ++++++++++++++
4 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/cpus.c b/cpus.c
index a2b33ccb29..c8b05260b4 100644
--- a/cpus.c
+++ b/cpus.c
@@ -79,6 +79,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 10000000
@@ -1103,9 +1105,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 c4e4f9f082..9ed4fe2e8e 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2074,6 +2074,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 8d6095d98b..826b701bfa 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -203,6 +203,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 a1c013cd8c..0e4ad6d009 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -129,9 +129,19 @@ static void windbg_send_control_packet(WindbgState *state, uint16_t type,
qemu_chr_fe_write(&state->chr, PTR(packet), sizeof(packet));
}
+static void windbg_bp_handler(CPUState *cs)
+{
+ DBGKD_ANY_WAIT_STATE_CHANGE *sc = kd_state_change_exc(cs);
+ windbg_send_data_packet(windbg_state, (uint8_t *) sc,
+ sizeof(DBGKD_ANY_WAIT_STATE_CHANGE),
+ PACKET_TYPE_KD_STATE_CHANGE64);
+}
+
static void windbg_vm_stop(void)
{
+ CPUState *cs = qemu_get_cpu(0);
vm_stop(RUN_STATE_PAUSED);
+ windbg_bp_handler(cs);
}
static void windbg_process_manipulate_packet(WindbgState *state)
@@ -481,6 +491,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;
}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 31/39] windbg: implement kd_api_continue
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (29 preceding siblings ...)
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 30/39] windbg: debug exception subscribing Mikhail Abakumov
@ 2018-12-05 12:54 ` Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 32/39] windbg: implement kd_api_read_io_space and kd_api_write_io_space Mikhail Abakumov
` (10 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@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 85b7322b82..2843ad055e 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -73,6 +73,7 @@ void kd_api_get_context(CPUState *cs, PacketData *pd);
void kd_api_set_context(CPUState *cs, PacketData *pd);
void kd_api_write_breakpoint(CPUState *cs, PacketData *pd);
void kd_api_restore_breakpoint(CPUState *cs, PacketData *pd);
+void kd_api_continue(CPUState *cs, PacketData *pd);
void kd_api_read_control_space(CPUState *cs, PacketData *pd);
void kd_api_write_control_space(CPUState *cs, PacketData *pd);
void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index ea96c0598c..8aa258e9fd 100644
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -10,6 +10,7 @@
*/
#include "exec/windbgstub-utils.h"
+#include "sysemu/sysemu.h"
static const char *kd_api_names[] = {
"DbgKdReadVirtualMemoryApi",
@@ -311,6 +312,20 @@ void kd_api_restore_breakpoint(CPUState *cs, PacketData *pd)
}
}
+void kd_api_continue(CPUState *cs, PacketData *pd)
+{
+ uint32_t status = ldl_p(&pd->m64.u.Continue2.ContinueStatus);
+ uint32_t trace = ldl_p(&pd->m64.u.Continue2.ControlSet.TraceFlag);
+ int ssFlag = trace ? SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER : 0;
+
+ if (NT_SUCCESS(status)) {
+ cpu_single_step(cs, ssFlag);
+ if (!runstate_needs_reset()) {
+ vm_start();
+ }
+ }
+}
+
void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd)
{
}
diff --git a/windbgstub.c b/windbgstub.c
index 0e4ad6d009..d64bbc3f34 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -183,6 +183,11 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_restore_breakpoint(cs, data);
break;
+ case DbgKdContinueApi:
+ case DbgKdContinueApi2:
+ kd_api_continue(cs, data);
+ return;
+
case DbgKdReadControlSpaceApi:
kd_api_read_control_space(cs, data);
break;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 32/39] windbg: implement kd_api_read_io_space and kd_api_write_io_space
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (30 preceding siblings ...)
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 31/39] windbg: implement kd_api_continue Mikhail Abakumov
@ 2018-12-05 12:55 ` Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 33/39] windbg: implement kd_api_read_physical_memory and kd_api_write_physical_memory Mikhail Abakumov
` (9 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:55 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@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 2843ad055e..f0a786cdef 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -76,6 +76,8 @@ void kd_api_restore_breakpoint(CPUState *cs, PacketData *pd);
void kd_api_continue(CPUState *cs, PacketData *pd);
void kd_api_read_control_space(CPUState *cs, PacketData *pd);
void kd_api_write_control_space(CPUState *cs, PacketData *pd);
+void kd_api_read_io_space(CPUState *cs, PacketData *pd);
+void kd_api_write_io_space(CPUState *cs, PacketData *pd);
void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd);
void kd_api_get_context_ex(CPUState *cs, PacketData *pd);
void kd_api_set_context_ex(CPUState *cs, PacketData *pd);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 8aa258e9fd..b3c2504be2 100644
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -10,6 +10,7 @@
*/
#include "exec/windbgstub-utils.h"
+#include "exec/address-spaces.h"
#include "sysemu/sysemu.h"
static const char *kd_api_names[] = {
@@ -326,6 +327,67 @@ void kd_api_continue(CPUState *cs, PacketData *pd)
}
}
+void kd_api_read_io_space(CPUState *cs, PacketData *pd)
+{
+ DBGKD_READ_WRITE_IO64 *io = &pd->m64.u.ReadWriteIo;
+ CPUArchState *env = cs->env_ptr;
+
+ target_ulong addr = ldtul_p(&io->IoAddress);
+ uint32_t value = 0;
+
+ switch (io->DataSize) {
+ case 1:
+ value = address_space_ldub(&address_space_io, addr,
+ cpu_get_mem_attrs(env), NULL);
+ stl_p(&io->DataValue, value);
+ break;
+ case 2:
+ value = address_space_lduw(&address_space_io, addr,
+ cpu_get_mem_attrs(env), NULL);
+ stl_p(&io->DataValue, value);
+ break;
+ case 4:
+ value = address_space_ldl(&address_space_io, addr,
+ cpu_get_mem_attrs(env), NULL);
+ stl_p(&io->DataValue, value);
+ break;
+ default:
+ pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+ return;
+ }
+
+ pd->m64.ReturnStatus = STATUS_SUCCESS;
+}
+
+void kd_api_write_io_space(CPUState *cs, PacketData *pd)
+{
+ DBGKD_READ_WRITE_IO64 *io = &pd->m64.u.ReadWriteIo;
+ CPUArchState *env = cs->env_ptr;
+
+ target_ulong addr = ldtul_p(&io->IoAddress);
+ uint32_t value = ldl_p(&io->DataValue);
+
+ switch (io->DataSize) {
+ case 1:
+ address_space_stb(&address_space_io, addr, value,
+ cpu_get_mem_attrs(env), NULL);
+ break;
+ case 2:
+ address_space_stw(&address_space_io, addr, value,
+ cpu_get_mem_attrs(env), NULL);
+ break;
+ case 4:
+ address_space_stl(&address_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_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd)
{
}
diff --git a/windbgstub.c b/windbgstub.c
index d64bbc3f34..78f96a6621 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -196,6 +196,14 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_write_control_space(cs, data);
break;
+ case DbgKdReadIoSpaceApi:
+ kd_api_read_io_space(cs, data);
+ break;
+
+ case DbgKdWriteIoSpaceApi:
+ kd_api_write_io_space(cs, data);
+ break;
+
case DbgKdClearAllInternalBreakpointsApi:
kd_api_clear_all_internal_breakpoints(cs, data);
return;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 33/39] windbg: implement kd_api_read_physical_memory and kd_api_write_physical_memory
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (31 preceding siblings ...)
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 32/39] windbg: implement kd_api_read_io_space and kd_api_write_io_space Mikhail Abakumov
@ 2018-12-05 12:55 ` Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 34/39] windbg: implement kd_api_get_version Mikhail Abakumov
` (8 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:55 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@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 f0a786cdef..fa67a7048d 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -78,6 +78,8 @@ void kd_api_read_control_space(CPUState *cs, PacketData *pd);
void kd_api_write_control_space(CPUState *cs, PacketData *pd);
void kd_api_read_io_space(CPUState *cs, PacketData *pd);
void kd_api_write_io_space(CPUState *cs, PacketData *pd);
+void kd_api_read_physical_memory(CPUState *cs, PacketData *pd);
+void kd_api_write_physical_memory(CPUState *cs, PacketData *pd);
void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd);
void kd_api_get_context_ex(CPUState *cs, PacketData *pd);
void kd_api_set_context_ex(CPUState *cs, PacketData *pd);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index b3c2504be2..602dcf0be8 100644
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -388,6 +388,35 @@ void kd_api_write_io_space(CPUState *cs, PacketData *pd)
pd->m64.ReturnStatus = STATUS_SUCCESS;
}
+void kd_api_read_physical_memory(CPUState *cs, PacketData *pd)
+{
+ DBGKD_READ_MEMORY64 *mem = &pd->m64.u.ReadMemory;
+ uint32_t len;
+ target_ulong addr;
+
+ len = MIN(ldl_p(&mem->TransferCount),
+ PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+ addr = ldtul_p(&mem->TargetBaseAddress);
+
+ cpu_physical_memory_rw(addr, pd->extra, len, 0);
+ pd->extra_size = len;
+ stl_p(&mem->ActualBytesRead, len);
+}
+
+void kd_api_write_physical_memory(CPUState *cs, PacketData *pd)
+{
+ DBGKD_WRITE_MEMORY64 *mem = &pd->m64.u.WriteMemory;
+ uint32_t len;
+ target_ulong addr;
+
+ len = MIN(ldl_p(&mem->TransferCount), pd->extra_size);
+ addr = ldtul_p(&mem->TargetBaseAddress);
+
+ cpu_physical_memory_rw(addr, pd->extra, len, 1);
+ pd->extra_size = 0;
+ stl_p(&mem->ActualBytesWritten, len);
+}
+
void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd)
{
}
diff --git a/windbgstub.c b/windbgstub.c
index 78f96a6621..25331f218f 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -204,6 +204,14 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_write_io_space(cs, data);
break;
+ case DbgKdReadPhysicalMemoryApi:
+ kd_api_read_physical_memory(cs, data);
+ break;
+
+ case DbgKdWritePhysicalMemoryApi:
+ kd_api_write_physical_memory(cs, data);
+ break;
+
case DbgKdClearAllInternalBreakpointsApi:
kd_api_clear_all_internal_breakpoints(cs, data);
return;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 34/39] windbg: implement kd_api_get_version
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (32 preceding siblings ...)
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 33/39] windbg: implement kd_api_read_physical_memory and kd_api_write_physical_memory Mikhail Abakumov
@ 2018-12-05 12:55 ` Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 35/39] windbg: implement kd_api_read_msr and kd_api_write_msr Mikhail Abakumov
` (7 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:55 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 1 +
target/i386/windbgstub.c | 61 +++++++++++++++++++++++++++++++++++++++
windbgstub.c | 4 +++
3 files changed, 66 insertions(+)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index fa67a7048d..adfc9936f3 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -80,6 +80,7 @@ void kd_api_read_io_space(CPUState *cs, PacketData *pd);
void kd_api_write_io_space(CPUState *cs, PacketData *pd);
void kd_api_read_physical_memory(CPUState *cs, PacketData *pd);
void kd_api_write_physical_memory(CPUState *cs, PacketData *pd);
+void kd_api_get_version(CPUState *cs, PacketData *pd);
void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd);
void kd_api_get_context_ex(CPUState *cs, PacketData *pd);
void kd_api_set_context_ex(CPUState *cs, PacketData *pd);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 6d2e7de746..9e84027f19 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -15,6 +15,9 @@
#ifdef TARGET_X86_64
#define OFFSET_KPCR_SELF 0x18
#define OFFSET_KPCR_LOCK_ARRAY 0x28
+#define OFFSET_KDBG_LIST 0x0
+#define OFFSET_KDBG_KERNBASE 0x18
+#define OFFSET_KDBG_MODULELIST 0x48
#define OFFSET_KPRCB 0x20
#define OFFSET_KPRCB_CURRTHREAD 0x8
#else /* TARGET_I386 */
@@ -1080,6 +1083,64 @@ void kd_api_set_context_ex(CPUState *cs, PacketData *pd)
stl_p(&ctx->BytesCopied, len);
}
+void kd_api_get_version(CPUState *cs, PacketData *pd)
+{
+ DBGKD_GET_VERSION64 *kdver = (DBGKD_GET_VERSION64 *) (PTR(pd->m64) + 0x10);
+#ifdef TARGET_X86_64
+ target_ulong kdbg = kdDebuggerDataBlock.addr;
+ target_ulong dDataList = VMEM_ADDR(cs, kdbg + OFFSET_KDBG_LIST);
+ target_ulong kernbase = VMEM_ADDR(cs, kdbg + OFFSET_KDBG_KERNBASE);
+ target_ulong modules = VMEM_ADDR(cs, kdbg + OFFSET_KDBG_MODULELIST);
+
+ /* TODO: Fix this hardcoded value.
+ * Receives 0xF if the target's operating system is a free build,
+ * and 0xC if it is a checked build.
+ */
+ stw_p(&kdver->MajorVersion, 0xF);
+ /* TODO: Fix this hardcoded value. Needs NtBuildNumber. How to get it? */
+ stw_p(&kdver->MinorVersion, 0x1db1);
+ stb_p(&kdver->ProtocolVersion, DBGKD_64BIT_PROTOCOL_VERSION2);
+ /* TODO: Fix this hardcoded value. */
+ stb_p(&kdver->KdSecondaryVersion, 0);
+ stw_p(&kdver->Flags,
+ DBGKD_VERS_FLAG_MP | DBGKD_VERS_FLAG_DATA | DBGKD_VERS_FLAG_PTR64);
+ stw_p(&kdver->MachineType, IMAGE_FILE_MACHINE_AMD64);
+ stb_p(&kdver->MaxPacketType, PACKET_TYPE_MAX);
+ stb_p(&kdver->MaxStateChange,
+ DbgKdMaximumStateChange - DbgKdMinimumStateChange);
+ stb_p(&kdver->MaxManipulate,
+ DbgKdMaximumManipulate - DbgKdMinimumManipulate);
+ /* FIXME: Maybe DBGKD_SIMULATION_EXDI? */
+ stb_p(&kdver->Simulation, DBGKD_SIMULATION_NONE);
+ stw_p(&kdver->Unused[0], 0);
+ sttul_p(&kdver->KernBase, kernbase);
+ sttul_p(&kdver->PsLoadedModuleList, modules);
+ sttul_p(&kdver->DebuggerDataList, dDataList);
+#else /* TARGET_I386 */
+ int err = cpu_memory_rw_debug(cs, kdVersion.addr, (uint8_t *) kdver,
+ sizeof(DBGKD_MANIPULATE_STATE64) - 0x10, 0);
+ if (!err) {
+ stw_p(&kdver->MajorVersion, kdver->MajorVersion);
+ stw_p(&kdver->MinorVersion, kdver->MinorVersion);
+ stb_p(&kdver->ProtocolVersion, kdver->ProtocolVersion);
+ stb_p(&kdver->KdSecondaryVersion, kdver->KdSecondaryVersion);
+ stw_p(&kdver->Flags, kdver->Flags);
+ stw_p(&kdver->MachineType, kdver->MachineType);
+ stb_p(&kdver->MaxPacketType, kdver->MaxPacketType);
+ stb_p(&kdver->MaxStateChange, kdver->MaxStateChange);
+ stb_p(&kdver->MaxManipulate, kdver->MaxManipulate);
+ stb_p(&kdver->Simulation, kdver->Simulation);
+ stw_p(&kdver->Unused[0], kdver->Unused[0]);
+ sttul_p(&kdver->KernBase, kdver->KernBase);
+ sttul_p(&kdver->PsLoadedModuleList, kdver->PsLoadedModuleList);
+ sttul_p(&kdver->DebuggerDataList, kdver->DebuggerDataList);
+ } else {
+ pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+ WINDBG_ERROR("get_version: " FMT_ERR, err);
+ }
+#endif /* TARGET_I386 */
+}
+
static bool find_KPCR(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
diff --git a/windbgstub.c b/windbgstub.c
index 25331f218f..366856bc81 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -212,6 +212,10 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_write_physical_memory(cs, data);
break;
+ case DbgKdGetVersionApi:
+ kd_api_get_version(cs, data);
+ break;
+
case DbgKdClearAllInternalBreakpointsApi:
kd_api_clear_all_internal_breakpoints(cs, data);
return;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 35/39] windbg: implement kd_api_read_msr and kd_api_write_msr
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (33 preceding siblings ...)
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 34/39] windbg: implement kd_api_get_version Mikhail Abakumov
@ 2018-12-05 12:55 ` Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 36/39] windbg: implement kd_api_search_memory Mikhail Abakumov
` (6 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:55 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Add sub functions for helper_wrmsr and helper_rdmsr: cpu_x86_write_msr
and cpu_x86_read_msr.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 2 ++
target/i386/cpu.h | 5 +++++
target/i386/misc_helper.c | 39 ++++++++++++++++++++++++++++-----------
target/i386/windbgstub.c | 30 ++++++++++++++++++++++++++++++
windbgstub.c | 8 ++++++++
5 files changed, 73 insertions(+), 11 deletions(-)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index adfc9936f3..74e3b9a0da 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -81,6 +81,8 @@ void kd_api_write_io_space(CPUState *cs, PacketData *pd);
void kd_api_read_physical_memory(CPUState *cs, PacketData *pd);
void kd_api_write_physical_memory(CPUState *cs, PacketData *pd);
void kd_api_get_version(CPUState *cs, PacketData *pd);
+void kd_api_read_msr(CPUState *cs, PacketData *pd);
+void kd_api_write_msr(CPUState *cs, PacketData *pd);
void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd);
void kd_api_get_context_ex(CPUState *cs, PacketData *pd);
void kd_api_set_context_ex(CPUState *cs, PacketData *pd);
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 9c52d0cbeb..0f451d81bf 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1680,6 +1680,11 @@ 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);
+#ifndef CONFIG_USER_ONLY
+void cpu_x86_write_msr(CPUX86State *env, uint64_t val);
+uint64_t cpu_x86_read_msr(CPUX86State *env);
+#endif
+
/* 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 6ae67cf885..1f9adb246d 100644
--- a/target/i386/misc_helper.c
+++ b/target/i386/misc_helper.c
@@ -228,15 +228,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 & 0xffff;
@@ -386,11 +379,9 @@ 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;
@@ -537,6 +528,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 9e84027f19..ccc7bc3035 100644
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -1083,6 +1083,36 @@ void kd_api_set_context_ex(CPUState *cs, PacketData *pd)
stl_p(&ctx->BytesCopied, len);
}
+void kd_api_read_msr(CPUState *cs, PacketData *pd)
+{
+#ifndef CONFIG_USER_ONLY
+ DBGKD_READ_WRITE_MSR *m64c = &pd->m64.u.ReadWriteMsr;
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+ uint64_t val = cpu_x86_read_msr(env);
+
+ stq_p(&val, val);
+
+ m64c->DataValueLow = val;
+ m64c->DataValueHigh = val >> 32;
+ pd->m64.ReturnStatus = STATUS_SUCCESS;
+#endif /* !CONFIG_USER_ONLY */
+}
+
+void kd_api_write_msr(CPUState *cs, PacketData *pd)
+{
+#ifndef CONFIG_USER_ONLY
+ DBGKD_READ_WRITE_MSR *m64c = &pd->m64.u.ReadWriteMsr;
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+ uint64_t val = m64c->DataValueLow | ((uint64_t) m64c->DataValueHigh) << 32;
+
+ cpu_x86_write_msr(env, ldq_p(&val));
+
+ pd->m64.ReturnStatus = STATUS_SUCCESS;
+#endif /* !CONFIG_USER_ONLY */
+}
+
void kd_api_get_version(CPUState *cs, PacketData *pd)
{
DBGKD_GET_VERSION64 *kdver = (DBGKD_GET_VERSION64 *) (PTR(pd->m64) + 0x10);
diff --git a/windbgstub.c b/windbgstub.c
index 366856bc81..109a52b663 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -216,6 +216,14 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_get_version(cs, data);
break;
+ case DbgKdReadMachineSpecificRegister:
+ kd_api_read_msr(cs, data);
+ break;
+
+ case DbgKdWriteMachineSpecificRegister:
+ kd_api_write_msr(cs, data);
+ break;
+
case DbgKdClearAllInternalBreakpointsApi:
kd_api_clear_all_internal_breakpoints(cs, data);
return;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 36/39] windbg: implement kd_api_search_memory
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (34 preceding siblings ...)
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 35/39] windbg: implement kd_api_read_msr and kd_api_write_msr Mikhail Abakumov
@ 2018-12-05 12:55 ` Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 37/39] windbg: implement kd_api_fill_memory Mikhail Abakumov
` (5 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:55 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 1 +
windbgstub-utils.c | 17 +++++++++++++++++
windbgstub.c | 4 ++++
3 files changed, 22 insertions(+)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 74e3b9a0da..4eb976260b 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -83,6 +83,7 @@ void kd_api_write_physical_memory(CPUState *cs, PacketData *pd);
void kd_api_get_version(CPUState *cs, PacketData *pd);
void kd_api_read_msr(CPUState *cs, PacketData *pd);
void kd_api_write_msr(CPUState *cs, PacketData *pd);
+void kd_api_search_memory(CPUState *cs, PacketData *pd);
void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd);
void kd_api_get_context_ex(CPUState *cs, PacketData *pd);
void kd_api_set_context_ex(CPUState *cs, PacketData *pd);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 602dcf0be8..848d52046b 100644
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -417,6 +417,23 @@ void kd_api_write_physical_memory(CPUState *cs, PacketData *pd)
stl_p(&mem->ActualBytesWritten, len);
}
+void kd_api_search_memory(CPUState *cs, PacketData *pd)
+{
+ DBGKD_SEARCH_MEMORY *m64c = &pd->m64.u.SearchMemory;
+ int s_len = MAX(ldq_p(&m64c->SearchLength), 1);
+ int p_len = MIN(ldl_p(&m64c->PatternLength), pd->extra_size);
+ target_ulong addr = ldq_p(&m64c->SearchAddress);
+ InitedAddr find =
+ windbg_search_vmaddr(cs, addr, addr + s_len, pd->extra, p_len);
+ pd->extra_size = 0;
+ if (find.is_init) {
+ stl_p(&m64c->FoundAddress, find.addr);
+ pd->m64.ReturnStatus = STATUS_SUCCESS;
+ } else {
+ pd->m64.ReturnStatus = STATUS_NO_MORE_ENTRIES;
+ }
+}
+
void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd)
{
}
diff --git a/windbgstub.c b/windbgstub.c
index 109a52b663..a50de68db5 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -224,6 +224,10 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_write_msr(cs, data);
break;
+ case DbgKdSearchMemoryApi:
+ kd_api_search_memory(cs, data);
+ break;
+
case DbgKdClearAllInternalBreakpointsApi:
kd_api_clear_all_internal_breakpoints(cs, data);
return;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 37/39] windbg: implement kd_api_fill_memory
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (35 preceding siblings ...)
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 36/39] windbg: implement kd_api_search_memory Mikhail Abakumov
@ 2018-12-05 12:55 ` Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 38/39] windbg: implement kd_api_query_memory Mikhail Abakumov
` (4 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:55 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 1 +
windbgstub-utils.c | 41 +++++++++++++++++++++++++++++++++++++++
windbgstub.c | 4 ++++
3 files changed, 46 insertions(+)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 4eb976260b..8192a7b849 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -85,6 +85,7 @@ void kd_api_read_msr(CPUState *cs, PacketData *pd);
void kd_api_write_msr(CPUState *cs, PacketData *pd);
void kd_api_search_memory(CPUState *cs, PacketData *pd);
void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd);
+void kd_api_fill_memory(CPUState *cs, PacketData *pd);
void kd_api_get_context_ex(CPUState *cs, PacketData *pd);
void kd_api_set_context_ex(CPUState *cs, PacketData *pd);
void kd_api_unsupported(CPUState *cs, PacketData *pd);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 848d52046b..80f87c862b 100644
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -438,6 +438,47 @@ void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd)
{
}
+void kd_api_fill_memory(CPUState *cs, PacketData *pd)
+{
+ DBGKD_FILL_MEMORY *m64c = &pd->m64.u.FillMemory;
+ uint32_t len = ldl_p(&m64c->Length);
+ target_ulong addr = ldq_p(&m64c->Address);
+ uint16_t pattern = MIN(ldl_p(&m64c->PatternLength), pd->extra_size);
+ uint16_t flags = ldl_p(&m64c->Flags);
+ int err, offset = 0;
+
+ uint8_t *mem = g_new(uint8_t, 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(cs, addr + offset, mem,
+ MIN(pattern, len - offset), 1);
+ offset += pattern;
+ if (err) {
+ DPRINTF("fill_memory: No physical page mapped: " FMT_ADDR "\n",
+ 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;
+ }
+
+ g_free(mem);
+}
+
void kd_api_unsupported(CPUState *cs, PacketData *pd)
{
WINDBG_ERROR("Caught unimplemented api %s", kd_api_name(pd->m64.ApiNumber));
diff --git a/windbgstub.c b/windbgstub.c
index a50de68db5..daf6d37aa1 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -232,6 +232,10 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_clear_all_internal_breakpoints(cs, data);
return;
+ case DbgKdFillMemoryApi:
+ kd_api_fill_memory(cs, data);
+ break;
+
case DbgKdGetContextExApi:
kd_api_get_context_ex(cs, data);
break;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 38/39] windbg: implement kd_api_query_memory
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (36 preceding siblings ...)
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 37/39] windbg: implement kd_api_fill_memory Mikhail Abakumov
@ 2018-12-05 12:55 ` Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 39/39] windbg: maintainers Mikhail Abakumov
` (3 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:55 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
include/exec/windbgstub-utils.h | 1 +
windbgstub-utils.c | 10 ++++++++++
windbgstub.c | 4 ++++
3 files changed, 15 insertions(+)
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 8192a7b849..bddb52d3db 100644
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -86,6 +86,7 @@ void kd_api_write_msr(CPUState *cs, PacketData *pd);
void kd_api_search_memory(CPUState *cs, PacketData *pd);
void kd_api_clear_all_internal_breakpoints(CPUState *cs, PacketData *pd);
void kd_api_fill_memory(CPUState *cs, PacketData *pd);
+void kd_api_query_memory(CPUState *cs, PacketData *pd);
void kd_api_get_context_ex(CPUState *cs, PacketData *pd);
void kd_api_set_context_ex(CPUState *cs, PacketData *pd);
void kd_api_unsupported(CPUState *cs, PacketData *pd);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 80f87c862b..0c895d8fc3 100644
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -479,6 +479,16 @@ void kd_api_fill_memory(CPUState *cs, PacketData *pd)
g_free(mem);
}
+void kd_api_query_memory(CPUState *cs, PacketData *pd)
+{
+ DBGKD_QUERY_MEMORY *mem = &pd->m64.u.QueryMemory;
+
+ /* TODO: Needs test memory. */
+ stl_p(&mem->AddressSpace, DBGKD_QUERY_MEMORY_PROCESS);
+ stl_p(&mem->Flags, DBGKD_QUERY_MEMORY_READ | DBGKD_QUERY_MEMORY_WRITE |
+ DBGKD_QUERY_MEMORY_EXECUTE);
+}
+
void kd_api_unsupported(CPUState *cs, PacketData *pd)
{
WINDBG_ERROR("Caught unimplemented api %s", kd_api_name(pd->m64.ApiNumber));
diff --git a/windbgstub.c b/windbgstub.c
index daf6d37aa1..23ad05f12b 100644
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -236,6 +236,10 @@ static void windbg_process_manipulate_packet(WindbgState *state)
kd_api_fill_memory(cs, data);
break;
+ case DbgKdQueryMemoryApi:
+ kd_api_query_memory(cs, data);
+ break;
+
case DbgKdGetContextExApi:
kd_api_get_context_ex(cs, data);
break;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [Qemu-devel] [PATCH 2 39/39] windbg: maintainers
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (37 preceding siblings ...)
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 38/39] windbg: implement kd_api_query_memory Mikhail Abakumov
@ 2018-12-05 12:55 ` Mikhail Abakumov
2018-12-05 14:30 ` [Qemu-devel] [PATCH 2 00/39] Windbg supporting no-reply
` (2 subsequent siblings)
41 siblings, 0 replies; 44+ messages in thread
From: Mikhail Abakumov @ 2018-12-05 12:55 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Add WinDbg stub to the MAINTAINERS.
Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
---
MAINTAINERS | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 1032406c56..dffbd267be 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1689,6 +1689,18 @@ S: Odd Fixes
F: gdbstub*
F: gdb-xml/
+WinDbg stub
+M: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
+R: Pavel Dovgalyuk <pavel.dovgaluk@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 <pbonzini@redhat.com>
S: Supported
^ permalink raw reply related [flat|nested] 44+ messages in thread
* Re: [Qemu-devel] [PATCH 2 00/39] Windbg supporting
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (38 preceding siblings ...)
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 39/39] windbg: maintainers Mikhail Abakumov
@ 2018-12-05 14:30 ` no-reply
2018-12-05 14:37 ` no-reply
2018-12-05 14:38 ` no-reply
41 siblings, 0 replies; 44+ messages in thread
From: no-reply @ 2018-12-05 14:30 UTC (permalink / raw)
To: mikhail.abakumov
Cc: famz, qemu-devel, sw, lprosek, dovgaluk, rkagan, pbonzini, den
Patchew URL: https://patchew.org/QEMU/154401431697.8440.845616703562380651.stgit@Misha-PC.lan02.inno/
Hi,
This series failed the docker-mingw@fedora build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.
=== TEST SCRIPT BEGIN ===
#!/bin/bash
time make docker-test-mingw@fedora SHOW_ENV=1 J=8
=== TEST SCRIPT END ===
CC x86_64-softmmu/windbgstub-utils.o
CC x86_64-softmmu/accel/accel.o
/tmp/qemu-test/src/windbgstub-utils.c: In function 'windbg_search_vmaddr':
/tmp/qemu-test/src/windbgstub-utils.c:173:9: error: 'addr' undeclared (first use in this function); did you mean 'vaddr'?
addr = 0;
^~~~
vaddr
/tmp/qemu-test/src/windbgstub-utils.c:173:9: note: each undeclared identifier is reported only once for each function it appears in
/tmp/qemu-test/src/windbgstub-utils.c:173:17: error: expected '}' before ';' token
addr = 0;
^
make[1]: *** [/tmp/qemu-test/src/rules.mak:69: windbgstub-utils.o] Error 1
The full log is available at
http://patchew.org/logs/154401431697.8440.845616703562380651.stgit@Misha-PC.lan02.inno/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [Qemu-devel] [PATCH 2 30/39] windbg: debug exception subscribing
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 30/39] windbg: debug exception subscribing Mikhail Abakumov
@ 2018-12-05 14:36 ` Alex Bennée
0 siblings, 0 replies; 44+ messages in thread
From: Alex Bennée @ 2018-12-05 14:36 UTC (permalink / raw)
To: qemu-devel; +Cc: sw, lprosek, dovgaluk, rkagan, pbonzini, den
Mikhail Abakumov <mikhail.abakumov@ispras.ru> writes:
> Add handler registration of gdb debug exception. Its exception also can be used
> for windbg.
>
> Signed-off-by: Mikhail Abakumov <mikhail.abakumov@ispras.ru>
> Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru>
> ---
> cpus.c | 19 ++++++++++++++++++-
> gdbstub.c | 4 ++++
> include/sysemu/sysemu.h | 2 ++
> windbgstub.c | 14 ++++++++++++++
> 4 files changed, 38 insertions(+), 1 deletion(-)
>
> diff --git a/cpus.c b/cpus.c
> index a2b33ccb29..c8b05260b4 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -79,6 +79,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 10000000
> @@ -1103,9 +1105,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 we are going to have a handler approach we can make gdb_set_stop_cpu
static and remove the gdbstub.h reference from cpus.c as well.
> + 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 c4e4f9f082..9ed4fe2e8e 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -2074,6 +2074,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 8d6095d98b..826b701bfa 100644
> --- a/include/sysemu/sysemu.h
> +++ b/include/sysemu/sysemu.h
> @@ -203,6 +203,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 a1c013cd8c..0e4ad6d009 100644
> --- a/windbgstub.c
> +++ b/windbgstub.c
> @@ -129,9 +129,19 @@ static void windbg_send_control_packet(WindbgState *state, uint16_t type,
> qemu_chr_fe_write(&state->chr, PTR(packet), sizeof(packet));
> }
>
> +static void windbg_bp_handler(CPUState *cs)
> +{
> + DBGKD_ANY_WAIT_STATE_CHANGE *sc = kd_state_change_exc(cs);
> + windbg_send_data_packet(windbg_state, (uint8_t *) sc,
> + sizeof(DBGKD_ANY_WAIT_STATE_CHANGE),
> + PACKET_TYPE_KD_STATE_CHANGE64);
> +}
> +
> static void windbg_vm_stop(void)
> {
> + CPUState *cs = qemu_get_cpu(0);
This can fail - although I guess it's unlikely someone has hotplugged cpu0.
> vm_stop(RUN_STATE_PAUSED);
> + windbg_bp_handler(cs);
> }
>
> static void windbg_process_manipulate_packet(WindbgState *state)
> @@ -481,6 +491,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;
> }
--
Alex Bennée
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [Qemu-devel] [PATCH 2 00/39] Windbg supporting
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (39 preceding siblings ...)
2018-12-05 14:30 ` [Qemu-devel] [PATCH 2 00/39] Windbg supporting no-reply
@ 2018-12-05 14:37 ` no-reply
2018-12-05 14:38 ` no-reply
41 siblings, 0 replies; 44+ messages in thread
From: no-reply @ 2018-12-05 14:37 UTC (permalink / raw)
To: mikhail.abakumov
Cc: famz, qemu-devel, sw, lprosek, dovgaluk, rkagan, pbonzini, den
Patchew URL: https://patchew.org/QEMU/154401431697.8440.845616703562380651.stgit@Misha-PC.lan02.inno/
Hi,
This series failed the docker-quick@centos7 build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.
=== TEST SCRIPT BEGIN ===
#!/bin/bash
time make docker-test-quick@centos7 SHOW_ENV=1 J=8
=== TEST SCRIPT END ===
libpmem support no
libudev no
WARNING: Use of SDL 1.2 is deprecated and will be removed in
WARNING: future releases. Please switch to using SDL 2.0
NOTE: cross-compilers enabled: 'cc'
GEN x86_64-softmmu/config-devices.mak.tmp
---
CC x86_64-softmmu/accel/accel.o
CC x86_64-softmmu/accel/kvm/kvm-all.o
/tmp/qemu-test/src/windbgstub-utils.c: In function 'windbg_search_vmaddr':
/tmp/qemu-test/src/windbgstub-utils.c:173:9: error: 'addr' undeclared (first use in this function)
addr = 0;
^
/tmp/qemu-test/src/windbgstub-utils.c:173:9: note: each undeclared identifier is reported only once for each function it appears in
/tmp/qemu-test/src/windbgstub-utils.c:173:17: error: expected '}' before ';' token
addr = 0;
^
make[1]: *** [windbgstub-utils.o] Error 1
The full log is available at
http://patchew.org/logs/154401431697.8440.845616703562380651.stgit@Misha-PC.lan02.inno/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [Qemu-devel] [PATCH 2 00/39] Windbg supporting
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
` (40 preceding siblings ...)
2018-12-05 14:37 ` no-reply
@ 2018-12-05 14:38 ` no-reply
41 siblings, 0 replies; 44+ messages in thread
From: no-reply @ 2018-12-05 14:38 UTC (permalink / raw)
To: mikhail.abakumov
Cc: famz, qemu-devel, sw, lprosek, dovgaluk, rkagan, pbonzini, den
Patchew URL: https://patchew.org/QEMU/154401431697.8440.845616703562380651.stgit@Misha-PC.lan02.inno/
Hi,
This series seems to have some coding style problems. See output below for
more information:
Message-id: 154401431697.8440.845616703562380651.stgit@Misha-PC.lan02.inno
Type: series
Subject: [Qemu-devel] [PATCH 2 00/39] Windbg supporting
=== TEST SCRIPT BEGIN ===
#!/bin/bash
BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done
exit $failed
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
3ab8f93 windbg: maintainers
19399ee windbg: implement kd_api_query_memory
fedc3ed windbg: implement kd_api_fill_memory
2327661 windbg: implement kd_api_search_memory
b3ebde4 windbg: implement kd_api_read_msr and kd_api_write_msr
bd560bc windbg: implement kd_api_get_version
0d30b4b windbg: implement kd_api_read_physical_memory and kd_api_write_physical_memory
5f3d2da windbg: implement kd_api_read_io_space and kd_api_write_io_space
a970aa1 windbg: implement kd_api_continue
e7f4432 windbg: debug exception subscribing
92745ee windbg: implement kd_api_write_breakpoint and kd_api_restore_breakpoint
1a275c5 windbg: implement kd_api_read_control_space and kd_api_write_control_space
e72cf62 windbg: implement kd_api_get_context_ex and kd_api_set_context_ex
ee2f444 windbg: implement kd_api_get_context and kd_api_set_context
c12adfa windbg: [de]serialization cpu spec registers
930f2c1 windbg: [de]serialization cpu context
1956044 windbg: add helper functions
e92c5a0 windbg: some kernel structures
e444486 windbg: implement kd_api_read_virtual_memory and kd_api_write_virtual_memory
829a870 windbg: implement windbg_process_manipulate_packet
3f73f31 windbg: implement windbg_process_data_packet
fd43737 windbg: implement windbg_process_control_packet
313477d windbg: generate ExceptionStateChange and LoadSymbolsStateChange
30ccfe5 windbg: init DBGKD_ANY_WAIT_STATE_CHANGE
6298ba5 windbg: handler of parsing context
dfe88bf windbg: send data and control packets
bc8ec4c windbg: parsing data stream
1de1e8f windbg: implement find_kdDebuggerDataBlock
d8cc50a windbg: add windbg_search_vmaddr
31d02b5 windbg: implement find_kdVersion
1d436b8 windbg: implement find_KPCR
b862005 windbg: implement windbg_on_load
ae78964 windbg: hook to wrmsr operation
2e6e5ad windbg: add chardev
6471d15 windbg: add WindbgState
4433b42 windbg: add helper features
5413de4 windbg: add -windbg option
e810415 windbg: add windbg's KD header file
c6b263d windbg: add empty windbgstub files
=== OUTPUT BEGIN ===
Checking PATCH 1/39: windbg: add empty windbgstub files...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#35:
new file mode 100644
total: 0 errors, 1 warnings, 121 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 2/39: windbg: add windbg's KD header file...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#14:
new file mode 100644
total: 0 errors, 1 warnings, 934 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 3/39: windbg: add -windbg option...
Checking PATCH 4/39: windbg: add helper features...
Checking PATCH 5/39: windbg: add WindbgState...
Checking PATCH 6/39: windbg: add chardev...
Checking PATCH 7/39: windbg: hook to wrmsr operation...
Checking PATCH 8/39: windbg: implement windbg_on_load...
Checking PATCH 9/39: windbg: implement find_KPCR...
Checking PATCH 10/39: windbg: implement find_kdVersion...
Checking PATCH 11/39: windbg: add windbg_search_vmaddr...
Checking PATCH 12/39: windbg: implement find_kdDebuggerDataBlock...
Checking PATCH 13/39: windbg: parsing data stream...
Checking PATCH 14/39: windbg: send data and control packets...
Checking PATCH 15/39: windbg: handler of parsing context...
Checking PATCH 16/39: windbg: init DBGKD_ANY_WAIT_STATE_CHANGE...
Checking PATCH 17/39: windbg: generate ExceptionStateChange and LoadSymbolsStateChange...
Checking PATCH 18/39: windbg: implement windbg_process_control_packet...
Checking PATCH 19/39: windbg: implement windbg_process_data_packet...
Checking PATCH 20/39: windbg: implement windbg_process_manipulate_packet...
Checking PATCH 21/39: windbg: implement kd_api_read_virtual_memory and kd_api_write_virtual_memory...
Checking PATCH 22/39: windbg: some kernel structures...
Checking PATCH 23/39: windbg: add helper functions...
ERROR: Macros with multiple statements should be enclosed in a do - while loop
#126: FILE: target/i386/windbgstub.c:387:
+#define CASE_FIELD(stct, field, field_size, block) \
+ case offsetof(stct, field): \
+ field_size = sizeof_field(stct, field); \
+ block; \
+ break;
total: 1 errors, 0 warnings, 129 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 24/39: windbg: [de]serialization cpu context...
Checking PATCH 25/39: windbg: [de]serialization cpu spec registers...
Checking PATCH 26/39: windbg: implement kd_api_get_context and kd_api_set_context...
Checking PATCH 27/39: windbg: implement kd_api_get_context_ex and kd_api_set_context_ex...
Checking PATCH 28/39: windbg: implement kd_api_read_control_space and kd_api_write_control_space...
Checking PATCH 29/39: windbg: implement kd_api_write_breakpoint and kd_api_restore_breakpoint...
Checking PATCH 30/39: windbg: debug exception subscribing...
Checking PATCH 31/39: windbg: implement kd_api_continue...
Checking PATCH 32/39: windbg: implement kd_api_read_io_space and kd_api_write_io_space...
Checking PATCH 33/39: windbg: implement kd_api_read_physical_memory and kd_api_write_physical_memory...
Checking PATCH 34/39: windbg: implement kd_api_get_version...
Checking PATCH 35/39: windbg: implement kd_api_read_msr and kd_api_write_msr...
Checking PATCH 36/39: windbg: implement kd_api_search_memory...
Checking PATCH 37/39: windbg: implement kd_api_fill_memory...
Checking PATCH 38/39: windbg: implement kd_api_query_memory...
Checking PATCH 39/39: windbg: maintainers...
=== OUTPUT END ===
Test command exited with code: 1
The full log is available at
http://patchew.org/logs/154401431697.8440.845616703562380651.stgit@Misha-PC.lan02.inno/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 44+ messages in thread
end of thread, other threads:[~2018-12-05 15:23 UTC | newest]
Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-12-05 12:52 [Qemu-devel] [PATCH 2 00/39] Windbg supporting Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 01/39] windbg: add empty windbgstub files Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 02/39] windbg: add windbg's KD header file Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 03/39] windbg: add -windbg option Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 04/39] windbg: add helper features Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 05/39] windbg: add WindbgState Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 06/39] windbg: add chardev Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 07/39] windbg: hook to wrmsr operation Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 08/39] windbg: implement windbg_on_load Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 09/39] windbg: implement find_KPCR Mikhail Abakumov
2018-12-05 12:52 ` [Qemu-devel] [PATCH 2 10/39] windbg: implement find_kdVersion Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 11/39] windbg: add windbg_search_vmaddr Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 12/39] windbg: implement find_kdDebuggerDataBlock Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 13/39] windbg: parsing data stream Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 14/39] windbg: send data and control packets Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 15/39] windbg: handler of parsing context Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 16/39] windbg: init DBGKD_ANY_WAIT_STATE_CHANGE Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 17/39] windbg: generate ExceptionStateChange and LoadSymbolsStateChange Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 18/39] windbg: implement windbg_process_control_packet Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 19/39] windbg: implement windbg_process_data_packet Mikhail Abakumov
2018-12-05 12:53 ` [Qemu-devel] [PATCH 2 20/39] windbg: implement windbg_process_manipulate_packet Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 21/39] windbg: implement kd_api_read_virtual_memory and kd_api_write_virtual_memory Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 22/39] windbg: some kernel structures Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 23/39] windbg: add helper functions Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 24/39] windbg: [de]serialization cpu context Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 25/39] windbg: [de]serialization cpu spec registers Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 26/39] windbg: implement kd_api_get_context and kd_api_set_context Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 27/39] windbg: implement kd_api_get_context_ex and kd_api_set_context_ex Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 28/39] windbg: implement kd_api_read_control_space and kd_api_write_control_space Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 29/39] windbg: implement kd_api_write_breakpoint and kd_api_restore_breakpoint Mikhail Abakumov
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 30/39] windbg: debug exception subscribing Mikhail Abakumov
2018-12-05 14:36 ` Alex Bennée
2018-12-05 12:54 ` [Qemu-devel] [PATCH 2 31/39] windbg: implement kd_api_continue Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 32/39] windbg: implement kd_api_read_io_space and kd_api_write_io_space Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 33/39] windbg: implement kd_api_read_physical_memory and kd_api_write_physical_memory Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 34/39] windbg: implement kd_api_get_version Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 35/39] windbg: implement kd_api_read_msr and kd_api_write_msr Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 36/39] windbg: implement kd_api_search_memory Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 37/39] windbg: implement kd_api_fill_memory Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 38/39] windbg: implement kd_api_query_memory Mikhail Abakumov
2018-12-05 12:55 ` [Qemu-devel] [PATCH 2 39/39] windbg: maintainers Mikhail Abakumov
2018-12-05 14:30 ` [Qemu-devel] [PATCH 2 00/39] Windbg supporting no-reply
2018-12-05 14:37 ` no-reply
2018-12-05 14:38 ` no-reply
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).