/** @file | |
Copyright (c) 2007, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "Edb.h" | |
// | |
// Debugger Disasm definition | |
// | |
#define EDB_DISASM_DEFINE(func) \ | |
UINTN \ | |
func ( \ | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, \ | |
IN EFI_SYSTEM_CONTEXT SystemContext, \ | |
OUT CHAR16 **DisasmString \ | |
) | |
EDB_DISASM_DEFINE (EdbDisasmBREAK); | |
EDB_DISASM_DEFINE (EdbDisasmJMP); | |
EDB_DISASM_DEFINE (EdbDisasmJMP8); | |
EDB_DISASM_DEFINE (EdbDisasmCALL); | |
EDB_DISASM_DEFINE (EdbDisasmRET); | |
EDB_DISASM_DEFINE (EdbDisasmCMP); | |
EDB_DISASM_DEFINE (EdbDisasmUnsignedDataManip); | |
EDB_DISASM_DEFINE (EdbDisasmSignedDataManip); | |
EDB_DISASM_DEFINE (EdbDisasmMOVxx); | |
EDB_DISASM_DEFINE (EdbDisasmMOVsnw); | |
EDB_DISASM_DEFINE (EdbDisasmMOVsnd); | |
EDB_DISASM_DEFINE (EdbDisasmLOADSP); | |
EDB_DISASM_DEFINE (EdbDisasmSTORESP); | |
EDB_DISASM_DEFINE (EdbDisasmPUSH); | |
EDB_DISASM_DEFINE (EdbDisasmPOP); | |
EDB_DISASM_DEFINE (EdbDisasmCMPI); | |
EDB_DISASM_DEFINE (EdbDisasmPUSHn); | |
EDB_DISASM_DEFINE (EdbDisasmPOPn); | |
EDB_DISASM_DEFINE (EdbDisasmMOVI); | |
EDB_DISASM_DEFINE (EdbDisasmMOVIn); | |
EDB_DISASM_DEFINE (EdbDisasmMOVREL); | |
// | |
// Debugger Disasm Table | |
// | |
EDB_DISASM_INSTRUCTION mEdbDisasmInstructionTable[] = { | |
EdbDisasmBREAK, // opcode 0x00 BREAK | |
EdbDisasmJMP, // opcode 0x01 JMP | |
EdbDisasmJMP8, // opcode 0x02 JMP8 | |
EdbDisasmCALL, // opcode 0x03 CALL | |
EdbDisasmRET, // opcode 0x04 RET | |
EdbDisasmCMP, // opcode 0x05 CMPEQ | |
EdbDisasmCMP, // opcode 0x06 CMPLTE | |
EdbDisasmCMP, // opcode 0x07 CMPGTE | |
EdbDisasmCMP, // opcode 0x08 CMPULTE | |
EdbDisasmCMP, // opcode 0x09 CMPUGTE | |
EdbDisasmUnsignedDataManip, // opcode 0x0A NOT | |
EdbDisasmSignedDataManip, // opcode 0x0B NEG | |
EdbDisasmSignedDataManip, // opcode 0x0C ADD | |
EdbDisasmSignedDataManip, // opcode 0x0D SUB | |
EdbDisasmSignedDataManip, // opcode 0x0E MUL | |
EdbDisasmUnsignedDataManip, // opcode 0x0F MULU | |
EdbDisasmSignedDataManip, // opcode 0x10 DIV | |
EdbDisasmUnsignedDataManip, // opcode 0x11 DIVU | |
EdbDisasmSignedDataManip, // opcode 0x12 MOD | |
EdbDisasmUnsignedDataManip, // opcode 0x13 MODU | |
EdbDisasmUnsignedDataManip, // opcode 0x14 AND | |
EdbDisasmUnsignedDataManip, // opcode 0x15 OR | |
EdbDisasmUnsignedDataManip, // opcode 0x16 XOR | |
EdbDisasmUnsignedDataManip, // opcode 0x17 SHL | |
EdbDisasmUnsignedDataManip, // opcode 0x18 SHR | |
EdbDisasmSignedDataManip, // opcode 0x19 ASHR | |
EdbDisasmUnsignedDataManip, // opcode 0x1A EXTNDB | |
EdbDisasmUnsignedDataManip, // opcode 0x1B EXTNDW | |
EdbDisasmUnsignedDataManip, // opcode 0x1C EXTNDD | |
EdbDisasmMOVxx, // opcode 0x1D MOVBW | |
EdbDisasmMOVxx, // opcode 0x1E MOVWW | |
EdbDisasmMOVxx, // opcode 0x1F MOVDW | |
EdbDisasmMOVxx, // opcode 0x20 MOVQW | |
EdbDisasmMOVxx, // opcode 0x21 MOVBD | |
EdbDisasmMOVxx, // opcode 0x22 MOVWD | |
EdbDisasmMOVxx, // opcode 0x23 MOVDD | |
EdbDisasmMOVxx, // opcode 0x24 MOVQD | |
EdbDisasmMOVsnw, // opcode 0x25 MOVSNW | |
EdbDisasmMOVsnd, // opcode 0x26 MOVSND | |
NULL, // opcode 0x27 | |
EdbDisasmMOVxx, // opcode 0x28 MOVQQ | |
EdbDisasmLOADSP, // opcode 0x29 LOADSP | |
EdbDisasmSTORESP, // opcode 0x2A STORESP | |
EdbDisasmPUSH, // opcode 0x2B PUSH | |
EdbDisasmPOP, // opcode 0x2C POP | |
EdbDisasmCMPI, // opcode 0x2D CMPIEQ | |
EdbDisasmCMPI, // opcode 0x2E CMPILTE | |
EdbDisasmCMPI, // opcode 0x2F CMPIGTE | |
EdbDisasmCMPI, // opcode 0x30 CMPIULTE | |
EdbDisasmCMPI, // opcode 0x31 CMPIUGTE | |
EdbDisasmMOVxx, // opcode 0x32 MOVNW | |
EdbDisasmMOVxx, // opcode 0x33 MOVND | |
NULL, // opcode 0x34 | |
EdbDisasmPUSHn, // opcode 0x35 PUSHN | |
EdbDisasmPOPn, // opcode 0x36 POPN | |
EdbDisasmMOVI, // opcode 0x37 MOVI | |
EdbDisasmMOVIn, // opcode 0x38 MOVIN | |
EdbDisasmMOVREL, // opcode 0x39 MOVREL | |
}; | |
/** | |
Disasm instruction - BREAK. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmBREAK ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_BREAK); | |
if (*(UINT8 *)(UINTN)(InstructionAddress + 1) > 6) { | |
return 0; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"BREAK"); | |
EdbPrintDatan (*(UINT8 *)(UINTN)(InstructionAddress + 1)); | |
EdbPostInstructionString (); | |
} | |
return 2; | |
} | |
extern CONST UINT8 mJMPLen[]; | |
/** | |
Disasm instruction - JMP. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmJMP ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Operands; | |
UINTN Size; | |
UINT32 Data32; | |
UINT64 Data64; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_JMP); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
Operands = GET_OPERANDS (InstructionAddress); | |
Size = (UINTN)mJMPLen[(Modifiers >> 6) & 0x03]; | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"JMP"); | |
// if (Modifiers & OPCODE_M_IMMDATA64) { | |
// EdbPrintInstructionName (L"64"); | |
// } else { | |
// EdbPrintInstructionName (L"32"); | |
// } | |
if ((Modifiers & CONDITION_M_CONDITIONAL) != 0) { | |
if ((Modifiers & JMP_M_CS) != 0) { | |
EdbPrintInstructionName (L"cs"); | |
} else { | |
EdbPrintInstructionName (L"cc"); | |
} | |
} | |
InstructionAddress += 2; | |
if ((Modifiers & OPCODE_M_IMMDATA64) != 0) { | |
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT64)); | |
if ((Modifiers & OPCODE_M_IMMDATA) != 0) { | |
EdbPrintData64 (Data64); | |
} else { | |
return 0; | |
} | |
} else { | |
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT32)); | |
EdbPrintRegister1 (Operands); | |
if ((Operands & OPERAND_M_INDIRECT1) == 0) { | |
if ((Modifiers & OPCODE_M_IMMDATA) == 0) { | |
Data32 = 0; | |
} | |
EdbPrintImmDatan (Data32); | |
} else { | |
EdbPrintRawIndexData32 (Data32); | |
} | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - JMP8. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmJMP8 ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_JMP8); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"JMP8"); | |
if ((Modifiers & CONDITION_M_CONDITIONAL) != 0) { | |
if ((Modifiers & JMP_M_CS) != 0) { | |
EdbPrintInstructionName (L"cs"); | |
} else { | |
EdbPrintInstructionName (L"cc"); | |
} | |
} | |
EdbPrintData8 (*(UINT8 *)(UINTN)(InstructionAddress + 1)); | |
EdbPostInstructionString (); | |
} | |
return 2; | |
} | |
/** | |
Disasm instruction - CALL. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmCALL ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Operands; | |
UINTN Size; | |
UINT32 Data32; | |
UINT64 Data64; | |
UINT64 Ip; | |
UINTN Result; | |
EFI_PHYSICAL_ADDRESS SavedInstructionAddress; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_CALL); | |
SavedInstructionAddress = InstructionAddress; | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
Operands = GET_OPERANDS (InstructionAddress); | |
Size = (UINTN)mJMPLen[(Modifiers >> 6) & 0x03]; | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"CALL"); | |
// if (Modifiers & OPCODE_M_IMMDATA64) { | |
// EdbPrintInstructionName (L"64"); | |
// } else { | |
// EdbPrintInstructionName (L"32"); | |
// } | |
if ((Operands & OPERAND_M_NATIVE_CALL) != 0) { | |
EdbPrintInstructionName (L"EX"); | |
} | |
// if ((Operands & OPERAND_M_RELATIVE_ADDR) == 0) { | |
// EdbPrintInstructionName (L"a"); | |
// } | |
InstructionAddress += 2; | |
if ((Modifiers & OPCODE_M_IMMDATA64) != 0) { | |
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT64)); | |
Ip = Data64; | |
if ((Modifiers & OPCODE_M_IMMDATA) != 0) { | |
Result = EdbFindAndPrintSymbol ((UINTN)Ip); | |
if (Result == 0) { | |
EdbPrintData64 (Data64); | |
} | |
} else { | |
return 0; | |
} | |
} else { | |
if ((Modifiers & OPCODE_M_IMMDATA) != 0) { | |
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT32)); | |
} else { | |
Data32 = 0; | |
} | |
if ((Operands & OPERAND_M_OP1) == 0) { | |
Ip = (UINT64)Data32; | |
} else { | |
Ip = GetRegisterValue (SystemContext, (Operands & OPERAND_M_OP1)); | |
} | |
if ((Operands & OPERAND_M_INDIRECT1) == 0) { | |
if ((Operands & OPERAND_M_RELATIVE_ADDR) != 0) { | |
Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Ip + Size)); | |
} else { | |
Result = EdbFindAndPrintSymbol ((UINTN)Ip); | |
} | |
if (Result == 0) { | |
EdbPrintRegister1 (Operands); | |
if ((Modifiers & OPCODE_M_IMMDATA) != 0) { | |
EdbPrintImmData32 (Data32); | |
} | |
} | |
} else { | |
EdbPrintRegister1 (Operands); | |
if ((Modifiers & OPCODE_M_IMMDATA) != 0) { | |
EdbPrintRawIndexData32 (Data32); | |
} | |
} | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - RET. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmRET ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_RET); | |
if (*(UINT8 *)(UINTN)(InstructionAddress + 1) != 0) { | |
return 0; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"RET"); | |
EdbPostInstructionString (); | |
} | |
return 2; | |
} | |
/** | |
Disasm instruction - CMP. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmCMP ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Opcode; | |
UINT8 Modifiers; | |
UINT8 Operands; | |
UINT16 Data16; | |
UINTN Size; | |
ASSERT ( | |
(GET_OPCODE (InstructionAddress) == OPCODE_CMPEQ) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_CMPLTE) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_CMPGTE) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_CMPULTE) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_CMPUGTE) | |
); | |
Opcode = GET_OPCODE (InstructionAddress); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
Operands = GET_OPERANDS (InstructionAddress); | |
if ((Modifiers & OPCODE_M_IMMDATA) != 0) { | |
Size = 4; | |
} else { | |
Size = 2; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"CMP"); | |
// if (Modifiers & OPCODE_M_64BIT) { | |
// EdbPrintInstructionName (L"64"); | |
// } else { | |
// EdbPrintInstructionName (L"32"); | |
// } | |
switch (Opcode) { | |
case OPCODE_CMPEQ: | |
EdbPrintInstructionName (L"eq"); | |
break; | |
case OPCODE_CMPLTE: | |
EdbPrintInstructionName (L"lte"); | |
break; | |
case OPCODE_CMPGTE: | |
EdbPrintInstructionName (L"gte"); | |
break; | |
case OPCODE_CMPULTE: | |
EdbPrintInstructionName (L"ulte"); | |
break; | |
case OPCODE_CMPUGTE: | |
EdbPrintInstructionName (L"ugte"); | |
break; | |
} | |
EdbPrintRegister1 (Operands); | |
InstructionAddress += 2; | |
EdbPrintComma (); | |
EdbPrintRegister2 (Operands); | |
if ((Modifiers & OPCODE_M_IMMDATA) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
if ((Operands & OPERAND_M_INDIRECT2) != 0) { | |
EdbPrintRawIndexData16 (Data16); | |
} else { | |
EdbPrintImmDatan (Data16); | |
} | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - Unsigned Data Manipulate. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmUnsignedDataManip ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Opcode; | |
UINT8 Operands; | |
UINTN Size; | |
UINT16 Data16; | |
ASSERT ( | |
(GET_OPCODE (InstructionAddress) == OPCODE_NOT) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MULU) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_DIVU) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MODU) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_AND) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_OR) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_XOR) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_SHL) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_SHR) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_EXTNDB) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_EXTNDW) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_EXTNDD) | |
); | |
Opcode = GET_OPCODE (InstructionAddress); | |
Operands = GET_OPERANDS (InstructionAddress); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
if ((Modifiers & DATAMANIP_M_IMMDATA) != 0) { | |
Size = 4; | |
} else { | |
Size = 2; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
switch (Opcode) { | |
case OPCODE_NOT: | |
EdbPrintInstructionName (L"NOT"); | |
break; | |
case OPCODE_MULU: | |
EdbPrintInstructionName (L"MULU"); | |
break; | |
case OPCODE_DIVU: | |
EdbPrintInstructionName (L"DIVU"); | |
break; | |
case OPCODE_MODU: | |
EdbPrintInstructionName (L"MODU"); | |
break; | |
case OPCODE_AND: | |
EdbPrintInstructionName (L"AND"); | |
break; | |
case OPCODE_OR: | |
EdbPrintInstructionName (L"OR"); | |
break; | |
case OPCODE_XOR: | |
EdbPrintInstructionName (L"XOR"); | |
break; | |
case OPCODE_SHL: | |
EdbPrintInstructionName (L"SHL"); | |
break; | |
case OPCODE_SHR: | |
EdbPrintInstructionName (L"SHR"); | |
break; | |
case OPCODE_EXTNDB: | |
EdbPrintInstructionName (L"EXTNDB"); | |
break; | |
case OPCODE_EXTNDW: | |
EdbPrintInstructionName (L"EXTNDW"); | |
break; | |
case OPCODE_EXTNDD: | |
EdbPrintInstructionName (L"EXTNDD"); | |
break; | |
} | |
// if (Modifiers & DATAMANIP_M_64) { | |
// EdbPrintInstructionName (L"64"); | |
// } else { | |
// EdbPrintInstructionName (L"32"); | |
// } | |
EdbPrintRegister1 (Operands); | |
EdbPrintComma (); | |
EdbPrintRegister2 (Operands); | |
InstructionAddress += 2; | |
if ((Modifiers & DATAMANIP_M_IMMDATA) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
if ((Operands & OPERAND_M_INDIRECT2) != 0) { | |
EdbPrintRawIndexData16 (Data16); | |
} else { | |
EdbPrintImmDatan (Data16); | |
} | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - Signed Data Manipulate, | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmSignedDataManip ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Opcode; | |
UINT8 Operands; | |
UINTN Size; | |
UINT16 Data16; | |
ASSERT ( | |
(GET_OPCODE (InstructionAddress) == OPCODE_NEG) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_ADD) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_SUB) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MUL) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_DIV) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MOD) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_ASHR) | |
); | |
Opcode = GET_OPCODE (InstructionAddress); | |
Operands = GET_OPERANDS (InstructionAddress); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
if ((Modifiers & DATAMANIP_M_IMMDATA) != 0) { | |
Size = 4; | |
} else { | |
Size = 2; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
switch (Opcode) { | |
case OPCODE_NEG: | |
EdbPrintInstructionName (L"NEG"); | |
break; | |
case OPCODE_ADD: | |
EdbPrintInstructionName (L"ADD"); | |
break; | |
case OPCODE_SUB: | |
EdbPrintInstructionName (L"SUB"); | |
break; | |
case OPCODE_MUL: | |
EdbPrintInstructionName (L"MUL"); | |
break; | |
case OPCODE_DIV: | |
EdbPrintInstructionName (L"DIV"); | |
break; | |
case OPCODE_MOD: | |
EdbPrintInstructionName (L"MOD"); | |
break; | |
case OPCODE_ASHR: | |
EdbPrintInstructionName (L"ASHR"); | |
break; | |
} | |
// if (Modifiers & DATAMANIP_M_64) { | |
// EdbPrintInstructionName (L"64"); | |
// } else { | |
// EdbPrintInstructionName (L"32"); | |
// } | |
EdbPrintRegister1 (Operands); | |
EdbPrintComma (); | |
EdbPrintRegister2 (Operands); | |
InstructionAddress += 2; | |
if ((Modifiers & DATAMANIP_M_IMMDATA) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
if ((Operands & OPERAND_M_INDIRECT2) != 0) { | |
EdbPrintRawIndexData16 (Data16); | |
} else { | |
EdbPrintImmDatan (Data16); | |
} | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - MOVxx. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmMOVxx ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Opcode; | |
UINT8 Operands; | |
UINTN Size; | |
UINT16 Data16; | |
UINT32 Data32; | |
UINT64 Data64; | |
ASSERT ( | |
(GET_OPCODE (InstructionAddress) == OPCODE_MOVBW) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MOVWW) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MOVDW) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MOVQW) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MOVBD) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MOVWD) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MOVDD) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MOVQD) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MOVQQ) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MOVNW) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_MOVND) | |
); | |
Opcode = GET_OPCODE (InstructionAddress); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
Operands = GET_OPERANDS (InstructionAddress); | |
Size = 2; | |
if ((Modifiers & (OPCODE_M_IMMED_OP1 | OPCODE_M_IMMED_OP2)) != 0) { | |
if ((Opcode <= OPCODE_MOVQW) || (Opcode == OPCODE_MOVNW)) { | |
if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) { | |
Size += 2; | |
} | |
if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) { | |
Size += 2; | |
} | |
} else if (((Opcode <= OPCODE_MOVQD) || (Opcode == OPCODE_MOVND)) != 0) { | |
if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) { | |
Size += 4; | |
} | |
if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) { | |
Size += 4; | |
} | |
} else if (Opcode == OPCODE_MOVQQ) { | |
if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) { | |
Size += 8; | |
} | |
if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) { | |
Size += 8; | |
} | |
} | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"MOV"); | |
switch (Opcode) { | |
case OPCODE_MOVBW: | |
EdbPrintInstructionName (L"bw"); | |
break; | |
case OPCODE_MOVWW: | |
EdbPrintInstructionName (L"ww"); | |
break; | |
case OPCODE_MOVDW: | |
EdbPrintInstructionName (L"dw"); | |
break; | |
case OPCODE_MOVQW: | |
EdbPrintInstructionName (L"qw"); | |
break; | |
case OPCODE_MOVBD: | |
EdbPrintInstructionName (L"bd"); | |
break; | |
case OPCODE_MOVWD: | |
EdbPrintInstructionName (L"wd"); | |
break; | |
case OPCODE_MOVDD: | |
EdbPrintInstructionName (L"dd"); | |
break; | |
case OPCODE_MOVQD: | |
EdbPrintInstructionName (L"qd"); | |
break; | |
case OPCODE_MOVQQ: | |
EdbPrintInstructionName (L"qq"); | |
break; | |
case OPCODE_MOVNW: | |
EdbPrintInstructionName (L"nw"); | |
break; | |
case OPCODE_MOVND: | |
EdbPrintInstructionName (L"nd"); | |
break; | |
} | |
EdbPrintRegister1 (Operands); | |
InstructionAddress += 2; | |
if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) { | |
if ((Opcode <= OPCODE_MOVQW) || (Opcode == OPCODE_MOVNW)) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
InstructionAddress += 2; | |
EdbPrintRawIndexData16 (Data16); | |
} else if ((Opcode <= OPCODE_MOVQD) || (Opcode == OPCODE_MOVND)) { | |
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT32)); | |
InstructionAddress += 4; | |
EdbPrintRawIndexData32 (Data32); | |
} else if (Opcode == OPCODE_MOVQQ) { | |
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT64)); | |
InstructionAddress += 8; | |
EdbPrintRawIndexData64 (Data64); | |
} | |
} | |
EdbPrintComma (); | |
EdbPrintRegister2 (Operands); | |
if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) { | |
if ((Opcode <= OPCODE_MOVQW) || (Opcode == OPCODE_MOVNW)) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
EdbPrintRawIndexData16 (Data16); | |
} else if ((Opcode <= OPCODE_MOVQD) || (Opcode == OPCODE_MOVND)) { | |
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT32)); | |
EdbPrintRawIndexData32 (Data32); | |
} else if (Opcode == OPCODE_MOVQQ) { | |
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT64)); | |
EdbPrintRawIndexData64 (Data64); | |
} | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - MOVsnw. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmMOVsnw ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Operands; | |
UINTN Size; | |
UINT16 Data16; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_MOVSNW); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
Operands = GET_OPERANDS (InstructionAddress); | |
Size = 2; | |
if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) { | |
Size += 2; | |
} | |
if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) { | |
Size += 2; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"MOVsnw"); | |
EdbPrintRegister1 (Operands); | |
InstructionAddress += 2; | |
if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
InstructionAddress += 2; | |
EdbPrintRawIndexData16 (Data16); | |
} | |
EdbPrintComma (); | |
EdbPrintRegister2 (Operands); | |
if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
if ((Operands & OPERAND_M_INDIRECT2) != 0) { | |
EdbPrintRawIndexData16 (Data16); | |
} else { | |
EdbPrintImmDatan (Data16); | |
} | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - MOVsnd. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmMOVsnd ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Operands; | |
UINTN Size; | |
UINT32 Data32; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_MOVSND); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
Operands = GET_OPERANDS (InstructionAddress); | |
Size = 2; | |
if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) { | |
Size += 4; | |
} | |
if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) { | |
Size += 4; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"MOVsnd"); | |
EdbPrintRegister1 (Operands); | |
InstructionAddress += 2; | |
if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) { | |
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT32)); | |
InstructionAddress += 4; | |
EdbPrintRawIndexData32 (Data32); | |
} | |
EdbPrintComma (); | |
EdbPrintRegister2 (Operands); | |
if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) { | |
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT32)); | |
if ((Operands & OPERAND_M_INDIRECT2) != 0) { | |
EdbPrintRawIndexData32 (Data32); | |
} else { | |
EdbPrintImmDatan (Data32); | |
} | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - LOADSP. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmLOADSP ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Operands; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_LOADSP); | |
Operands = GET_OPERANDS (InstructionAddress); | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"LOADSP"); | |
EdbPrintDedicatedRegister1 (Operands); | |
EdbPrintRegister2 (Operands); | |
EdbPostInstructionString (); | |
} | |
return 2; | |
} | |
/** | |
Disasm instruction - STORESP. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmSTORESP ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Operands; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_STORESP); | |
Operands = GET_OPERANDS (InstructionAddress); | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"STORESP"); | |
EdbPrintRegister1 (Operands); | |
EdbPrintDedicatedRegister2 (Operands); | |
EdbPostInstructionString (); | |
} | |
return 2; | |
} | |
/** | |
Disasm instruction - PUSH. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmPUSH ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Operands; | |
UINTN Size; | |
UINT16 Data16; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_PUSH); | |
Operands = GET_OPERANDS (InstructionAddress); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) { | |
Size = 4; | |
} else { | |
Size = 2; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"PUSH"); | |
// if (Modifiers & PUSHPOP_M_64) { | |
// EdbPrintInstructionName (L"64"); | |
// } else { | |
// EdbPrintInstructionName (L"32"); | |
// } | |
EdbPrintRegister1 (Operands); | |
InstructionAddress += 2; | |
if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
if ((Operands & OPERAND_M_INDIRECT1) != 0) { | |
EdbPrintRawIndexData16 (Data16); | |
} else { | |
EdbPrintImmDatan (Data16); | |
} | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - POP. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmPOP ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Operands; | |
UINTN Size; | |
UINT16 Data16; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_POP); | |
Operands = GET_OPERANDS (InstructionAddress); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) { | |
Size = 4; | |
} else { | |
Size = 2; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"POP"); | |
// if (Modifiers & PUSHPOP_M_64) { | |
// EdbPrintInstructionName (L"64"); | |
// } else { | |
// EdbPrintInstructionName (L"32"); | |
// } | |
EdbPrintRegister1 (Operands); | |
InstructionAddress += 2; | |
if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
if ((Operands & OPERAND_M_INDIRECT1) != 0) { | |
EdbPrintRawIndexData16 (Data16); | |
} else { | |
EdbPrintImmDatan (Data16); | |
} | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - CMPI. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmCMPI ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Opcode; | |
UINT8 Operands; | |
UINT16 Data16; | |
UINT32 Data32; | |
UINTN Size; | |
ASSERT ( | |
(GET_OPCODE (InstructionAddress) == OPCODE_CMPIEQ) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_CMPILTE) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_CMPIGTE) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_CMPIULTE) || | |
(GET_OPCODE (InstructionAddress) == OPCODE_CMPIUGTE) | |
); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
Opcode = GET_OPCODE (InstructionAddress); | |
Operands = GET_OPERANDS (InstructionAddress); | |
if ((Operands & 0xE0) != 0) { | |
return 0; | |
} | |
Size = 2; | |
if ((Operands & OPERAND_M_CMPI_INDEX) != 0) { | |
Size += 2; | |
} | |
if ((Modifiers & OPCODE_M_CMPI32_DATA) != 0) { | |
Size += 4; | |
} else { | |
Size += 2; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"CMPI"); | |
// if (Modifiers & OPCODE_M_CMPI64) { | |
// EdbPrintInstructionName (L"64"); | |
// } else { | |
// EdbPrintInstructionName (L"32"); | |
// } | |
if ((Modifiers & OPCODE_M_CMPI32_DATA) != 0) { | |
EdbPrintInstructionName (L"d"); | |
} else { | |
EdbPrintInstructionName (L"w"); | |
} | |
switch (Opcode) { | |
case OPCODE_CMPIEQ: | |
EdbPrintInstructionName (L"eq"); | |
break; | |
case OPCODE_CMPILTE: | |
EdbPrintInstructionName (L"lte"); | |
break; | |
case OPCODE_CMPIGTE: | |
EdbPrintInstructionName (L"gte"); | |
break; | |
case OPCODE_CMPIULTE: | |
EdbPrintInstructionName (L"ulte"); | |
break; | |
case OPCODE_CMPIUGTE: | |
EdbPrintInstructionName (L"ugte"); | |
break; | |
} | |
EdbPrintRegister1 (Operands); | |
InstructionAddress += 2; | |
if ((Operands & OPERAND_M_CMPI_INDEX) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
InstructionAddress += 2; | |
EdbPrintRawIndexData16 (Data16); | |
} | |
EdbPrintComma (); | |
if ((Modifiers & OPCODE_M_CMPI32_DATA) != 0) { | |
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT32)); | |
EdbPrintDatan (Data32); | |
} else { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
EdbPrintDatan (Data16); | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - PUSHn. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmPUSHn ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Operands; | |
UINTN Size; | |
UINT16 Data16; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_PUSHN); | |
Operands = GET_OPERANDS (InstructionAddress); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) { | |
Size = 4; | |
} else { | |
Size = 2; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"PUSHn"); | |
EdbPrintRegister1 (Operands); | |
InstructionAddress += 2; | |
if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
if ((Operands & OPERAND_M_INDIRECT1) != 0) { | |
EdbPrintRawIndexData16 (Data16); | |
} else { | |
EdbPrintImmDatan (Data16); | |
} | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - POPn. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmPOPn ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Operands; | |
UINTN Size; | |
UINT16 Data16; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_POPN); | |
Operands = GET_OPERANDS (InstructionAddress); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) { | |
Size = 4; | |
} else { | |
Size = 2; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"POPn"); | |
EdbPrintRegister1 (Operands); | |
InstructionAddress += 2; | |
if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
if ((Operands & OPERAND_M_INDIRECT1) != 0) { | |
EdbPrintRawIndexData16 (Data16); | |
} else { | |
EdbPrintImmDatan (Data16); | |
} | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - MOVI. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmMOVI ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Operands; | |
UINTN Size; | |
UINT16 Data16; | |
UINT32 Data32; | |
UINT64 Data64; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_MOVI); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
Operands = GET_OPERANDS (InstructionAddress); | |
if ((Operands & MOVI_M_IMMDATA) != 0) { | |
Size = 4; | |
} else { | |
Size = 2; | |
} | |
if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) { | |
Size += 2; | |
} else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) { | |
Size += 4; | |
} else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) { | |
Size += 8; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"MOVI"); | |
switch (Operands & MOVI_M_MOVEWIDTH) { | |
case MOVI_MOVEWIDTH8: | |
EdbPrintInstructionName (L"b"); | |
break; | |
case MOVI_MOVEWIDTH16: | |
EdbPrintInstructionName (L"w"); | |
break; | |
case MOVI_MOVEWIDTH32: | |
EdbPrintInstructionName (L"d"); | |
break; | |
case MOVI_MOVEWIDTH64: | |
EdbPrintInstructionName (L"q"); | |
break; | |
} | |
switch (Modifiers & MOVI_M_DATAWIDTH) { | |
case MOVI_DATAWIDTH16: | |
EdbPrintInstructionName (L"w"); | |
break; | |
case MOVI_DATAWIDTH32: | |
EdbPrintInstructionName (L"d"); | |
break; | |
case MOVI_DATAWIDTH64: | |
EdbPrintInstructionName (L"q"); | |
break; | |
} | |
EdbPrintRegister1 (Operands); | |
InstructionAddress += 2; | |
if ((Operands & MOVI_M_IMMDATA) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
InstructionAddress += 2; | |
EdbPrintRawIndexData16 (Data16); | |
} | |
EdbPrintComma (); | |
switch (Modifiers & MOVI_M_DATAWIDTH) { | |
case MOVI_DATAWIDTH16: | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
EdbPrintDatan (Data16); | |
break; | |
case MOVI_DATAWIDTH32: | |
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT32)); | |
EdbPrintDatan (Data32); | |
break; | |
case MOVI_DATAWIDTH64: | |
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT64)); | |
EdbPrintData64n (Data64); | |
break; | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - MOVIn. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmMOVIn ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Operands; | |
UINTN Size; | |
UINT16 Data16; | |
UINT32 Data32; | |
UINT64 Data64; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_MOVIN); | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
Operands = GET_OPERANDS (InstructionAddress); | |
if ((Operands & MOVI_M_IMMDATA) != 0) { | |
Size = 4; | |
} else { | |
Size = 2; | |
} | |
if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) { | |
Size += 2; | |
} else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) { | |
Size += 4; | |
} else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) { | |
Size += 8; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"MOVIn"); | |
switch (Modifiers & MOVI_M_DATAWIDTH) { | |
case MOVI_DATAWIDTH16: | |
EdbPrintInstructionName (L"w"); | |
break; | |
case MOVI_DATAWIDTH32: | |
EdbPrintInstructionName (L"d"); | |
break; | |
case MOVI_DATAWIDTH64: | |
EdbPrintInstructionName (L"q"); | |
break; | |
} | |
EdbPrintRegister1 (Operands); | |
InstructionAddress += 2; | |
if ((Operands & MOVI_M_IMMDATA) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
InstructionAddress += 2; | |
EdbPrintRawIndexData16 (Data16); | |
} | |
EdbPrintComma (); | |
switch (Modifiers & MOVI_M_DATAWIDTH) { | |
case MOVI_DATAWIDTH16: | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
EdbPrintRawIndexData16 (Data16); | |
break; | |
case MOVI_DATAWIDTH32: | |
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT32)); | |
EdbPrintRawIndexData32 (Data32); | |
break; | |
case MOVI_DATAWIDTH64: | |
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT64)); | |
EdbPrintRawIndexData64 (Data64); | |
break; | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} | |
/** | |
Disasm instruction - MOVREL. | |
@param InstructionAddress - The instruction address | |
@param SystemContext - EBC system context. | |
@param DisasmString - The instruction string | |
@return Instruction length | |
**/ | |
UINTN | |
EdbDisasmMOVREL ( | |
IN EFI_PHYSICAL_ADDRESS InstructionAddress, | |
IN EFI_SYSTEM_CONTEXT SystemContext, | |
OUT CHAR16 **DisasmString | |
) | |
{ | |
UINT8 Modifiers; | |
UINT8 Operands; | |
UINTN Size; | |
UINT16 Data16; | |
UINT32 Data32; | |
UINT64 Data64; | |
UINTN Result; | |
EFI_PHYSICAL_ADDRESS SavedInstructionAddress; | |
ASSERT (GET_OPCODE (InstructionAddress) == OPCODE_MOVREL); | |
SavedInstructionAddress = InstructionAddress; | |
Modifiers = GET_MODIFIERS (InstructionAddress); | |
Operands = GET_OPERANDS (InstructionAddress); | |
if ((Operands & MOVI_M_IMMDATA) != 0) { | |
Size = 4; | |
} else { | |
Size = 2; | |
} | |
if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) { | |
Size += 2; | |
} else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) { | |
Size += 4; | |
} else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) { | |
Size += 8; | |
} else { | |
return 0; | |
} | |
// | |
// Construct Disasm String | |
// | |
if (DisasmString != NULL) { | |
*DisasmString = EdbPreInstructionString (); | |
EdbPrintInstructionName (L"MOVrel"); | |
switch (Modifiers & MOVI_M_DATAWIDTH) { | |
case MOVI_DATAWIDTH16: | |
EdbPrintInstructionName (L"w"); | |
break; | |
case MOVI_DATAWIDTH32: | |
EdbPrintInstructionName (L"d"); | |
break; | |
case MOVI_DATAWIDTH64: | |
EdbPrintInstructionName (L"q"); | |
break; | |
} | |
EdbPrintRegister1 (Operands); | |
InstructionAddress += 2; | |
if ((Operands & MOVI_M_IMMDATA) != 0) { | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
InstructionAddress += 2; | |
EdbPrintRawIndexData16 (Data16); | |
} | |
EdbPrintComma (); | |
switch (Modifiers & MOVI_M_DATAWIDTH) { | |
case MOVI_DATAWIDTH16: | |
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT16)); | |
Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Size + (INT16)Data16)); | |
if (Result == 0) { | |
EdbPrintData16 (Data16); | |
} | |
break; | |
case MOVI_DATAWIDTH32: | |
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT32)); | |
Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Size + (INT32)Data32)); | |
if (Result == 0) { | |
EdbPrintData32 (Data32); | |
} | |
break; | |
case MOVI_DATAWIDTH64: | |
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof (UINT64)); | |
if (sizeof (UINTN) == sizeof (UINT64)) { | |
Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Size + (INT64)Data64)); | |
} else { | |
Result = 0; | |
} | |
if (Result == 0) { | |
EdbPrintData64 (Data64); | |
} | |
break; | |
} | |
EdbPostInstructionString (); | |
} | |
return Size; | |
} |