]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbCmdBreakpoint.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / EbcDebugger / EdbCmdBreakpoint.c
1 /** @file
2
3 Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
5
6
7 **/
8
9 #include "Edb.h"
10
11 /**
12
13 Check whether current IP is EBC BREAK3 instruction.
14
15 @param Address EBC IP address.
16
17 @retval TRUE Current IP is EBC BREAK3 instruction
18 @retval FALSE Current IP is not EBC BREAK3 instruction
19
20 **/
21 BOOLEAN
22 IsEBCBREAK3 (
23 IN UINTN Address
24 )
25 {
26 if (GET_OPCODE(Address) != OPCODE_BREAK) {
27 return FALSE;
28 }
29
30 if (GET_OPERANDS (Address) != 3) {
31 return FALSE;
32 } else {
33 return TRUE;
34 }
35 }
36
37 /**
38
39 Check whether the Address is already set in breakpoint.
40
41 @param DebuggerPrivate EBC Debugger private data structure
42 @param Address Breakpoint Address
43
44 @retval TRUE breakpoint is found
45 @retval FALSE breakpoint is not found
46
47 **/
48 BOOLEAN
49 DebuggerBreakpointIsDuplicated (
50 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
51 IN UINTN Address
52 )
53 {
54 UINTN Index;
55
56 //
57 // Go through each breakpoint context
58 //
59 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {
60 if (DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress == Address) {
61 //
62 // Found it
63 //
64 return TRUE;
65 }
66 }
67
68 //
69 // Not found
70 //
71 return FALSE;
72 }
73
74 /**
75
76 Add this breakpoint.
77
78 @param DebuggerPrivate EBC Debugger private data structure
79 @param Address Breakpoint Address
80
81 @retval EFI_SUCCESS breakpoint added successfully
82 @retval EFI_ALREADY_STARTED breakpoint is already added
83 @retval EFI_OUT_OF_RESOURCES all the breakpoint entries are used
84
85 **/
86 EFI_STATUS
87 DebuggerBreakpointAdd (
88 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
89 IN UINTN Address
90 )
91 {
92 //
93 // Check duplicated breakpoint
94 //
95 if (DebuggerBreakpointIsDuplicated (DebuggerPrivate, Address)) {
96 EDBPrint (L"Breakpoint duplicated!\n");
97 return EFI_ALREADY_STARTED;
98 }
99
100 //
101 // Check whether the address is a breakpoint 3 instruction
102 //
103 if (IsEBCBREAK3 (Address)) {
104 EDBPrint (L"Breakpoint can not be set on BREAK 3 instruction!\n");
105 return EFI_ALREADY_STARTED;
106 }
107
108 if (DebuggerPrivate->DebuggerBreakpointCount >= EFI_DEBUGGER_BREAKPOINT_MAX) {
109 EDBPrint (L"Breakpoint out of resource!\n");
110 return EFI_OUT_OF_RESOURCES;
111 }
112
113 //
114 // Set the breakpoint
115 //
116 DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].BreakpointAddress = Address;
117 DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].State = TRUE;
118 DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].OldInstruction = 0;
119 CopyMem (
120 &DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].OldInstruction,
121 (VOID *)Address,
122 sizeof(UINT16)
123 );
124
125 DebuggerPrivate->DebuggerBreakpointCount ++;
126
127 //
128 // Done
129 //
130 return EFI_SUCCESS;
131 }
132
133 /**
134
135 Delete this breakpoint.
136
137 @param DebuggerPrivate EBC Debugger private data structure
138 @param Index Breakpoint Index
139
140 @retval EFI_SUCCESS breakpoint deleted successfully
141 @retval EFI_NOT_FOUND breakpoint not found
142
143 **/
144 EFI_STATUS
145 DebuggerBreakpointDel (
146 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
147 IN UINTN Index
148 )
149 {
150 UINTN BpIndex;
151
152 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||
153 (Index >= DebuggerPrivate->DebuggerBreakpointCount)) {
154 return EFI_NOT_FOUND;
155 }
156
157 //
158 // Delete this breakpoint
159 //
160 for (BpIndex = Index; BpIndex < DebuggerPrivate->DebuggerBreakpointCount - 1; BpIndex++) {
161 DebuggerPrivate->DebuggerBreakpointContext[BpIndex] = DebuggerPrivate->DebuggerBreakpointContext[BpIndex + 1];
162 }
163 ZeroMem (
164 &DebuggerPrivate->DebuggerBreakpointContext[BpIndex],
165 sizeof(DebuggerPrivate->DebuggerBreakpointContext[BpIndex])
166 );
167
168 DebuggerPrivate->DebuggerBreakpointCount --;
169
170 //
171 // Done
172 //
173 return EFI_SUCCESS;
174 }
175
176 /**
177
178 Disable this breakpoint.
179
180 @param DebuggerPrivate EBC Debugger private data structure
181 @param Index Breakpoint Index
182
183 @retval EFI_SUCCESS breakpoint disabled successfully
184 @retval EFI_NOT_FOUND breakpoint not found
185
186 **/
187 EFI_STATUS
188 DebuggerBreakpointDis (
189 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
190 IN UINTN Index
191 )
192 {
193 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||
194 (Index >= DebuggerPrivate->DebuggerBreakpointCount)) {
195 return EFI_NOT_FOUND;
196 }
197
198 //
199 // Disable this breakpoint
200 //
201 DebuggerPrivate->DebuggerBreakpointContext[Index].State = FALSE;
202
203 return EFI_SUCCESS;
204 }
205
206 /**
207
208 Enable this breakpoint.
209
210 @param DebuggerPrivate - EBC Debugger private data structure
211 @param Index - Breakpoint Index
212
213 @retval EFI_SUCCESS - breakpoint enabled successfully
214 @retval EFI_NOT_FOUND - breakpoint not found
215
216 **/
217 EFI_STATUS
218 DebuggerBreakpointEn (
219 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
220 IN UINTN Index
221 )
222 {
223 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||
224 (Index >= DebuggerPrivate->DebuggerBreakpointCount)) {
225 return EFI_NOT_FOUND;
226 }
227
228 //
229 // Enable this breakpoint
230 //
231 DebuggerPrivate->DebuggerBreakpointContext[Index].State = TRUE;
232
233 return EFI_SUCCESS;
234 }
235
236 /**
237
238 DebuggerCommand - BreakpointList.
239
240 @param CommandArg - The argument for this command
241 @param DebuggerPrivate - EBC Debugger private data structure
242 @param ExceptionType - Exception type.
243 @param SystemContext - EBC system context.
244
245 @retval EFI_DEBUG_CONTINUE - formal return value
246
247 **/
248 EFI_DEBUG_STATUS
249 DebuggerBreakpointList (
250 IN CHAR16 *CommandArg,
251 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
252 IN EFI_EXCEPTION_TYPE ExceptionType,
253 IN OUT EFI_SYSTEM_CONTEXT SystemContext
254 )
255 {
256 UINTN Index;
257
258 //
259 // Check breakpoint cound
260 //
261 if (DebuggerPrivate->DebuggerBreakpointCount == 0) {
262 EDBPrint (L"No Breakpoint\n");
263 return EFI_DEBUG_CONTINUE;
264 } else if (DebuggerPrivate->DebuggerBreakpointCount > EFI_DEBUGGER_BREAKPOINT_MAX) {
265 EDBPrint (L"Breakpoint too many!\n");
266 DebuggerPrivate->DebuggerBreakpointCount = 0;
267 return EFI_DEBUG_CONTINUE;
268 }
269
270 //
271 // Go through each breakpoint
272 //
273 EDBPrint (L"Breakpoint :\n");
274 EDBPrint (L" Index Address Status\n");
275 EDBPrint (L"======= ================== ========\n");
276 //EDBPrint (L" 1 0xFFFFFFFF00000000 *\n");
277 //EDBPrint (L" 12 0x00000000FFFFFFFF\n");
278 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {
279 //
280 // Print the breakpoint
281 //
282 EDBPrint (L" %2d 0x%016lx", Index, DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress);
283 if (DebuggerPrivate->DebuggerBreakpointContext[Index].State) {
284 EDBPrint (L" *\n");
285 } else {
286 EDBPrint (L"\n");
287 }
288 }
289
290 //
291 // Done
292 //
293 return EFI_DEBUG_CONTINUE;
294 }
295
296 /**
297
298 DebuggerCommand - BreakpointSet.
299
300 @param CommandArg The argument for this command
301 @param DebuggerPrivate EBC Debugger private data structure
302 @param ExceptionType Exception type.
303 @param SystemContext EBC system context.
304
305 @retval EFI_DEBUG_CONTINUE - formal return value
306
307 **/
308 EFI_DEBUG_STATUS
309 DebuggerBreakpointSet (
310 IN CHAR16 *CommandArg,
311 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
312 IN EFI_EXCEPTION_TYPE ExceptionType,
313 IN OUT EFI_SYSTEM_CONTEXT SystemContext
314 )
315 {
316 UINTN Address;
317 EFI_STATUS Status;
318
319 if (CommandArg == NULL) {
320 EDBPrint (L"BreakpointSet Argument error!\n");
321 return EFI_DEBUG_CONTINUE;
322 }
323
324 //
325 // Get breakpoint address
326 //
327 Status = Symboltoi (CommandArg, &Address);
328 if (EFI_ERROR (Status)) {
329 if (Status == EFI_NOT_FOUND) {
330 Address = Xtoi(CommandArg);
331 } else {
332 //
333 // Something wrong, let Symboltoi print error info.
334 //
335 EDBPrint (L"Command Argument error!\n");
336 return EFI_DEBUG_CONTINUE;
337 }
338 }
339
340 //
341 // Add breakpoint
342 //
343 Status = DebuggerBreakpointAdd (DebuggerPrivate, Address);
344 if (EFI_ERROR(Status)) {
345 EDBPrint (L"BreakpointSet error!\n");
346 }
347
348 //
349 // Done
350 //
351 return EFI_DEBUG_CONTINUE;
352 }
353
354 /**
355
356 DebuggerCommand - BreakpointClear
357
358 @param CommandArg The argument for this command
359 @param DebuggerPrivate EBC Debugger private data structure
360 @param ExceptionType Exception type.
361 @param SystemContext EBC system context.
362
363 @retval EFI_DEBUG_CONTINUE formal return value
364
365 **/
366 EFI_DEBUG_STATUS
367 DebuggerBreakpointClear (
368 IN CHAR16 *CommandArg,
369 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
370 IN EFI_EXCEPTION_TYPE ExceptionType,
371 IN OUT EFI_SYSTEM_CONTEXT SystemContext
372 )
373 {
374 UINTN Index;
375 EFI_STATUS Status;
376
377 if (CommandArg == NULL) {
378 EDBPrint (L"BreakpointClear Argument error!\n");
379 return EFI_DEBUG_CONTINUE;
380 }
381
382 if (StriCmp (CommandArg, L"*") == 0) {
383 //
384 // delete all breakpoint
385 //
386 DebuggerPrivate->DebuggerBreakpointCount = 0;
387 ZeroMem (DebuggerPrivate->DebuggerBreakpointContext, sizeof(DebuggerPrivate->DebuggerBreakpointContext));
388 EDBPrint (L"All the Breakpoint is cleared\n");
389 return EFI_DEBUG_CONTINUE;
390 }
391
392 //
393 // Get breakpoint index
394 //
395 Index = Atoi(CommandArg);
396 if (Index == (UINTN) -1) {
397 EDBPrint (L"BreakpointClear Argument error!\n");
398 return EFI_DEBUG_CONTINUE;
399 }
400
401 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||
402 (Index >= DebuggerPrivate->DebuggerBreakpointCount)) {
403 EDBPrint (L"BreakpointClear error!\n");
404 return EFI_DEBUG_CONTINUE;
405 }
406
407 //
408 // Delete breakpoint
409 //
410 Status = DebuggerBreakpointDel (DebuggerPrivate, Index);
411 if (EFI_ERROR(Status)) {
412 EDBPrint (L"BreakpointClear error!\n");
413 }
414
415 //
416 // Done
417 //
418 return EFI_DEBUG_CONTINUE;
419 }
420
421 /**
422
423 DebuggerCommand - BreakpointDisable
424
425 @param CommandArg The argument for this command
426 @param DebuggerPrivate EBC Debugger private data structure
427 @param ExceptionType Exception type.
428 @param SystemContext EBC system context.
429
430 @retval EFI_DEBUG_CONTINUE formal return value
431
432 **/
433 EFI_DEBUG_STATUS
434 DebuggerBreakpointDisable (
435 IN CHAR16 *CommandArg,
436 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
437 IN EFI_EXCEPTION_TYPE ExceptionType,
438 IN OUT EFI_SYSTEM_CONTEXT SystemContext
439 )
440 {
441 UINTN Index;
442 EFI_STATUS Status;
443
444 if (CommandArg == NULL) {
445 EDBPrint (L"BreakpointDisable Argument error!\n");
446 return EFI_DEBUG_CONTINUE;
447 }
448
449 if (StriCmp (CommandArg, L"*") == 0) {
450 //
451 // disable all breakpoint
452 //
453 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {
454 Status = DebuggerBreakpointDis (DebuggerPrivate, Index);
455 }
456 EDBPrint (L"All the Breakpoint is disabled\n");
457 return EFI_DEBUG_CONTINUE;
458 }
459
460 //
461 // Get breakpoint index
462 //
463 Index = Atoi(CommandArg);
464 if (Index == (UINTN) -1) {
465 EDBPrint (L"BreakpointDisable Argument error!\n");
466 return EFI_DEBUG_CONTINUE;
467 }
468
469 //
470 // Disable breakpoint
471 //
472 Status = DebuggerBreakpointDis (DebuggerPrivate, Index);
473 if (EFI_ERROR(Status)) {
474 EDBPrint (L"BreakpointDisable error!\n");
475 }
476
477 //
478 // Done
479 //
480 return EFI_DEBUG_CONTINUE;
481 }
482
483 /**
484 DebuggerCommand - BreakpointEnable.
485
486 @param CommandArg The argument for this command
487 @param DebuggerPrivate EBC Debugger private data structure
488 @param ExceptionType Exception type.
489 @param SystemContext EBC system context.
490
491 @retval EFI_DEBUG_CONTINUE formal return value
492
493 **/
494 EFI_DEBUG_STATUS
495 DebuggerBreakpointEnable (
496 IN CHAR16 *CommandArg,
497 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
498 IN EFI_EXCEPTION_TYPE ExceptionType,
499 IN OUT EFI_SYSTEM_CONTEXT SystemContext
500 )
501 {
502 UINTN Index;
503 EFI_STATUS Status;
504
505 if (CommandArg == NULL) {
506 EDBPrint (L"BreakpointEnable Argument error!\n");
507 return EFI_DEBUG_CONTINUE;
508 }
509
510 if (StriCmp (CommandArg, L"*") == 0) {
511 //
512 // enable all breakpoint
513 //
514 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {
515 Status = DebuggerBreakpointEn (DebuggerPrivate, Index);
516 }
517 EDBPrint (L"All the Breakpoint is enabled\n");
518 return EFI_DEBUG_CONTINUE;
519 }
520
521 //
522 // Get breakpoint index
523 //
524 Index = Atoi(CommandArg);
525 if (Index == (UINTN) -1) {
526 EDBPrint (L"BreakpointEnable Argument error!\n");
527 return EFI_DEBUG_CONTINUE;
528 }
529
530 //
531 // Enable breakpoint
532 //
533 Status = DebuggerBreakpointEn (DebuggerPrivate, Index);
534 if (EFI_ERROR(Status)) {
535 EDBPrint (L"BreakpointEnable error!\n");
536 }
537
538 //
539 // Done
540 //
541 return EFI_DEBUG_CONTINUE;
542 }