mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-03 13:13:30 +01:00
7c0aa811ec
Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
1212 lines
25 KiB
C
1212 lines
25 KiB
C
/** @file
|
|
|
|
Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
|
|
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"<Unknown Instruction>");
|
|
}
|
|
}
|
|
|
|
EdbPrintSource ((UINTN)InstructionAddress, TRUE);
|
|
|
|
InstructionAddress += InstructionLength;
|
|
} else {
|
|
//
|
|
// Something wrong with OPCODE
|
|
//
|
|
EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE);
|
|
EDBPrint (L"%s\n", L"<Bad Instruction>");
|
|
break;
|
|
}
|
|
} else {
|
|
//
|
|
// Something wrong with OPCODE
|
|
//
|
|
EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE);
|
|
EDBPrint (L"%s\n", L"<Bad Instruction>");
|
|
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;
|
|
}
|