CloverBootloader/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbCmdBranch.c
2019-09-03 12:58:42 +03:00

307 lines
8.2 KiB
C

/** @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;
}