[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 13/39] windbg: parsing data stream
From: |
Mikhail Abakumov |
Subject: |
[Qemu-devel] [PATCH 13/39] windbg: parsing data stream |
Date: |
Thu, 29 Nov 2018 17:28:43 +0300 |
User-agent: |
StGit/0.17.1-dirty |
Add parsing data stream to packets from windbg client.
Signed-off-by: Mikhail Abakumov <address@hidden>
Signed-off-by: Pavel Dovgalyuk <address@hidden>
---
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);
- [Qemu-devel] [PATCH 03/39] windbg: add -windbg option, (continued)
- [Qemu-devel] [PATCH 03/39] windbg: add -windbg option, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 04/39] windbg: add helper features, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 05/39] windbg: add WindbgState, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 06/39] windbg: add chardev, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 07/39] windbg: hook to wrmsr operation, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 08/39] windbg: implement windbg_on_load, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 09/39] windbg: implement find_KPCR, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 10/39] windbg: implement find_kdVersion, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 11/39] windbg: add windbg_search_vmaddr, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 12/39] windbg: implement find_kdDebuggerDataBlock, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 13/39] windbg: parsing data stream,
Mikhail Abakumov <=
- [Qemu-devel] [PATCH 15/39] windbg: handler of parsing context, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 14/39] windbg: send data and control packets, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 16/39] windbg: init DBGKD_ANY_WAIT_STATE_CHANGE, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 17/39] windbg: generate ExceptionStateChange and LoadSymbolsStateChange, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 18/39] windbg: implement windbg_process_control_packet, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 20/39] windbg: implement windbg_process_manipulate_packet, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 19/39] windbg: implement windbg_process_data_packet, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 21/39] windbg: implement kd_api_read_virtual_memory and kd_api_write_virtual_memory, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 22/39] windbg: some kernel structures, Mikhail Abakumov, 2018/11/29
- [Qemu-devel] [PATCH 23/39] windbg: add helper functions, Mikhail Abakumov, 2018/11/29