* [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
* 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
* [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 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