-
Notifications
You must be signed in to change notification settings - Fork 550
/
DebuggerAsm.cs
272 lines (240 loc) · 8.96 KB
/
DebuggerAsm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
using IL2CPU.API;
using IL2CPU.API.Attribs;
using Cosmos.Debug.Kernel;
using XSharp;
using XSharp.Assembler;
namespace Cosmos.Debug.Kernel.Plugs.Asm
{
[Plug(Target = typeof(Debugger))]
public static class DebuggerAsm
{
[PlugMethod(Assembler = typeof(DebugBreak))]
public static void Break(Debugger aThis) { }
[PlugMethod(Assembler = typeof(DebugDoSend))]
public static void DoSend(string aText) { }
[PlugMethod(Assembler = typeof(DebugDoSendNumber))]
public static void DoSendNumber(int aNumber) { }
[PlugMethod(Assembler = typeof(DebugDoSendNumber))]
public static void DoSendNumber(uint aNumber) { }
[PlugMethod(Assembler = typeof(DebugDoSendLongNumber))]
public static void DoSendNumber(long aNumber) { }
[PlugMethod(Assembler = typeof(DebugDoSendLongNumber))]
public static void DoSendNumber(ulong aNumber) { }
[PlugMethod(Assembler = typeof(DebugDoSendComplexNumber))]
public static void DoSendNumber(float aNumber) { }
[PlugMethod(Assembler = typeof(DebugDoSendComplexLongNumber))]
public static void DoSendNumber(double aNumber) { }
[PlugMethod(Assembler = typeof(DebugSendMessageBox))]
public static unsafe void SendMessageBox(Debugger aThis, int aLength, char* aText) { }
[PlugMethod(Assembler = typeof(DebugSendPtr))]
public static unsafe void SendPtr(Debugger aThis, object aPtr) { }
[PlugMethod(Assembler = typeof(DebugSendChannelCommand))]
public static unsafe void SendChannelCommand(byte aChannel, byte aCommand, int aByteCount, byte* aData) { }
[PlugMethod(Assembler = typeof(DebugSendChannelCommandNoData))]
public static unsafe void SendChannelCommand(byte aChannel, byte aCommand) { }
[PlugMethod(Assembler = typeof(DoBochsBreak))]
public static void DoBochsBreak() { }
[Inline]
public static void SendKernelPanic(uint id)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("push dword [EBP + 8]");
new LiteralAssemblerCode("xchg bx, bx");
new LiteralAssemblerCode("Call DebugStub_SendKernelPanic");
new LiteralAssemblerCode("add ESP, 4");
new LiteralAssemblerCode("%endif");
}
[PlugMethod(Assembler = typeof(DoRealHalt))]
public static void DoRealHalt() { }
//[PlugMethod(Assembler = typeof(DebugTraceOff))]
//public static void TraceOff() { }
//[PlugMethod(Assembler = typeof(DebugTraceOn))]
//public static void TraceOn() { }
}
//TODO: Make a new plug attrib that assembly plug methods dont need
// an empty stub also, its just extra fluff - although they allow signature matching
// Maybe could merge this into the same unit as the plug
public class DebugTraceOff : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("pushad");
new LiteralAssemblerCode("Call DebugStub_TraceOff");
new LiteralAssemblerCode("popad");
new LiteralAssemblerCode("%endif");
}
}
public class DebugTraceOn : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("pushad");
new LiteralAssemblerCode("Call DebugStub_TraceOn");
new LiteralAssemblerCode("popad");
new LiteralAssemblerCode("%endif");
}
}
/// <summary>
/// Assembler for SendChannelCommand
/// </summary>
/// <remarks>
/// AL contains channel
/// BL contains command
/// ECX contains number of bytes to send as command data
/// ESI contains data start pointer
/// </remarks>
public class DebugSendChannelCommand : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("mov AL, [EBP + 20]");
new LiteralAssemblerCode("mov BL, [EBP + 16]");
new LiteralAssemblerCode("mov ECX, [EBP + 12]");
new LiteralAssemblerCode("mov ESI, [EBP + 8]");
new LiteralAssemblerCode("call DebugStub_SendCommandOnChannel");
new LiteralAssemblerCode("%endif");
}
}
/// <summary>
/// Assembler for SendChannelCommandNoData
/// </summary>
/// <remarks>
/// AL contains channel
/// BL contains command
/// ECX contains number of bytes to send as command data
/// ESI contains data start pointer
/// </remarks>
public class DebugSendChannelCommandNoData : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("mov AL, [EBP + 12]");
new LiteralAssemblerCode("mov BL, [EBP + 8]");
new LiteralAssemblerCode("mov ECX, 0");
new LiteralAssemblerCode("mov ESI, EBP");
new LiteralAssemblerCode("call DebugStub_SendCommandOnChannel");
new LiteralAssemblerCode("%endif");
}
}
public class DebugBreak : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("mov dword [DebugStub_DebugBreakOnNextTrace], 1");
new LiteralAssemblerCode("%endif");
}
}
/// <summary>
/// Assembler for DoSend
/// </summary>
/// <remarks>
/// EBP + 12 contains length
/// EBP + 8 contains first char pointer
/// </remarks>
public class DebugDoSend : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
XS.Label(".BeforeArgumentsPrepare");
new LiteralAssemblerCode("mov EBX, [EBP + 12]");
new LiteralAssemblerCode("push dword [EBX + 12]");
new LiteralAssemblerCode("add EBX, 16");
new LiteralAssemblerCode("push dword EBX");
XS.Label(".BeforeCall");
new LiteralAssemblerCode("Call DebugStub_SendText");
new LiteralAssemblerCode("add ESP, 8");
new LiteralAssemblerCode("%endif");
}
}
public class DebugDoSendNumber : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("push dword [EBP + 8]");
new LiteralAssemblerCode("Call DebugStub_SendSimpleNumber");
new LiteralAssemblerCode("add ESP, 4");
new LiteralAssemblerCode("%endif");
}
}
public class DebugDoSendLongNumber : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("push dword [EBP + 12]");
new LiteralAssemblerCode("push dword [EBP + 8]");
new LiteralAssemblerCode("Call DebugStub_SendSimpleLongNumber");
new LiteralAssemblerCode("add ESP, 8");
new LiteralAssemblerCode("%endif");
}
}
public class DebugDoSendComplexNumber : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("push dword [EBP + 8]");
new LiteralAssemblerCode("Call DebugStub_SendComplexNumber");
new LiteralAssemblerCode("add ESP, 4");
new LiteralAssemblerCode("%endif");
}
}
public class DebugDoSendComplexLongNumber : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("push dword [EBP + 12]");
new LiteralAssemblerCode("push dword [EBP + 8]");
new LiteralAssemblerCode("Call DebugStub_SendComplexLongNumber");
new LiteralAssemblerCode("add ESP, 8");
new LiteralAssemblerCode("%endif");
}
}
public class DebugSendMessageBox : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("pushad");
new LiteralAssemblerCode("Call DebugStub_SendMessageBox");
new LiteralAssemblerCode("popad");
new LiteralAssemblerCode("%endif");
}
}
public class DebugSendPtr : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("pushad");
new LiteralAssemblerCode("Call DebugStub_SendPtr");
new LiteralAssemblerCode("popad");
new LiteralAssemblerCode("%endif");
}
}
public class DoBochsBreak : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
XS.Exchange(XSRegisters.BX, XSRegisters.BX);
}
}
public class DoRealHalt : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
XS.DisableInterrupts();
// bochs magic break
//Exchange(BX, BX);
XS.Halt();
}
}
}