/** @file
Copyright (c) 2007, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "Edb.h"
extern EDB_DISASM_INSTRUCTION mEdbDisasmInstructionTable[];
typedef struct {
CHAR16 Name[EDB_INSTRUCTION_NAME_MAX_LENGTH];
CHAR16 Content[EDB_INSTRUCTION_CONTENT_MAX_LENGTH];
CHAR16 Tail;
} EDB_INSTRUCTION_STRING;
EDB_INSTRUCTION_STRING mInstructionString;
UINTN mInstructionNameOffset;
UINTN mInstructionContentOffset;
/**
Set offset for Instruction name and content.
@param InstructionNameOffset - Instruction name offset
@param InstructionContentOffset - Instruction content offset
**/
VOID
EdbSetOffset (
IN UINTN InstructionNameOffset,
IN UINTN InstructionContentOffset
)
{
mInstructionNameOffset = InstructionNameOffset;
mInstructionContentOffset = InstructionContentOffset;
return;
}
/**
Pre instruction string construction.
@return Instruction string
**/
CHAR16 *
EdbPreInstructionString (
VOID
)
{
ZeroMem (&mInstructionString, sizeof (mInstructionString));
mInstructionNameOffset = 0;
mInstructionContentOffset = 0;
return (CHAR16 *)&mInstructionString;
}
/**
Post instruction string construction.
@return Instruction string
**/
CHAR16 *
EdbPostInstructionString (
VOID
)
{
CHAR16 *Char;
for (Char = (CHAR16 *)&mInstructionString; Char < &mInstructionString.Tail; Char++) {
if (*Char == 0) {
*Char = L' ';
}
}
mInstructionString.Tail = 0;
mInstructionNameOffset = 0;
mInstructionContentOffset = 0;
return (CHAR16 *)&mInstructionString;
}
/**
Get Sign, NaturalUnits, and ConstantUnits of the WORD data.
@param Data16 - WORD data
@param NaturalUnits - Natural Units of the WORD
@param ConstantUnits - Constant Units of the WORD
@return Sign value of WORD
**/
BOOLEAN
EdbGetNaturalIndex16 (
IN UINT16 Data16,
OUT UINTN *NaturalUnits,
OUT UINTN *ConstantUnits
)
{
BOOLEAN Sign;
UINTN NaturalUnitBit;
Sign = (BOOLEAN)(Data16 >> 15);
NaturalUnitBit = (UINTN)((Data16 >> 12) & 0x7);
NaturalUnitBit *= 2;
Data16 = Data16 & 0xFFF;
*NaturalUnits = (UINTN)(Data16 & ((1 << NaturalUnitBit) - 1));
*ConstantUnits = (UINTN)((Data16 >> NaturalUnitBit) & ((1 << (12 - NaturalUnitBit)) - 1));
return Sign;
}
/**
Get Sign, NaturalUnits, and ConstantUnits of the DWORD data.
@param Data32 - DWORD data
@param NaturalUnits - Natural Units of the DWORD
@param ConstantUnits - Constant Units of the DWORD
@return Sign value of DWORD
**/
BOOLEAN
EdbGetNaturalIndex32 (
IN UINT32 Data32,
OUT UINTN *NaturalUnits,
OUT UINTN *ConstantUnits
)
{
BOOLEAN Sign;
UINTN NaturalUnitBit;
Sign = (BOOLEAN)(Data32 >> 31);
NaturalUnitBit = (UINTN)((Data32 >> 28) & 0x7);
NaturalUnitBit *= 4;
Data32 = Data32 & 0xFFFFFFF;
*NaturalUnits = (UINTN)(Data32 & ((1 << NaturalUnitBit) - 1));
*ConstantUnits = (UINTN)((Data32 >> NaturalUnitBit) & ((1 << (28 - NaturalUnitBit)) - 1));
return Sign;
}
/**
Get Sign, NaturalUnits, and ConstantUnits of the QWORD data.
@param Data64 - QWORD data
@param NaturalUnits - Natural Units of the QWORD
@param ConstantUnits - Constant Units of the QWORD
@return Sign value of QWORD
**/
BOOLEAN
EdbGetNaturalIndex64 (
IN UINT64 Data64,
OUT UINT64 *NaturalUnits,
OUT UINT64 *ConstantUnits
)
{
BOOLEAN Sign;
UINTN NaturalUnitBit;
Sign = (BOOLEAN)RShiftU64 (Data64, 63);
NaturalUnitBit = (UINTN)(RShiftU64 (Data64, 60) & 0x7);
NaturalUnitBit *= 8;
Data64 = RShiftU64 (LShiftU64 (Data64, 4), 4);
*NaturalUnits = (UINT64)(Data64 & (LShiftU64 (1, NaturalUnitBit) - 1));
*ConstantUnits = (UINT64)(RShiftU64 (Data64, NaturalUnitBit) & (LShiftU64 (1, (60 - NaturalUnitBit)) - 1));
return Sign;
}
/**
Get Bit Width of the value.
@param Value - data
@return Bit width
**/
UINT8
EdbGetBitWidth (
IN UINT64 Value
)
{
if (Value >= 10000000000000) {
return 14;
} else if (Value >= 1000000000000) {
return 13;
} else if (Value >= 100000000000) {
return 12;
} else if (Value >= 10000000000) {
return 11;
} else if (Value >= 1000000000) {
return 10;
} else if (Value >= 100000000) {
return 9;
} else if (Value >= 10000000) {
return 8;
} else if (Value >= 1000000) {
return 7;
} else if (Value >= 100000) {
return 6;
} else if (Value >= 10000) {
return 5;
} else if (Value >= 1000) {
return 4;
} else if (Value >= 100) {
return 3;
} else if (Value >= 10) {
return 2;
} else {
return 1;
}
}
/**
Print the instruction name.
@param Name - instruction name
@return Instruction name offset
**/
UINTN
EdbPrintInstructionName (
IN CHAR16 *Name
)
{
EDBSPrintWithOffset (
mInstructionString.Name,
EDB_INSTRUCTION_NAME_MAX_SIZE,
mInstructionNameOffset,
L"%s",
Name
);
mInstructionNameOffset += StrLen (Name);
return mInstructionNameOffset;
}
/**
Print register 1 in operands.
@param Operands - instruction operands
@return Instruction content offset
**/
UINTN
EdbPrintRegister1 (
IN UINT8 Operands
)
{
if ((Operands & OPERAND_M_INDIRECT1) != 0) {
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"@"
);
mInstructionContentOffset += 1;
}
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"R%d",
(UINTN)(Operands & OPERAND_M_OP1)
);
mInstructionContentOffset += 2;
return mInstructionContentOffset;
}
/**
Print register 2 in operands.
@param Operands - instruction operands
@return Instruction content offset
**/
UINTN
EdbPrintRegister2 (
IN UINT8 Operands
)
{
if ((Operands & OPERAND_M_INDIRECT2) != 0) {
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"@"
);
mInstructionContentOffset += 1;
}
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"R%d",
(UINTN)((Operands & OPERAND_M_OP2) >> 4)
);
mInstructionContentOffset += 2;
return mInstructionContentOffset;
}
/**
Print dedicated register 1 in operands.
@param Operands - instruction operands
@return Instruction content offset
**/
UINTN
EdbPrintDedicatedRegister1 (
IN UINT8 Operands
)
{
switch (Operands & OPERAND_M_OP1) {
case 0:
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"[FLAGS]"
);
mInstructionContentOffset += 7;
break;
case 1:
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"[IP]"
);
mInstructionContentOffset += 4;
break;
}
return mInstructionContentOffset;
}
/**
Print dedicated register 2 in operands.
@param Operands - instruction operands
@return Instruction content offset
**/
UINTN
EdbPrintDedicatedRegister2 (
IN UINT8 Operands
)
{
switch ((Operands & OPERAND_M_OP2) >> 4) {
case 0:
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"[FLAGS]"
);
mInstructionContentOffset += 7;
break;
case 1:
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"[IP]"
);
mInstructionContentOffset += 4;
break;
}
return mInstructionContentOffset;
}
/**
Print the hexical UINTN index data to instruction content.
@param Sign - Signed bit of UINTN data
@param NaturalUnits - natural units of UINTN data
@param ConstantUnits - natural units of UINTN data
@return Instruction content offset
**/
UINTN
EdbPrintIndexData (
IN BOOLEAN Sign,
IN UINTN NaturalUnits,
IN UINTN ConstantUnits
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"(%s%d,%s%d)",
Sign ? L"-" : L"+",
NaturalUnits,
Sign ? L"-" : L"+",
ConstantUnits
);
mInstructionContentOffset = mInstructionContentOffset + 5 + EdbGetBitWidth (NaturalUnits) + EdbGetBitWidth (ConstantUnits);
return mInstructionContentOffset;
}
/**
Print the hexical QWORD index data to instruction content.
@param Sign - Signed bit of QWORD data
@param NaturalUnits - natural units of QWORD data
@param ConstantUnits - natural units of QWORD data
@return Instruction content offset
**/
UINTN
EdbPrintIndexData64 (
IN BOOLEAN Sign,
IN UINT64 NaturalUnits,
IN UINT64 ConstantUnits
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"(%s%ld,%s%ld)",
Sign ? L"-" : L"+",
NaturalUnits,
Sign ? L"-" : L"+",
ConstantUnits
);
mInstructionContentOffset = mInstructionContentOffset + 5 + EdbGetBitWidth (NaturalUnits) + EdbGetBitWidth (ConstantUnits);
return mInstructionContentOffset;
}
/**
Print the hexical WORD raw index data to instruction content.
@param Data16 - WORD data
@return Instruction content offset
**/
UINTN
EdbPrintRawIndexData16 (
IN UINT16 Data16
)
{
BOOLEAN Sign;
UINTN NaturalUnits;
UINTN ConstantUnits;
UINTN Offset;
Sign = EdbGetNaturalIndex16 (Data16, &NaturalUnits, &ConstantUnits);
Offset = EdbPrintIndexData (Sign, NaturalUnits, ConstantUnits);
return Offset;
}
/**
Print the hexical DWORD raw index data to instruction content.
@param Data32 - DWORD data
@return Instruction content offset
**/
UINTN
EdbPrintRawIndexData32 (
IN UINT32 Data32
)
{
BOOLEAN Sign;
UINTN NaturalUnits;
UINTN ConstantUnits;
UINTN Offset;
Sign = EdbGetNaturalIndex32 (Data32, &NaturalUnits, &ConstantUnits);
Offset = EdbPrintIndexData (Sign, NaturalUnits, ConstantUnits);
return Offset;
}
/**
Print the hexical QWORD raw index data to instruction content.
@param Data64 - QWORD data
@return Instruction content offset
**/
UINTN
EdbPrintRawIndexData64 (
IN UINT64 Data64
)
{
BOOLEAN Sign;
UINT64 NaturalUnits;
UINT64 ConstantUnits;
UINTN Offset;
Sign = EdbGetNaturalIndex64 (Data64, &NaturalUnits, &ConstantUnits);
Offset = EdbPrintIndexData64 (Sign, NaturalUnits, ConstantUnits);
return Offset;
}
/**
Print the hexical BYTE immediate data to instruction content.
@param Data - BYTE data
@return Instruction content offset
**/
UINTN
EdbPrintImmData8 (
IN UINT8 Data
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"(0x%02x)",
(UINTN)Data
);
mInstructionContentOffset += 6;
return mInstructionContentOffset;
}
/**
Print the hexical WORD immediate data to instruction content.
@param Data - WORD data
@return Instruction content offset
**/
UINTN
EdbPrintImmData16 (
IN UINT16 Data
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"(0x%04x)",
(UINTN)Data
);
mInstructionContentOffset += 8;
return mInstructionContentOffset;
}
/**
Print the hexical DWORD immediate data to instruction content.
@param Data - DWORD data
@return Instruction content offset
**/
UINTN
EdbPrintImmData32 (
IN UINT32 Data
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"(0x%08x)",
(UINTN)Data
);
mInstructionContentOffset += 12;
return mInstructionContentOffset;
}
/**
Print the hexical QWORD immediate data to instruction content.
@param Data - QWORD data
@return Instruction content offset
**/
UINTN
EdbPrintImmData64 (
IN UINT64 Data
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"(0x%016lx)",
Data
);
mInstructionContentOffset += 20;
return mInstructionContentOffset;
}
/**
Print the decimal UINTN immediate data to instruction content.
@param Data - UINTN data
@return Instruction content offset
**/
UINTN
EdbPrintImmDatan (
IN UINTN Data
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"(%d)",
(UINTN)Data
);
mInstructionContentOffset = mInstructionContentOffset + 2 + EdbGetBitWidth (Data);
return mInstructionContentOffset;
}
/**
Print the decimal QWORD immediate data to instruction content.
@param Data64 - QWORD data
@return Instruction content offset
**/
UINTN
EdbPrintImmData64n (
IN UINT64 Data64
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"(%ld)",
Data64
);
mInstructionContentOffset = mInstructionContentOffset + 2 + EdbGetBitWidth (Data64);
return mInstructionContentOffset;
}
/**
Print the hexical BYTE to instruction content.
@param Data8 - BYTE data
@return Instruction content offset
**/
UINTN
EdbPrintData8 (
IN UINT8 Data8
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"0x%02x",
(UINTN)Data8
);
mInstructionContentOffset += 4;
return mInstructionContentOffset;
}
/**
Print the hexical WORD to instruction content.
@param Data16 - WORD data
@return Instruction content offset
**/
UINTN
EdbPrintData16 (
IN UINT16 Data16
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"0x%04x",
(UINTN)Data16
);
mInstructionContentOffset += 6;
return mInstructionContentOffset;
}
/**
Print the hexical DWORD to instruction content.
@param Data32 - DWORD data
@return Instruction content offset
**/
UINTN
EdbPrintData32 (
IN UINT32 Data32
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"0x%08x",
(UINTN)Data32
);
mInstructionContentOffset += 10;
return mInstructionContentOffset;
}
/**
Print the hexical QWORD to instruction content.
@param Data64 - QWORD data
@return Instruction content offset
**/
UINTN
EdbPrintData64 (
IN UINT64 Data64
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"0x%016lx",
(UINT64)Data64
);
mInstructionContentOffset += 18;
return mInstructionContentOffset;
}
/**
Print the decimal unsigned UINTN to instruction content.
@param Data - unsigned UINTN data
@return Instruction content offset
**/
UINTN
EdbPrintDatan (
IN UINTN Data
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"%d",
(UINTN)Data
);
mInstructionContentOffset = mInstructionContentOffset + EdbGetBitWidth (Data);
return mInstructionContentOffset;
}
/**
Print the decimal unsigned QWORD to instruction content.
@param Data64 - unsigned QWORD data
@return Instruction content offset
**/
UINTN
EdbPrintData64n (
IN UINT64 Data64
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"%ld",
Data64
);
mInstructionContentOffset = mInstructionContentOffset + EdbGetBitWidth (Data64);
return mInstructionContentOffset;
}
/**
Print the decimal signed BYTE to instruction content.
@param Data8 - signed BYTE data
@return Instruction content offset
**/
UINTN
EdbPrintData8s (
IN UINT8 Data8
)
{
BOOLEAN Sign;
Sign = (BOOLEAN)(Data8 >> 7);
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"%s%d",
Sign ? L"-" : L"+",
(UINTN)(Data8 & 0x7F)
);
mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data8 & 0x7F);
return mInstructionContentOffset;
}
/**
Print the decimal signed WORD to instruction content.
@param Data16 - signed WORD data
@return Instruction content offset
**/
UINTN
EdbPrintData16s (
IN UINT16 Data16
)
{
BOOLEAN Sign;
Sign = (BOOLEAN)(Data16 >> 15);
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"%s%d",
Sign ? L"-" : L"+",
(UINTN)(Data16 & 0x7FFF)
);
mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data16 & 0x7FFF);
return mInstructionContentOffset;
}
/**
Print the decimal signed DWORD to instruction content.
@param Data32 - signed DWORD data
@return Instruction content offset
**/
UINTN
EdbPrintData32s (
IN UINT32 Data32
)
{
BOOLEAN Sign;
Sign = (BOOLEAN)(Data32 >> 31);
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"%s%d",
Sign ? L"-" : L"+",
(UINTN)(Data32 & 0x7FFFFFFF)
);
mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data32 & 0x7FFFFFFF);
return mInstructionContentOffset;
}
/**
Print the decimal signed QWORD to instruction content.
@param Data64 - signed QWORD data
@return Instruction content offset
**/
UINTN
EdbPrintData64s (
IN UINT64 Data64
)
{
BOOLEAN Sign;
INT64 Data64s;
Sign = (BOOLEAN)RShiftU64 (Data64, 63);
Data64s = (INT64)RShiftU64 (LShiftU64 (Data64, 1), 1);
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"%s%ld",
Sign ? L"-" : L"+",
(UINT64)Data64s
);
mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data64s);
return mInstructionContentOffset;
}
/**
Print the comma to instruction content.
@return Instruction content offset
**/
UINTN
EdbPrintComma (
VOID
)
{
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L", "
);
mInstructionContentOffset += 2;
return mInstructionContentOffset;
}
/**
Find the symbol string according to address, then print it.
@param Address - instruction address
@retval 1 - symbol string is found and printed
@retval 0 - symbol string not found
**/
UINTN
EdbFindAndPrintSymbol (
IN UINTN Address
)
{
CHAR8 *SymbolStr;
SymbolStr = FindSymbolStr (Address);
if (SymbolStr != NULL) {
EDBSPrintWithOffset (
mInstructionString.Content,
EDB_INSTRUCTION_CONTENT_MAX_SIZE,
mInstructionContentOffset,
L"[%a]",
SymbolStr
);
return 1;
}
return 0;
}
/**
Print the EBC byte code.
@param InstructionAddress - instruction address
@param InstructionNumber - instruction number
**/
VOID
EdbPrintRaw (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN UINTN InstructionNumber
)
{
UINTN LineNumber;
UINTN ByteNumber;
UINTN LineIndex;
UINTN ByteIndex;
CHAR8 *SymbolStr;
if (InstructionNumber == 0) {
return;
}
LineNumber = InstructionNumber / EDB_BYTECODE_NUMBER_IN_LINE;
ByteNumber = InstructionNumber % EDB_BYTECODE_NUMBER_IN_LINE;
if (ByteNumber == 0) {
LineNumber -= 1;
ByteNumber = EDB_BYTECODE_NUMBER_IN_LINE;
}
//
// Print Symbol
//
SymbolStr = FindSymbolStr ((UINTN)InstructionAddress);
if (SymbolStr != NULL) {
EDBPrint (L"[%a]:\n", SymbolStr);
}
for (LineIndex = 0; LineIndex < LineNumber; LineIndex++) {
EDBPrint (EDB_PRINT_ADDRESS_FORMAT, (UINTN)InstructionAddress);
for (ByteIndex = 0; ByteIndex < EDB_BYTECODE_NUMBER_IN_LINE; ByteIndex++) {
EDBPrint (L"%02x ", *(UINT8 *)(UINTN)InstructionAddress);
InstructionAddress += 1;
}
EDBPrint (L"\n");
}
EDBPrint (EDB_PRINT_ADDRESS_FORMAT, (UINTN)InstructionAddress);
for (ByteIndex = 0; ByteIndex < ByteNumber; ByteIndex++) {
EDBPrint (L"%02x ", *(UINT8 *)(UINTN)InstructionAddress);
InstructionAddress += 1;
}
for (ByteIndex = 0; ByteIndex < EDB_BYTECODE_NUMBER_IN_LINE - ByteNumber; ByteIndex++) {
EDBPrint (L" ");
}
return;
}
/**
Print the EBC asm code.
@param DebuggerPrivate - EBC Debugger private data structure
@param SystemContext - EBC system context.
@retval EFI_SUCCESS - show disasm successfully
**/
EFI_STATUS
EdbShowDisasm (
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
EFI_PHYSICAL_ADDRESS InstructionAddress;
UINTN InstructionNumber;
UINTN InstructionLength;
UINT8 Opcode;
CHAR16 *InstructionString;
// UINTN Result;
InstructionAddress = DebuggerPrivate->InstructionScope;
for (InstructionNumber = 0; InstructionNumber < DebuggerPrivate->InstructionNumber; InstructionNumber++) {
//
// Break each 0x10 instruction
//
if (((InstructionNumber % EFI_DEBUGGER_LINE_NUMBER_IN_PAGE) == 0) &&
(InstructionNumber != 0))
{
if (SetPageBreak ()) {
break;
}
}
Opcode = GET_OPCODE (InstructionAddress);
if ((Opcode < OPCODE_MAX) && (mEdbDisasmInstructionTable[Opcode] != NULL)) {
InstructionLength = mEdbDisasmInstructionTable[Opcode](InstructionAddress, SystemContext, &InstructionString);
if (InstructionLength != 0) {
//
// Print Source
//
// Result = EdbPrintSource ((UINTN)InstructionAddress, FALSE);
if (!DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly) {
EdbPrintRaw (InstructionAddress, InstructionLength);
if (InstructionString != NULL) {
EDBPrint (L"%s\n", InstructionString);
} else {
EDBPrint (L"%s\n", L"");
}
}
EdbPrintSource ((UINTN)InstructionAddress, TRUE);
InstructionAddress += InstructionLength;
} else {
//
// Something wrong with OPCODE
//
EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE);
EDBPrint (L"%s\n", L"");
break;
}
} else {
//
// Something wrong with OPCODE
//
EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE);
EDBPrint (L"%s\n", L"");
break;
}
}
return EFI_SUCCESS;
}
/**
Get register value according to the system context, and register index.
@param SystemContext - EBC system context.
@param Index - EBC register index
@return register value
**/
UINT64
GetRegisterValue (
IN EFI_SYSTEM_CONTEXT SystemContext,
IN UINT8 Index
)
{
switch (Index) {
case 0:
return SystemContext.SystemContextEbc->R0;
case 1:
return SystemContext.SystemContextEbc->R1;
case 2:
return SystemContext.SystemContextEbc->R2;
case 3:
return SystemContext.SystemContextEbc->R3;
case 4:
return SystemContext.SystemContextEbc->R4;
case 5:
return SystemContext.SystemContextEbc->R5;
case 6:
return SystemContext.SystemContextEbc->R6;
case 7:
return SystemContext.SystemContextEbc->R7;
default:
ASSERT (FALSE);
break;
}
return 0;
}