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   Get file name from full path.
20 
21   @param  FullPath        - full file path
22 
23   @return  file name
24 
25 **/
26 CHAR16 *
GetFileNameFromFullPath(IN CHAR16 * FullPath)27 GetFileNameFromFullPath (
28   IN CHAR16   *FullPath
29   )
30 {
31   CHAR16   *FileName;
32   CHAR16   *TempFileName;
33 
34   FileName = FullPath;
35   TempFileName = StrGetNewTokenLine (FullPath, L"\\");
36 
37   while (TempFileName != NULL) {
38     FileName = TempFileName;
39     TempFileName = StrGetNextTokenLine (L"\\");
40     PatchForStrTokenBefore (TempFileName, L'\\');
41   }
42 
43   return FileName;
44 }
45 
46 /**
47 
48   Get dir name from full path.
49 
50   @param  FullPath        - full file path
51 
52   @return dir name
53 
54 **/
55 CHAR16 *
GetDirNameFromFullPath(IN CHAR16 * FullPath)56 GetDirNameFromFullPath (
57   IN CHAR16   *FullPath
58   )
59 {
60   CHAR16   *FileName;
61 
62   FileName = GetFileNameFromFullPath (FullPath);
63   if (FileName != FullPath) {
64     *(FileName - 1) = 0;
65     return FullPath;
66   }
67 
68   return L"";
69 }
70 
71 /**
72 
73   Construct full path accroding to dir and file path.
74 
75   @param  DirPath         - dir path
76   @param  FilePath        - file path
77   @param  Size            - dir max size
78 
79   @return Full file name
80 
81 **/
82 CHAR16 *
ConstructFullPath(IN CHAR16 * DirPath,IN CHAR16 * FilePath,IN UINTN Size)83 ConstructFullPath (
84   IN CHAR16   *DirPath,
85   IN CHAR16   *FilePath,
86   IN UINTN    Size
87   )
88 {
89   UINTN DirPathSize;
90 
91   DirPathSize = StrLen(DirPath);
92   *(DirPath + DirPathSize) = L'\\';
93   StrnCatS (DirPath, DirPathSize + Size + 1, FilePath, Size);
94 
95   *(DirPath + DirPathSize + Size + 1) = 0;
96 
97   return DirPath;
98 }
99 
100 CHAR16 *mSymbolTypeStr[] = {
101   L"( F)",
102   L"(SF)",
103   L"(GV)",
104   L"(SV)",
105 };
106 
107 /**
108 
109   Comvert Symbol Type to string.
110 
111   @param  Type            - Symbol Type
112 
113   @return String
114 
115 **/
116 CHAR16 *
EdbSymbolTypeToStr(IN EFI_DEBUGGER_SYMBOL_TYPE Type)117 EdbSymbolTypeToStr (
118   IN EFI_DEBUGGER_SYMBOL_TYPE  Type
119   )
120 {
121   if (Type < 0 || Type >= EfiDebuggerSymbolTypeMax) {
122     return L"(?)";
123   }
124 
125   return mSymbolTypeStr [Type];
126 }
127 
128 /**
129 
130   Find the symbol accroding to address and display symbol.
131 
132   @param  Address         - SymbolAddress
133   @param  DebuggerPrivate - EBC Debugger private data structure
134 
135   @retval EFI_DEBUG_CONTINUE - formal return value
136 
137 **/
138 EFI_DEBUG_STATUS
DebuggerDisplaySymbolAccrodingToAddress(IN UINTN Address,IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate)139 DebuggerDisplaySymbolAccrodingToAddress (
140   IN     UINTN                      Address,
141   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate
142   )
143 {
144   EFI_DEBUGGER_SYMBOL_OBJECT *Object;
145   EFI_DEBUGGER_SYMBOL_ENTRY  *Entry;
146   UINTN                      CandidateAddress;
147 
148   //
149   // Find the nearest symbol address
150   //
151   CandidateAddress = EbdFindSymbolAddress (Address, EdbMatchSymbolTypeNearestAddress, &Object, &Entry);
152   if (CandidateAddress == 0 || CandidateAddress == (UINTN) -1) {
153     EDBPrint (L"Symbole at Address not found!\n");
154     return EFI_DEBUG_CONTINUE;
155   } else if (Address != CandidateAddress) {
156     EDBPrint (L"Symbole at Address not found, print nearest one!\n");
157   }
158 
159   //
160   // Display symbol
161   //
162   EDBPrint (L"Symbol File Name: %s\n", Object->Name);
163   if (sizeof(UINTN) == sizeof(UINT64)) {
164     EDBPrint (L"        Address      Type  Symbol\n");
165     EDBPrint (L"  ================== ==== ========\n");
166 //  EDBPrint (L"  0xFFFFFFFF00000000 ( F) TestMain\n");
167     EDBPrint (
168       L"  0x%016lx %s %a\n",
169       (UINT64)Entry->Rva + Object->BaseAddress,
170       EdbSymbolTypeToStr (Entry->Type),
171       Entry->Name
172       );
173   } else {
174     EDBPrint (L"   Address   Type  Symbol\n");
175     EDBPrint (L"  ========== ==== ========\n");
176 //  EDBPrint (L"  0xFFFF0000 ( F) TestMain\n");
177     EDBPrint (
178       L"  0x%08x %s %a\n",
179       Entry->Rva + Object->BaseAddress,
180       EdbSymbolTypeToStr (Entry->Type),
181       Entry->Name
182       );
183   }
184 
185   //
186   // Done
187   //
188   return EFI_DEBUG_CONTINUE;
189 }
190 
191 /**
192 
193   Find the symbol accroding to name and display symbol.
194 
195   @param  SymbolFileName  - The Symbol File Name, NULL means for all
196   @param  SymbolName      - The Symbol Name, NULL means for all
197   @param  DebuggerPrivate - EBC Debugger private data structure
198 
199   @retval EFI_DEBUG_CONTINUE - formal return value
200 
201 **/
202 EFI_DEBUG_STATUS
DebuggerDisplaySymbolAccrodingToName(IN CHAR16 * SymbolFileName,IN CHAR16 * SymbolName,IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate)203 DebuggerDisplaySymbolAccrodingToName (
204   IN     CHAR16                     *SymbolFileName,
205   IN     CHAR16                     *SymbolName,
206   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate
207   )
208 {
209   UINTN                      Index;
210   UINTN                      SubIndex;
211   EFI_DEBUGGER_SYMBOL_OBJECT *Object;
212   EFI_DEBUGGER_SYMBOL_ENTRY  *Entry;
213 
214   if (DebuggerPrivate->DebuggerSymbolContext.ObjectCount == 0) {
215     EDBPrint (L"No Symbol File!\n");
216     return EFI_DEBUG_CONTINUE;
217   }
218 
219   //
220   // Go throuth each symbol file
221   //
222   Object = DebuggerPrivate->DebuggerSymbolContext.Object;
223   for (Index = 0; Index < DebuggerPrivate->DebuggerSymbolContext.ObjectCount; Index++, Object++) {
224     if ((SymbolFileName != NULL) &&
225         (StriCmp (SymbolFileName, Object->Name) != 0)) {
226       continue;
227     }
228 
229     //
230     // Break each symbol file
231     //
232     if (Index != 0) {
233       if (SetPageBreak ()) {
234         break;
235       }
236     }
237 
238     EDBPrint (L"Symbol File Name: %s\n", Object->Name);
239     if (Object->EntryCount == 0) {
240       EDBPrint (L"No Symbol!\n");
241       continue;
242     }
243     Entry = Object->Entry;
244     if (sizeof(UINTN) == sizeof(UINT64)) {
245       EDBPrint (L"        Address      Type  Symbol\n");
246       EDBPrint (L"  ================== ==== ========\n");
247 //    EDBPrint (L"  0xFFFFFFFF00000000 ( F) TestMain (EbcTest.obj)\n");
248     } else {
249       EDBPrint (L"   Address   Type  Symbol\n");
250       EDBPrint (L"  ========== ==== ========\n");
251 //    EDBPrint (L"  0xFFFF0000 ( F) TestMain (EbcTest.obj)\n");
252     }
253 
254     //
255     // Go through each symbol name
256     //
257     for (SubIndex = 0; SubIndex < Object->EntryCount; SubIndex++, Entry++) {
258       if ((SymbolName != NULL) &&
259           (StrCmpUnicodeAndAscii (SymbolName, Entry->Name) != 0)) {
260         continue;
261       }
262 
263       //
264       // Break symbol
265       //
266       if (((SubIndex % EFI_DEBUGGER_LINE_NUMBER_IN_PAGE) == 0) &&
267           (SubIndex != 0)) {
268         if (SetPageBreak ()) {
269           break;
270         }
271       }
272 
273       if (sizeof(UINTN) == sizeof(UINT64)) {
274         EDBPrint (
275           L"  0x%016lx %s %a (%a)\n",
276           (UINT64)Entry->Rva + Object->BaseAddress,
277           EdbSymbolTypeToStr (Entry->Type),
278           Entry->Name,
279           Entry->ObjName
280           );
281       } else {
282         EDBPrint (
283           L"  0x%08x %s %a (%a)\n",
284           Entry->Rva + Object->BaseAddress,
285           EdbSymbolTypeToStr (Entry->Type),
286           Entry->Name,
287           Entry->ObjName
288           );
289       }
290     }
291   }
292 
293   //
294   // Done
295   //
296   return EFI_DEBUG_CONTINUE;
297 }
298 
299 /**
300 
301   DebuggerCommand - ListSymbol.
302 
303   @param  CommandArg      - The argument for this command
304   @param  DebuggerPrivate - EBC Debugger private data structure
305   @param  ExceptionType   - Exception type.
306   @param  SystemContext   - EBC system context.
307 
308   @retval EFI_DEBUG_CONTINUE - formal return value
309 
310 **/
311 EFI_DEBUG_STATUS
DebuggerListSymbol(IN CHAR16 * CommandArg,IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate,IN EFI_EXCEPTION_TYPE ExceptionType,IN OUT EFI_SYSTEM_CONTEXT SystemContext)312 DebuggerListSymbol (
313   IN     CHAR16                    *CommandArg,
314   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
315   IN     EFI_EXCEPTION_TYPE        ExceptionType,
316   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
317   )
318 {
319   CHAR16                     *SymbolFileName;
320   CHAR16                     *SymbolName;
321   CHAR16                     *CommandStr;
322   UINTN                      Address;
323 
324   SymbolFileName = NULL;
325   SymbolName = NULL;
326   CommandStr = CommandArg;
327 
328   //
329   // display symbol according to address
330   //
331   if (CommandStr != NULL) {
332     if ((StriCmp (CommandStr, L"F") != 0) &&
333         (StriCmp (CommandStr, L"S") != 0)) {
334       Address = Xtoi (CommandStr);
335       return DebuggerDisplaySymbolAccrodingToAddress (Address, DebuggerPrivate);
336     }
337   }
338 
339   //
340   // Get SymbolFileName
341   //
342   if (CommandStr != NULL) {
343     if (StriCmp (CommandStr, L"F") == 0) {
344       CommandStr = StrGetNextTokenLine (L" ");
345       if (CommandStr == NULL) {
346         EDBPrint (L"Symbol File Name missing!\n");
347         return EFI_DEBUG_CONTINUE;
348       } else {
349         SymbolFileName = CommandStr;
350         CommandStr = StrGetNextTokenLine (L" ");
351       }
352     }
353   }
354   //
355   // Get SymbolName
356   //
357   if (CommandStr != NULL) {
358     if (StriCmp (CommandStr, L"S") == 0) {
359       CommandStr = StrGetNextTokenLine (L" ");
360       if (CommandStr == NULL) {
361         EDBPrint (L"Symbol Name missing!\n");
362         return EFI_DEBUG_CONTINUE;
363       } else {
364         SymbolName = CommandStr;
365         CommandStr = StrGetNextTokenLine (L" ");
366       }
367     }
368   }
369   if (CommandStr != NULL) {
370     EDBPrint (L"Argument error!\n");
371     return EFI_DEBUG_CONTINUE;
372   }
373 
374   //
375   // display symbol according to name
376   //
377   return DebuggerDisplaySymbolAccrodingToName (SymbolFileName, SymbolName, DebuggerPrivate);
378 }
379 
380 /**
381 
382   DebuggerCommand - LoadSymbol.
383 
384   @param  CommandArg      - The argument for this command
385   @param  DebuggerPrivate - EBC Debugger private data structure
386   @param  ExceptionType   - Exception type.
387   @param  SystemContext   - EBC system context.
388 
389   @retval EFI_DEBUG_CONTINUE - formal return value
390 
391 **/
392 EFI_DEBUG_STATUS
DebuggerLoadSymbol(IN CHAR16 * CommandArg,IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate,IN EFI_EXCEPTION_TYPE ExceptionType,IN OUT EFI_SYSTEM_CONTEXT SystemContext)393 DebuggerLoadSymbol (
394   IN     CHAR16                    *CommandArg,
395   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
396   IN     EFI_EXCEPTION_TYPE        ExceptionType,
397   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
398   )
399 {
400   UINTN      BufferSize;
401   VOID       *Buffer;
402   EFI_STATUS Status;
403   CHAR16     *FileName;
404   CHAR16     *CommandArg2;
405   BOOLEAN    IsLoadCode;
406   CHAR16     *DirName;
407   CHAR16     CodFile[EFI_DEBUGGER_SYMBOL_NAME_MAX];
408   CHAR16     *CodFileName;
409   UINTN      Index;
410 
411   //
412   // Check the argument
413   //
414   if (CommandArg == NULL) {
415     EDBPrint (L"SymbolFile not found!\n");
416     return EFI_DEBUG_CONTINUE;
417   }
418   IsLoadCode = FALSE;
419   CommandArg2 = StrGetNextTokenLine (L" ");
420   if (CommandArg2 != NULL) {
421     if (StriCmp (CommandArg2, L"a") == 0) {
422       IsLoadCode = TRUE;
423     } else {
424       EDBPrint (L"Argument error!\n");
425       return EFI_DEBUG_CONTINUE;
426     }
427   }
428 
429   if (StrLen (CommandArg) <= 4) {
430     EDBPrint (L"SymbolFile name error!\n");
431     return EFI_DEBUG_CONTINUE;
432   }
433   if (StriCmp (CommandArg + (StrLen (CommandArg) - 4), L".map") != 0) {
434     EDBPrint (L"SymbolFile name error!\n");
435     return EFI_DEBUG_CONTINUE;
436   }
437 
438   //
439   // Read MAP file to memory
440   //
441   Status = ReadFileToBuffer (DebuggerPrivate, CommandArg, &BufferSize, &Buffer, TRUE);
442   if (EFI_ERROR(Status)) {
443     EDBPrint (L"SymbolFile read error!\n");
444     return EFI_DEBUG_CONTINUE;
445   }
446 
447   FileName = GetFileNameFromFullPath (CommandArg);
448   //
449   // Load Symbol
450   //
451   Status = EdbLoadSymbol (DebuggerPrivate, FileName, BufferSize, Buffer);
452   if (EFI_ERROR(Status)) {
453     EDBPrint (L"LoadSymbol error!\n");
454     gBS->FreePool (Buffer);
455     return EFI_DEBUG_CONTINUE;
456   }
457   gBS->FreePool (Buffer);
458 
459   //
460   // Patch Symbol for RVA
461   //
462   Status = EdbPatchSymbolRVA (DebuggerPrivate, FileName, EdbEbcImageRvaSearchTypeLast);
463   if (EFI_ERROR(Status)) {
464     EDBPrint (L"PatchSymbol RVA  - %r! Using the RVA in symbol file.\n", Status);
465   } else {
466     DEBUG ((DEBUG_ERROR, "PatchSymbol RVA successfully!\n"));
467   }
468 
469   if (!IsLoadCode) {
470     return EFI_DEBUG_CONTINUE;
471   }
472 
473   //
474   // load each cod file
475   //
476   DirName = GetDirNameFromFullPath (CommandArg);
477   ZeroMem (CodFile, sizeof(CodFile));
478   if (StrCmp (DirName, L"") != 0) {
479     StrCpyS (CodFile, sizeof(CodFile), DirName);
480   } else {
481     DirName = L"\\";
482   }
483 
484   //
485   // Go throuth each file under this dir
486   //
487   Index = 0;
488   CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
489   while (CodFileName != NULL) {
490     ZeroMem (CodFile, sizeof(CodFile));
491     if (StrCmp (DirName, L"\\") != 0) {
492       StrCpyS (CodFile, sizeof(CodFile), DirName);
493     }
494 
495     //
496     // read cod file to memory
497     //
498     Status = ReadFileToBuffer (DebuggerPrivate, ConstructFullPath (CodFile, CodFileName, EFI_DEBUGGER_SYMBOL_NAME_MAX - StrLen (CodFile) - 2), &BufferSize, &Buffer, FALSE);
499     if (EFI_ERROR(Status)) {
500       EDBPrint (L"CodeFile read error!\n");
501       CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
502       continue;
503     }
504 
505     //
506     // Load Code
507     //
508     Status = EdbLoadCode (DebuggerPrivate, FileName, CodFileName, BufferSize, Buffer);
509     if (EFI_ERROR (Status)) {
510       EDBPrint (L"LoadCode error!\n");
511       gBS->FreePool (Buffer);
512       CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
513       continue;
514     }
515 
516     //
517     // Record the buffer
518     //
519     Status = EdbAddCodeBuffer (DebuggerPrivate, FileName, CodFileName, BufferSize, Buffer);
520     if (EFI_ERROR (Status)) {
521       EDBPrint (L"AddCodeBuffer error!\n");
522       gBS->FreePool (Buffer);
523       CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
524       continue;
525     }
526 
527     //
528     // Get next file
529     //
530     CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
531   }
532 
533   //
534   // Done
535   //
536   return EFI_DEBUG_CONTINUE;
537 }
538 
539 /**
540 
541   DebuggerCommand - UnloadSymbol
542 
543   @param  CommandArg      - The argument for this command
544   @param  DebuggerPrivate - EBC Debugger private data structure
545   @param  ExceptionType   - Exception type.
546   @param  SystemContext   - EBC system context.
547 
548   @retval EFI_DEBUG_CONTINUE - formal return value
549 
550 **/
551 EFI_DEBUG_STATUS
DebuggerUnloadSymbol(IN CHAR16 * CommandArg,IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate,IN EFI_EXCEPTION_TYPE ExceptionType,IN OUT EFI_SYSTEM_CONTEXT SystemContext)552 DebuggerUnloadSymbol (
553   IN     CHAR16                    *CommandArg,
554   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
555   IN     EFI_EXCEPTION_TYPE        ExceptionType,
556   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
557   )
558 {
559   EFI_STATUS Status;
560   CHAR16     *FileName;
561   CHAR16     *DirName;
562   CHAR16     CodFile[EFI_DEBUGGER_SYMBOL_NAME_MAX];
563   CHAR16     *CodFileName;
564   UINTN      Index;
565   VOID       *BufferPtr;
566 
567   //
568   // Check the argument
569   //
570   if (CommandArg == NULL) {
571     EDBPrint (L"SymbolFile not found!\n");
572     return EFI_DEBUG_CONTINUE;
573   }
574 
575   FileName = GetFileNameFromFullPath (CommandArg);
576 
577   //
578   // Unload Code
579   //
580   DirName = GetDirNameFromFullPath (CommandArg);
581   ZeroMem (CodFile, sizeof(CodFile));
582   if (StrCmp (DirName, L"") != 0) {
583     StrCpyS (CodFile, sizeof(CodFile), DirName);
584   } else {
585     DirName = L"\\";
586   }
587 
588   //
589   // Go through each file under this dir
590   //
591   Index = 0;
592   CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
593   while (CodFileName != NULL) {
594     ZeroMem (CodFile, sizeof(CodFile));
595     if (StrCmp (DirName, L"\\") != 0) {
596       StrCpyS (CodFile, sizeof(CodFile), DirName);
597     }
598 
599     //
600     // Unload Code
601     //
602     Status = EdbUnloadCode (DebuggerPrivate, FileName, CodFileName, &BufferPtr);
603     if (EFI_ERROR (Status)) {
604       EDBPrint (L"UnloadCode error!\n");
605       CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
606       continue;
607     }
608 
609     //
610     // Delete the code buffer
611     //
612     Status = EdbDeleteCodeBuffer (DebuggerPrivate, FileName, CodFileName, BufferPtr);
613     if (EFI_ERROR (Status)) {
614       EDBPrint (L"DeleteCodeBuffer error!\n");
615       CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
616       continue;
617     }
618 
619     //
620     // Get next file
621     //
622     CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
623   }
624 
625   //
626   // Unload Symbol
627   //
628   Status = EdbUnloadSymbol (DebuggerPrivate, FileName);
629   if (EFI_ERROR(Status)) {
630     EDBPrint (L"UnloadSymbol error!\n");
631   }
632 
633   //
634   // Done
635   //
636   return EFI_DEBUG_CONTINUE;
637 }
638 
639 /**
640 
641   DebuggerCommand - DisplaySymbol.
642 
643   @param  CommandArg      - The argument for this command
644   @param  DebuggerPrivate - EBC Debugger private data structure
645   @param  ExceptionType   - Exception type.
646   @param  SystemContext   - EBC system context.
647 
648   @retval EFI_DEBUG_CONTINUE - formal return value
649 
650 **/
651 EFI_DEBUG_STATUS
DebuggerDisplaySymbol(IN CHAR16 * CommandArg,IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate,IN EFI_EXCEPTION_TYPE ExceptionType,IN OUT EFI_SYSTEM_CONTEXT SystemContext)652 DebuggerDisplaySymbol (
653   IN     CHAR16                    *CommandArg,
654   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
655   IN     EFI_EXCEPTION_TYPE        ExceptionType,
656   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
657   )
658 {
659   if (CommandArg == NULL) {
660     DebuggerPrivate->DebuggerSymbolContext.DisplaySymbol = !DebuggerPrivate->DebuggerSymbolContext.DisplaySymbol;
661     EdbShowDisasm (DebuggerPrivate, SystemContext);
662   } else if (StriCmp (CommandArg, L"on") == 0) {
663     DebuggerPrivate->DebuggerSymbolContext.DisplaySymbol = TRUE;
664     EdbShowDisasm (DebuggerPrivate, SystemContext);
665   } else if (StriCmp (CommandArg, L"off") == 0) {
666     DebuggerPrivate->DebuggerSymbolContext.DisplaySymbol = FALSE;
667     EdbShowDisasm (DebuggerPrivate, SystemContext);
668   } else {
669     EDBPrint (L"DisplaySymbol - argument error\n");
670   }
671 
672   return EFI_DEBUG_CONTINUE;
673 }
674 
675 /**
676 
677   DebuggerCommand - LoadCode.
678 
679   @param  CommandArg      - The argument for this command
680   @param  DebuggerPrivate - EBC Debugger private data structure
681   @param  ExceptionType   - Exception type.
682   @param  SystemContext   - EBC system context.
683 
684   @retval EFI_DEBUG_CONTINUE - formal return value
685 
686 **/
687 EFI_DEBUG_STATUS
DebuggerLoadCode(IN CHAR16 * CommandArg,IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate,IN EFI_EXCEPTION_TYPE ExceptionType,IN OUT EFI_SYSTEM_CONTEXT SystemContext)688 DebuggerLoadCode (
689   IN     CHAR16                    *CommandArg,
690   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
691   IN     EFI_EXCEPTION_TYPE        ExceptionType,
692   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
693   )
694 {
695   UINTN      BufferSize;
696   VOID       *Buffer;
697   EFI_STATUS Status;
698   CHAR16     *CommandArg2;
699   CHAR16     *FileName;
700   CHAR16     *MapFileName;
701 
702   //
703   // Check the argument
704   //
705   if (CommandArg == NULL) {
706     EDBPrint (L"CodeFile not found!\n");
707     return EFI_DEBUG_CONTINUE;
708   }
709   CommandArg2 = StrGetNextTokenLine (L" ");
710   if (CommandArg2 == NULL) {
711     EDBPrint (L"SymbolFile not found!\n");
712     return EFI_DEBUG_CONTINUE;
713   }
714 
715   if (StrLen (CommandArg) <= 4) {
716     EDBPrint (L"CodeFile name error!\n");
717     return EFI_DEBUG_CONTINUE;
718   }
719   if (StriCmp (CommandArg + (StrLen (CommandArg) - 4), L".cod") != 0) {
720     EDBPrint (L"CodeFile name error!\n");
721     return EFI_DEBUG_CONTINUE;
722   }
723   if (StrLen (CommandArg2) <= 4) {
724     EDBPrint (L"SymbolFile name error!\n");
725     return EFI_DEBUG_CONTINUE;
726   }
727   if (StriCmp (CommandArg2 + (StrLen (CommandArg2) - 4), L".map") != 0) {
728     EDBPrint (L"SymbolFile name error!\n");
729     return EFI_DEBUG_CONTINUE;
730   }
731 
732   //
733   // read cod file to memory
734   //
735   Status = ReadFileToBuffer (DebuggerPrivate, CommandArg, &BufferSize, &Buffer, TRUE);
736   if (EFI_ERROR(Status)) {
737     EDBPrint (L"CodeFile read error!\n");
738     return EFI_DEBUG_CONTINUE;
739   }
740 
741   FileName = GetFileNameFromFullPath (CommandArg);
742   MapFileName = GetFileNameFromFullPath (CommandArg2);
743   //
744   // Load Code
745   //
746   Status = EdbLoadCode (DebuggerPrivate, MapFileName, FileName, BufferSize, Buffer);
747   if (EFI_ERROR (Status)) {
748     EDBPrint (L"LoadCode error!\n");
749     gBS->FreePool (Buffer);
750     return EFI_DEBUG_CONTINUE;
751   }
752 
753   //
754   // Record the buffer
755   //
756   Status = EdbAddCodeBuffer (DebuggerPrivate, MapFileName, FileName, BufferSize, Buffer);
757   if (EFI_ERROR (Status)) {
758     EDBPrint (L"AddCodeBuffer error!\n");
759     gBS->FreePool (Buffer);
760     return EFI_DEBUG_CONTINUE;
761   }
762 
763   //
764   // Done
765   //
766   return EFI_DEBUG_CONTINUE;
767 }
768 
769 /**
770 
771   DebuggerCommand - UnloadCode.
772 
773   @param  CommandArg      - The argument for this command
774   @param  DebuggerPrivate - EBC Debugger private data structure
775   @param  ExceptionType   - Exception type.
776   @param  SystemContext   - EBC system context.
777 
778   @retval EFI_DEBUG_CONTINUE - formal return value
779 
780 **/
781 EFI_DEBUG_STATUS
DebuggerUnloadCode(IN CHAR16 * CommandArg,IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate,IN EFI_EXCEPTION_TYPE ExceptionType,IN OUT EFI_SYSTEM_CONTEXT SystemContext)782 DebuggerUnloadCode (
783   IN     CHAR16                    *CommandArg,
784   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
785   IN     EFI_EXCEPTION_TYPE        ExceptionType,
786   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
787   )
788 {
789   CHAR16     *CommandArg2;
790   CHAR16     *FileName;
791   CHAR16     *MapFileName;
792   EFI_STATUS Status;
793   VOID       *BufferPtr;
794 
795   //
796   // Check the argument
797   //
798   if (CommandArg == NULL) {
799     EDBPrint (L"CodeFile not found!\n");
800     return EFI_DEBUG_CONTINUE;
801   }
802   CommandArg2 = StrGetNextTokenLine (L" ");
803   if (CommandArg2 == NULL) {
804     EDBPrint (L"SymbolFile not found!\n");
805     return EFI_DEBUG_CONTINUE;
806   }
807 
808   FileName = GetFileNameFromFullPath (CommandArg);
809   MapFileName = GetFileNameFromFullPath (CommandArg2);
810 
811   //
812   // Unload Code
813   //
814   Status = EdbUnloadCode (DebuggerPrivate, MapFileName, FileName, &BufferPtr);
815   if (EFI_ERROR (Status)) {
816     EDBPrint (L"UnloadCode error!\n");
817     return EFI_DEBUG_CONTINUE;
818   }
819 
820   //
821   // Delete Code buffer
822   //
823   Status = EdbDeleteCodeBuffer (DebuggerPrivate, MapFileName, FileName, BufferPtr);
824   if (EFI_ERROR (Status)) {
825     EDBPrint (L"DeleteCodeBuffer error!\n");
826   }
827 
828   //
829   // Done
830   //
831   return EFI_DEBUG_CONTINUE;
832 }
833 
834 /**
835 
836   DebuggerCommand - DisplayCode.
837 
838   @param  CommandArg      - The argument for this command
839   @param  DebuggerPrivate - EBC Debugger private data structure
840   @param  ExceptionType   - Exception type.
841   @param  SystemContext   - EBC system context.
842 
843   @retval EFI_DEBUG_CONTINUE - formal return value
844 
845 **/
846 EFI_DEBUG_STATUS
DebuggerDisplayCode(IN CHAR16 * CommandArg,IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate,IN EFI_EXCEPTION_TYPE ExceptionType,IN OUT EFI_SYSTEM_CONTEXT SystemContext)847 DebuggerDisplayCode (
848   IN     CHAR16                    *CommandArg,
849   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
850   IN     EFI_EXCEPTION_TYPE        ExceptionType,
851   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
852   )
853 {
854   if (CommandArg == NULL) {
855     DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly = !DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly;
856     EdbShowDisasm (DebuggerPrivate, SystemContext);
857   } else if (StriCmp (CommandArg, L"on") == 0) {
858     DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly = TRUE;
859     EdbShowDisasm (DebuggerPrivate, SystemContext);
860   } else if (StriCmp (CommandArg, L"off") == 0) {
861     DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly = FALSE;
862     EdbShowDisasm (DebuggerPrivate, SystemContext);
863   } else {
864     EDBPrint (L"DisplayCode - argument error\n");
865   }
866 
867   return EFI_DEBUG_CONTINUE;
868 }
869