| /** @file | |
| Copyright (c) 2007, Intel Corporation. All rights reserved.<BR> | |
| This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include "Edb.h" | |
| CHAR16 *mBranchTypeStr[] = { | |
| L"(CALL)", | |
| L"(CALLEX)", | |
| L"(RET)", | |
| L"(JMP)", | |
| L"(JMP8)", | |
| }; | |
| /** | |
| Comvert Branch Type to string. | |
| @param Type Branch Type | |
| @retval String string of Branch Type. | |
| **/ | |
| CHAR16 * | |
| EdbBranchTypeToStr ( | |
| IN EFI_DEBUGGER_BRANCH_TYPE Type | |
| ) | |
| { | |
| if (Type < 0 || Type >= EfiDebuggerBranchTypeEbcMax) { | |
| return L"(Unknown Type)"; | |
| } | |
| return mBranchTypeStr [Type]; | |
| } | |
| /** | |
| DebuggerCommand - CallStack. | |
| @param CommandArg The argument for this command | |
| @param DebuggerPrivate EBC Debugger private data structure | |
| @param ExceptionType Exception type. | |
| @param SystemContext EBC system context. | |
| @retval EFI_DEBUG_CONTINUE formal return value | |
| **/ | |
| EFI_DEBUG_STATUS | |
| DebuggerCallStack ( | |
| IN CHAR16 *CommandArg, | |
| IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, | |
| IN EFI_EXCEPTION_TYPE ExceptionType, | |
| IN OUT EFI_SYSTEM_CONTEXT SystemContext | |
| ) | |
| { | |
| INTN Index; | |
| UINTN SubIndex; | |
| CHAR8 *FuncName; | |
| EFI_DEBUGGER_CALLSTACK_CONTEXT *CallStackEntry; | |
| BOOLEAN ShowParameter; | |
| UINTN ParameterNumber; | |
| ShowParameter = FALSE; | |
| ParameterNumber = EFI_DEBUGGER_CALL_DEFAULT_PARAMETER; | |
| // | |
| // Check argument | |
| // | |
| if (CommandArg != NULL) { | |
| if (StriCmp (CommandArg, L"c") == 0) { | |
| // | |
| // Clear Call-Stack | |
| // | |
| DebuggerPrivate->CallStackEntryCount = 0; | |
| ZeroMem (DebuggerPrivate->CallStackEntry, sizeof(DebuggerPrivate->CallStackEntry)); | |
| EDBPrint (L"Call-Stack is cleared\n"); | |
| return EFI_DEBUG_CONTINUE; | |
| } else if (StriCmp (CommandArg, L"p") == 0) { | |
| // | |
| // Print Call-Stack with parameter | |
| // | |
| ShowParameter = TRUE; | |
| CommandArg = StrGetNextTokenLine (L" "); | |
| if (CommandArg != NULL) { | |
| // | |
| // Try to get the parameter number | |
| // | |
| ParameterNumber = Atoi (CommandArg); | |
| if (ParameterNumber > 16) { | |
| EDBPrint (L"Call-Stack argument Invalid\n"); | |
| return EFI_DEBUG_CONTINUE; | |
| } | |
| } | |
| } else { | |
| EDBPrint (L"Call-Stack argument Invalid\n"); | |
| return EFI_DEBUG_CONTINUE; | |
| } | |
| } | |
| // | |
| // Check CallStack Entry Count | |
| // | |
| if (DebuggerPrivate->CallStackEntryCount == 0) { | |
| EDBPrint (L"No Call-Stack\n"); | |
| return EFI_DEBUG_CONTINUE; | |
| } else if (DebuggerPrivate->CallStackEntryCount > EFI_DEBUGGER_CALLSTACK_MAX) { | |
| EDBPrint (L"Call-Stack Crash, re-initialize!\n"); | |
| DebuggerPrivate->CallStackEntryCount = 0; | |
| return EFI_DEBUG_CONTINUE; | |
| } | |
| // | |
| // Go through each CallStack entry and print | |
| // | |
| EDBPrint (L"Call-Stack (TOP):\n"); | |
| EDBPrint (L" Caller Callee Name\n"); | |
| EDBPrint (L" ================== ================== ========\n"); | |
| //EDBPrint (L" 0x00000000FFFFFFFF 0xFFFFFFFF00000000 EfiMain\n"); | |
| for (Index = (INTN)(DebuggerPrivate->CallStackEntryCount - 1); Index >= 0; Index--) { | |
| // | |
| // Get CallStack and print | |
| // | |
| CallStackEntry = &DebuggerPrivate->CallStackEntry[Index]; | |
| EDBPrint ( | |
| L" 0x%016lx 0x%016lx", | |
| CallStackEntry->SourceAddress, | |
| CallStackEntry->DestAddress | |
| ); | |
| FuncName = FindSymbolStr ((UINTN)CallStackEntry->DestAddress); | |
| if (FuncName != NULL) { | |
| EDBPrint (L" %a()", FuncName); | |
| } | |
| EDBPrint (L"\n"); | |
| if (ShowParameter) { | |
| // | |
| // Print parameter | |
| // | |
| if (sizeof(UINTN) == sizeof(UINT64)) { | |
| EDBPrint ( | |
| L" Parameter Address (0x%016lx) (\n", | |
| CallStackEntry->ParameterAddr | |
| ); | |
| if (ParameterNumber == 0) { | |
| EDBPrint (L" )\n"); | |
| continue; | |
| } | |
| // | |
| // Print each parameter | |
| // | |
| for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) { | |
| if (SubIndex % 2 == 0) { | |
| EDBPrint (L" "); | |
| } | |
| EDBPrint ( | |
| L"0x%016lx, ", | |
| CallStackEntry->Parameter[SubIndex] | |
| ); | |
| if (SubIndex % 2 == 1) { | |
| EDBPrint (L"\n"); | |
| } | |
| } | |
| if (SubIndex % 2 == 0) { | |
| EDBPrint (L" "); | |
| } | |
| EDBPrint ( | |
| L"0x%016lx\n", | |
| CallStackEntry->Parameter[SubIndex] | |
| ); | |
| EDBPrint (L" )\n"); | |
| // | |
| // break only for parameter | |
| // | |
| if ((((DebuggerPrivate->CallStackEntryCount - Index) % (16 / ParameterNumber)) == 0) && | |
| (Index != 0)) { | |
| if (SetPageBreak ()) { | |
| break; | |
| } | |
| } | |
| } else { | |
| EDBPrint ( | |
| L" Parameter Address (0x%08x) (\n", | |
| CallStackEntry->ParameterAddr | |
| ); | |
| if (ParameterNumber == 0) { | |
| EDBPrint (L" )\n"); | |
| continue; | |
| } | |
| // | |
| // Print each parameter | |
| // | |
| for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) { | |
| if (SubIndex % 4 == 0) { | |
| EDBPrint (L" "); | |
| } | |
| EDBPrint ( | |
| L"0x%08x, ", | |
| CallStackEntry->Parameter[SubIndex] | |
| ); | |
| if (SubIndex % 4 == 3) { | |
| EDBPrint (L"\n"); | |
| } | |
| } | |
| if (SubIndex % 4 == 0) { | |
| EDBPrint (L" "); | |
| } | |
| EDBPrint ( | |
| L"0x%08x\n", | |
| CallStackEntry->Parameter[SubIndex] | |
| ); | |
| EDBPrint (L" )\n"); | |
| // | |
| // break only for parameter | |
| // | |
| if ((((DebuggerPrivate->CallStackEntryCount - Index) % (32 / ParameterNumber)) == 0) && | |
| (Index != 0)) { | |
| if (SetPageBreak ()) { | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // | |
| // Done | |
| // | |
| return EFI_DEBUG_CONTINUE; | |
| } | |
| /** | |
| DebuggerCommand - InstructionBranch. | |
| @param CommandArg The argument for this command | |
| @param DebuggerPrivate EBC Debugger private data structure | |
| @param ExceptionType Exception type. | |
| @param SystemContext EBC system context. | |
| @retval EFI_DEBUG_CONTINUE formal return value | |
| **/ | |
| EFI_DEBUG_STATUS | |
| DebuggerInstructionBranch ( | |
| IN CHAR16 *CommandArg, | |
| IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, | |
| IN EFI_EXCEPTION_TYPE ExceptionType, | |
| IN OUT EFI_SYSTEM_CONTEXT SystemContext | |
| ) | |
| { | |
| UINTN Index; | |
| // | |
| // Check argument | |
| // | |
| if (CommandArg != NULL) { | |
| if (StriCmp (CommandArg, L"c") == 0) { | |
| // | |
| // Clear Trace | |
| // | |
| DebuggerPrivate->TraceEntryCount = 0; | |
| ZeroMem (DebuggerPrivate->TraceEntry, sizeof(DebuggerPrivate->TraceEntry)); | |
| EDBPrint (L"Instruction Trace is cleared\n"); | |
| } else { | |
| EDBPrint (L"Trace argument Invalid\n"); | |
| } | |
| return EFI_DEBUG_CONTINUE; | |
| } | |
| // | |
| // Check Trace Entry Count | |
| // | |
| if (DebuggerPrivate->TraceEntryCount == 0) { | |
| EDBPrint (L"No Instruction Trace\n"); | |
| return EFI_DEBUG_CONTINUE; | |
| } else if (DebuggerPrivate->TraceEntryCount > EFI_DEBUGGER_TRACE_MAX) { | |
| EDBPrint (L"Instruction Trace Crash, re-initialize!\n"); | |
| DebuggerPrivate->TraceEntryCount = 0; | |
| return EFI_DEBUG_CONTINUE; | |
| } | |
| // | |
| // Go through each Trace entry and print | |
| // | |
| EDBPrint (L"Instruction Trace (->Latest):\n"); | |
| EDBPrint (L" Source Addr Destination Addr Type\n"); | |
| EDBPrint (L" ================== ================== ========\n"); | |
| //EDBPrint (L" 0x00000000FFFFFFFF 0xFFFFFFFF00000000 (CALLEX)\n"); | |
| for (Index = 0; Index < DebuggerPrivate->TraceEntryCount; Index++) { | |
| EDBPrint ( | |
| L" 0x%016lx 0x%016lx %s\n", | |
| DebuggerPrivate->TraceEntry[Index].SourceAddress, | |
| DebuggerPrivate->TraceEntry[Index].DestAddress, | |
| EdbBranchTypeToStr (DebuggerPrivate->TraceEntry[Index].Type) | |
| ); | |
| } | |
| // | |
| // Done | |
| // | |
| return EFI_DEBUG_CONTINUE; | |
| } |