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

1790 lines
46 KiB
C

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