• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3 Copyright (c) 2007, 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 CHAR16 *mBranchTypeStr[] = {
18   L"(CALL)",
19   L"(CALLEX)",
20   L"(RET)",
21   L"(JMP)",
22   L"(JMP8)",
23 };
24 
25 /**
26 
27   Comvert Branch Type to string.
28 
29   @param Type        Branch Type
30 
31   @retval String     string of Branch Type.
32 
33 **/
34 CHAR16 *
EdbBranchTypeToStr(IN EFI_DEBUGGER_BRANCH_TYPE Type)35 EdbBranchTypeToStr (
36   IN EFI_DEBUGGER_BRANCH_TYPE  Type
37   )
38 {
39   if (Type < 0 || Type >= EfiDebuggerBranchTypeEbcMax) {
40     return L"(Unknown Type)";
41   }
42 
43   return mBranchTypeStr [Type];
44 }
45 
46 /**
47 
48   DebuggerCommand - CallStack.
49 
50   @param  CommandArg         The argument for this command
51   @param  DebuggerPrivate    EBC Debugger private data structure
52   @param  ExceptionType      Exception type.
53   @param  SystemContext      EBC system context.
54 
55   @retval EFI_DEBUG_CONTINUE   formal return value
56 
57 **/
58 EFI_DEBUG_STATUS
DebuggerCallStack(IN CHAR16 * CommandArg,IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate,IN EFI_EXCEPTION_TYPE ExceptionType,IN OUT EFI_SYSTEM_CONTEXT SystemContext)59 DebuggerCallStack (
60   IN     CHAR16                    *CommandArg,
61   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
62   IN     EFI_EXCEPTION_TYPE        ExceptionType,
63   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
64   )
65 {
66   INTN                           Index;
67   UINTN                          SubIndex;
68   CHAR8                          *FuncName;
69   EFI_DEBUGGER_CALLSTACK_CONTEXT *CallStackEntry;
70   BOOLEAN                        ShowParameter;
71   UINTN                          ParameterNumber;
72 
73   ShowParameter = FALSE;
74   ParameterNumber = EFI_DEBUGGER_CALL_DEFAULT_PARAMETER;
75 
76   //
77   // Check argument
78   //
79   if (CommandArg != NULL) {
80     if (StriCmp (CommandArg, L"c") == 0) {
81       //
82       // Clear Call-Stack
83       //
84       DebuggerPrivate->CallStackEntryCount = 0;
85       ZeroMem (DebuggerPrivate->CallStackEntry, sizeof(DebuggerPrivate->CallStackEntry));
86       EDBPrint (L"Call-Stack is cleared\n");
87       return EFI_DEBUG_CONTINUE;
88     } else if (StriCmp (CommandArg, L"p") == 0) {
89       //
90       // Print Call-Stack with parameter
91       //
92       ShowParameter = TRUE;
93       CommandArg = StrGetNextTokenLine (L" ");
94       if (CommandArg != NULL) {
95         //
96         // Try to get the parameter number
97         //
98         ParameterNumber = Atoi (CommandArg);
99         if (ParameterNumber > 16) {
100           EDBPrint (L"Call-Stack argument Invalid\n");
101           return EFI_DEBUG_CONTINUE;
102         }
103       }
104     } else {
105       EDBPrint (L"Call-Stack argument Invalid\n");
106       return EFI_DEBUG_CONTINUE;
107     }
108   }
109 
110   //
111   // Check CallStack Entry Count
112   //
113   if (DebuggerPrivate->CallStackEntryCount == 0) {
114     EDBPrint (L"No Call-Stack\n");
115     return EFI_DEBUG_CONTINUE;
116   } else if (DebuggerPrivate->CallStackEntryCount > EFI_DEBUGGER_CALLSTACK_MAX) {
117     EDBPrint (L"Call-Stack Crash, re-initialize!\n");
118     DebuggerPrivate->CallStackEntryCount = 0;
119     return EFI_DEBUG_CONTINUE;
120   }
121 
122   //
123   // Go through each CallStack entry and print
124   //
125   EDBPrint (L"Call-Stack (TOP):\n");
126   EDBPrint (L"         Caller             Callee        Name\n");
127   EDBPrint (L"  ================== ================== ========\n");
128 //EDBPrint (L"  0x00000000FFFFFFFF 0xFFFFFFFF00000000 EfiMain\n");
129   for (Index = (INTN)(DebuggerPrivate->CallStackEntryCount - 1); Index >= 0; Index--) {
130     //
131     // Get CallStack and print
132     //
133     CallStackEntry = &DebuggerPrivate->CallStackEntry[Index];
134     EDBPrint (
135       L"  0x%016lx 0x%016lx",
136       CallStackEntry->SourceAddress,
137       CallStackEntry->DestAddress
138       );
139     FuncName = FindSymbolStr ((UINTN)CallStackEntry->DestAddress);
140     if (FuncName != NULL) {
141       EDBPrint (L" %a()", FuncName);
142     }
143     EDBPrint (L"\n");
144 
145     if (ShowParameter) {
146       //
147       // Print parameter
148       //
149       if (sizeof(UINTN) == sizeof(UINT64)) {
150         EDBPrint (
151           L"    Parameter Address (0x%016lx) (\n",
152           CallStackEntry->ParameterAddr
153           );
154         if (ParameterNumber == 0) {
155           EDBPrint (L"        )\n");
156           continue;
157         }
158         //
159         // Print each parameter
160         //
161         for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
162           if (SubIndex % 2 == 0) {
163             EDBPrint (L"        ");
164           }
165           EDBPrint (
166             L"0x%016lx, ",
167             CallStackEntry->Parameter[SubIndex]
168             );
169           if (SubIndex % 2 == 1) {
170             EDBPrint (L"\n");
171           }
172         }
173         if (SubIndex % 2 == 0) {
174           EDBPrint (L"        ");
175         }
176         EDBPrint (
177           L"0x%016lx\n",
178           CallStackEntry->Parameter[SubIndex]
179           );
180         EDBPrint (L"        )\n");
181         //
182         // break only for parameter
183         //
184         if ((((DebuggerPrivate->CallStackEntryCount - Index) % (16 / ParameterNumber)) == 0) &&
185             (Index != 0)) {
186           if (SetPageBreak ()) {
187             break;
188           }
189         }
190       } else {
191         EDBPrint (
192           L"    Parameter Address (0x%08x) (\n",
193           CallStackEntry->ParameterAddr
194           );
195         if (ParameterNumber == 0) {
196           EDBPrint (L"        )\n");
197           continue;
198         }
199         //
200         // Print each parameter
201         //
202         for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
203           if (SubIndex % 4 == 0) {
204             EDBPrint (L"        ");
205           }
206           EDBPrint (
207             L"0x%08x, ",
208             CallStackEntry->Parameter[SubIndex]
209             );
210           if (SubIndex % 4 == 3) {
211             EDBPrint (L"\n");
212           }
213         }
214         if (SubIndex % 4 == 0) {
215           EDBPrint (L"        ");
216         }
217         EDBPrint (
218           L"0x%08x\n",
219           CallStackEntry->Parameter[SubIndex]
220           );
221         EDBPrint (L"        )\n");
222         //
223         // break only for parameter
224         //
225         if ((((DebuggerPrivate->CallStackEntryCount - Index) % (32 / ParameterNumber)) == 0) &&
226             (Index != 0)) {
227           if (SetPageBreak ()) {
228             break;
229           }
230         }
231       }
232     }
233   }
234 
235   //
236   // Done
237   //
238   return EFI_DEBUG_CONTINUE;
239 }
240 
241 /**
242 
243   DebuggerCommand - InstructionBranch.
244 
245   @param  CommandArg             The argument for this command
246   @param  DebuggerPrivate        EBC Debugger private data structure
247   @param  ExceptionType          Exception type.
248   @param  SystemContext          EBC system context.
249 
250   @retval  EFI_DEBUG_CONTINUE    formal return value
251 
252 **/
253 EFI_DEBUG_STATUS
DebuggerInstructionBranch(IN CHAR16 * CommandArg,IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate,IN EFI_EXCEPTION_TYPE ExceptionType,IN OUT EFI_SYSTEM_CONTEXT SystemContext)254 DebuggerInstructionBranch (
255   IN     CHAR16                    *CommandArg,
256   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
257   IN     EFI_EXCEPTION_TYPE        ExceptionType,
258   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
259   )
260 {
261   UINTN  Index;
262 
263   //
264   // Check argument
265   //
266   if (CommandArg != NULL) {
267     if (StriCmp (CommandArg, L"c") == 0) {
268       //
269       // Clear Trace
270       //
271       DebuggerPrivate->TraceEntryCount = 0;
272       ZeroMem (DebuggerPrivate->TraceEntry, sizeof(DebuggerPrivate->TraceEntry));
273       EDBPrint (L"Instruction Trace is cleared\n");
274     } else {
275       EDBPrint (L"Trace argument Invalid\n");
276     }
277     return EFI_DEBUG_CONTINUE;
278   }
279 
280   //
281   // Check Trace Entry Count
282   //
283   if (DebuggerPrivate->TraceEntryCount == 0) {
284     EDBPrint (L"No Instruction Trace\n");
285     return EFI_DEBUG_CONTINUE;
286   } else if (DebuggerPrivate->TraceEntryCount > EFI_DEBUGGER_TRACE_MAX) {
287     EDBPrint (L"Instruction Trace Crash, re-initialize!\n");
288     DebuggerPrivate->TraceEntryCount = 0;
289     return EFI_DEBUG_CONTINUE;
290   }
291 
292   //
293   // Go through each Trace entry and print
294   //
295   EDBPrint (L"Instruction Trace (->Latest):\n");
296   EDBPrint (L"    Source Addr        Destination Addr   Type\n");
297   EDBPrint (L"  ================== ================== ========\n");
298 //EDBPrint (L"  0x00000000FFFFFFFF 0xFFFFFFFF00000000  (CALLEX)\n");
299   for (Index = 0; Index < DebuggerPrivate->TraceEntryCount; Index++) {
300     EDBPrint (
301       L"  0x%016lx 0x%016lx  %s\n",
302       DebuggerPrivate->TraceEntry[Index].SourceAddress,
303       DebuggerPrivate->TraceEntry[Index].DestAddress,
304       EdbBranchTypeToStr (DebuggerPrivate->TraceEntry[Index].Type)
305       );
306   }
307 
308   //
309   // Done
310   //
311   return EFI_DEBUG_CONTINUE;
312 }
313