[KDGDB]
[reactos.git] / reactos / drivers / base / kdgdb / i386_sup.c
1 /*
2 * COPYRIGHT: GPL, see COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/base/kddll/gdb_input.c
5 * PURPOSE: Base functions for the kernel debugger.
6 */
7
8 #include "kdgdb.h"
9
10 enum reg_name
11 {
12 EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
13 EIP,
14 EFLAGS,
15 CS, SS, DS, ES, FS, GS,
16 ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7,
17 FCTRL, FSTAT, FTAG, FISEG, FIOFF, FOSEG, FOOFF, FOP,
18 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
19 MXCSR
20 };
21
22 static
23 void*
24 ctx_to_reg(CONTEXT* ctx, enum reg_name name, unsigned short* size)
25 {
26 /* For general registers: 32bits */
27 *size = 4;
28 switch (name)
29 {
30 case EAX: return &ctx->Eax;
31 case EBX: return &ctx->Ebx;
32 case ECX: return &ctx->Ecx;
33 case EDX: return &ctx->Edx;
34 case ESP: return &ctx->Esp;
35 case EBP: return &ctx->Ebp;
36 case ESI: return &ctx->Esi;
37 case EDI: return &ctx->Edi;
38 case EIP: return &ctx->Eip;
39 case EFLAGS: return &ctx->EFlags;
40 case CS: return &ctx->SegCs;
41 case DS: return &ctx->SegDs;
42 case ES: return &ctx->SegEs;
43 case FS: return &ctx->SegFs;
44 case GS: return &ctx->SegGs;
45 case SS: return &ctx->SegSs;
46 /* 80 bits */
47 case ST0:
48 case ST1:
49 case ST2:
50 case ST3:
51 case ST4:
52 case ST5:
53 case ST6:
54 case ST7:
55 *size = 10;
56 return &ctx->FloatSave.RegisterArea[10 * (name - ST0)];
57 /* X87 registers */
58 case FCTRL: return &ctx->FloatSave.ControlWord;
59 case FSTAT: return &ctx->FloatSave.StatusWord;
60 case FTAG: return &ctx->FloatSave.TagWord;
61 case FISEG: return &ctx->FloatSave.DataSelector;
62 case FIOFF: return &ctx->FloatSave.DataOffset;
63 case FOSEG: return &ctx->FloatSave.ErrorSelector;
64 case FOOFF: return &ctx->FloatSave.ErrorOffset;
65 case FOP: return &ctx->FloatSave.Cr0NpxState;
66 /* SSE */
67 case XMM0:
68 case XMM1:
69 case XMM2:
70 case XMM3:
71 case XMM4:
72 case XMM5:
73 case XMM6:
74 case XMM7:
75 *size = 16;
76 return &ctx->ExtendedRegisters[160 + (name - XMM0)*16];
77 case MXCSR: return &ctx->ExtendedRegisters[24];
78 }
79 return 0;
80 }
81
82 KDSTATUS
83 gdb_send_registers(
84 _Out_ DBGKD_MANIPULATE_STATE64* State,
85 _Out_ PSTRING MessageData,
86 _Out_ PULONG MessageLength,
87 _Inout_ PKD_CONTEXT KdContext)
88 {
89 ULONG32 Registers[16];
90 unsigned i;
91 unsigned short size;
92
93 for(i=0; i < 16; i++)
94 {
95 Registers[i] = *(ULONG32*)ctx_to_reg(&CurrentContext, i, &size);
96 }
97 send_gdb_memory(Registers, sizeof(Registers));
98 return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
99 }
100
101 KDSTATUS
102 gdb_send_register(
103 _Out_ DBGKD_MANIPULATE_STATE64* State,
104 _Out_ PSTRING MessageData,
105 _Out_ PULONG MessageLength,
106 _Inout_ PKD_CONTEXT KdContext)
107 {
108 enum reg_name reg_name;
109 void *ptr;
110 unsigned short size;
111
112 /* Get the GDB register name (gdb_input = "pXX") */
113 reg_name = (hex_value(gdb_input[1]) << 4) | hex_value(gdb_input[2]);
114
115 ptr = ctx_to_reg(&CurrentContext, reg_name, &size);
116 if (!ptr)
117 {
118 /* Undefined. Let's assume 32 bit register */
119 send_gdb_packet("xxxxxxxx");
120 }
121 else
122 {
123 send_gdb_memory(ptr, size);
124 }
125 return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
126 }