MdeModulePkg/EbcDxe: add EBC Debugger
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Pete Batard <pete@akeo.ie> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
336
MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbCmdBranch.c
Normal file
336
MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbCmdBranch.c
Normal file
@@ -0,0 +1,336 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2007, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
EdbCmdBranch.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#include "Edb.h"
|
||||
|
||||
CHAR16 *mBranchTypeStr[] = {
|
||||
L"(CALL)",
|
||||
L"(CALLEX)",
|
||||
L"(RET)",
|
||||
L"(JMP)",
|
||||
L"(JMP8)",
|
||||
};
|
||||
|
||||
CHAR16 *
|
||||
EdbBranchTypeToStr (
|
||||
IN EFI_DEBUGGER_BRANCH_TYPE Type
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Comvert Branch Type to string
|
||||
|
||||
Arguments:
|
||||
|
||||
Type - Branch Type
|
||||
|
||||
Returns:
|
||||
|
||||
String
|
||||
|
||||
--*/
|
||||
{
|
||||
if (Type < 0 || Type >= EfiDebuggerBranchTypeEbcMax) {
|
||||
return L"(Unknown Type)";
|
||||
}
|
||||
|
||||
return mBranchTypeStr [Type];
|
||||
}
|
||||
|
||||
EFI_DEBUG_STATUS
|
||||
DebuggerCallStack (
|
||||
IN CHAR16 *CommandArg,
|
||||
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
|
||||
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||
IN OUT EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
DebuggerCommand - CallStack
|
||||
|
||||
Arguments:
|
||||
|
||||
CommandArg - The argument for this command
|
||||
DebuggerPrivate - EBC Debugger private data structure
|
||||
InterruptType - Interrupt type.
|
||||
SystemContext - EBC system context.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_DEBUG_CONTINUE - formal return value
|
||||
|
||||
--*/
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
EFI_DEBUG_STATUS
|
||||
DebuggerInstructionBranch (
|
||||
IN CHAR16 *CommandArg,
|
||||
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
|
||||
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||
IN OUT EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
DebuggerCommand - InstructionBranch
|
||||
|
||||
Arguments:
|
||||
|
||||
CommandArg - The argument for this command
|
||||
DebuggerPrivate - EBC Debugger private data structure
|
||||
InterruptType - Interrupt type.
|
||||
SystemContext - EBC system context.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_DEBUG_CONTINUE - formal return value
|
||||
|
||||
--*/
|
||||
{
|
||||
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;
|
||||
}
|
Reference in New Issue
Block a user