audk/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbCmdBranch.c

313 lines
8.5 KiB
C

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