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