blob: eb9f3db4f946f93840468411941194760bdbad17 [file] [log] [blame]
/** @file
Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#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;
}